1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433
| ================================================================================ CTF CLIENT PROGRAM ANALYSIS ================================================================================
[BASIC INFO] File: client (ELF64 Linux executable) MD5: 204fea362fdd03097c8cc31f87f839c4 Size: 0x8ba8 bytes Connection: 127.0.0.1:8080 (AF_INET, SOCK_STREAM)
================================================================================ ENCRYPTION ALGORITHMS ================================================================================
1. RC4 (Stream Cipher) - Key: "qwertyui" (8 bytes, used twice = 16 bytes for key schedule) - Functions: * rc4_ksa (0x4AF9): Key Scheduling Algorithm * rc4_prga (0x4C23): Pseudo-Random Generation Algorithm * rc4_decrypt (0x4D4A): Decrypt received data * rc4_encrypt_and_send (0x2729): Encrypt and send data - Usage: ALL network traffic is RC4 encrypted/decrypted
2. RSA (Asymmetric Encryption) - Key parameters (all in hex): * n: 9a49428cadd84b7a81cb80f916e645a6a9dd23c2fe679f93af6a77eff0f0bb13 09b77fb7861275f07ab41e98ae5c2ecf933f27d47b9ce0a55a3e06569cacbb4c 9183f8ee9a47f2cfbb3a5965c9326f45d2d608cfeabea1a1879eae95b70224d2 e7736b9bc4109756f55a3f70f11a9b9c6564fb6456d329c336fbb59859db5fde 1f2338294e863c4f05b4a89e6c3b761d52a2081a0af0a320fde831daa741fad7 7aa7ef2dd30b3e33d1a6e7b44ed44ef40de4557a4fd65b63db63d105386bbd81 071739ec3d0fe44b6a0952a2b065bededfecea6e22229fea32adfc9a6e2ccfdf 5da437a56ad41d7ef08c2c4635d3a0218aab2a5ed6e9dd42d684bc918efe24d3 * e: 10001 (65537) * p: b782eca6a75067d398dd8ef00e9d024cc554f292d7820a72848d3c619dafaf61 ab8f7d719d4cd8ac44351281afd64f8cf23bc8aa5ec48bbd9eb301af50b96f52 8a108e6643223130a84addd5b9e1ad108c44d706adc5fb097a17ab990f395f37 81296e356ac60d64b9a2a641c3e2f593bbe98d38df528a1c67e583ef623b667f * q: d73b03a9b0c4b7e9236d56938d6264e6c8ecaab709effcf02f4e5ec26310273b 81089e1cb3d4c050e852721d3daf1d5b7a2be2df02bafcffb77e17d1a8e6428b f87579c859cbe778d3b9ea93aff0d934a0e7b83a1d7a39d0a1779ea18db5fffd 99b118c4c2361a22308f54f7ae568e7bf2de6d1b6eb0be1d77eca8edd94f9fad * d: 0 (not used by client, only server needs private key) - Padding: PKCS1 OAEP (RSA_PKCS1_OAEP_PADDING = 4) - Functions: * hex_str_to_bn (0x4E1C): Convert hex string to BIGNUM * rsa_create_key (0x4E86): Create RSA key structure * rsa_public_encrypt (0x4F70): RSA public key encryption * rsa_encrypt_with_keys (0x5042): Complete RSA encryption wrapper - Usage: Encrypt AES key and IV before sending to server
3. AES-128-CBC (Symmetric Encryption) - Key size: 16 bytes - Block size: 16 bytes - Rounds: 10 - Functions: * aes_key_expansion (0x33F6): Expand 16-byte key to round keys * aes_sub_bytes (0x37D2): S-box substitution * aes_shift_rows (0x38D8): Row shifting * aes_mix_columns (0x3CB1): Column mixing * aes_add_round_key (0x36C5): XOR with round key * aes_state_from_buffer (0x3323): Load state matrix from buffer * aes_state_to_buffer (0x338C): Store state matrix to buffer * aes_cbc_encrypt (0x4125): CBC mode encryption * aes_cbc_encrypt_password (0x49DD): Encrypt password with PKCS7 padding * pkcs7_pad (0x48ED): PKCS7 padding * calc_padded_len (0x49A4): Calculate padded length - Usage: Encrypt password for transmission
================================================================================ CONFIG FILE STRUCTURE ================================================================================
File: config (88 bytes total) Content: "key:xxxxxxxxxxxxxxxxiv:xxxxxxxxxxxxxxxxpasswd:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Offset Length Field Description
0 4 label "key:" (literal) 4 16 aes_iv AES IV (16 bytes), read when server asks "inp u key" 20 3 label "iv:" (literal) 23 16 aes_key AES Key (16 bytes), read when server asks "inp u account" 39 7 label "passwd:" (literal) 46 42 password Password (42 bytes), read when server asks "inp u passwd"
read_config_file function (0x5302): - n=0: Read bytes 4-19 (AES IV, 16 bytes) - n=1: Read bytes 23-38 (AES Key, 16 bytes) - n=2: Read bytes 46-87 (Password, 42 bytes)
================================================================================ PROTOCOL FLOW ================================================================================
1. Client connects to 127.0.0.1:8080
2. Client -> Server: "req login..." (RC4 encrypted)
3. Server -> Client: "inp u account" (RC4 encrypted)
4. Client reads AES KEY from config (offset 23-38, 16 bytes) Client -> Server: RSA_encrypt(AES_KEY) then RC4 encrypted 5. Server -> Client: "inp u key" (RC4 encrypted)
6. Client reads AES IV from config (offset 4-19, 16 bytes) Client -> Server: RSA_encrypt(AES_IV) then RC4 encrypted
7. Server -> Client: "inp u passwd" (RC4 encrypted)
8. Client reads password from config (offset 46-87, 42 bytes) Client performs: - PKCS7 padding: 42 bytes -> 48 bytes (pad with 6x 0x06) - AES-CBC encrypt with key=AES_KEY, iv=AES_IV Client -> Server: AES_encrypted_password (48 bytes, RC4 encrypted)
9. Server verifies and responds: - "login success" if password correct - "login error" if password wrong
================================================================================ IMPORTANT ADDRESSES ================================================================================
Global Variables: p_qwertyui (0x9020): Pointer to RC4 key "qwertyui" off_90A0: RSA modulus n off_90A8: RSA exponent e ("10001") off_90B0: RSA prime p off_90B8: RSA prime q off_90C0: RSA private exponent d ("0" - not used) byte_90E0: AES S-box dword_6500: AES round constants (Rcon)
Key Functions: main (0x27A0): Main function, login protocol rc4_encrypt_and_send (0x2729): Encrypt with RC4 and send rc4_decrypt (0x4D4A): Decrypt with RC4 rsa_encrypt_with_keys (0x5042): RSA encryption aes_cbc_encrypt_password (0x49DD): AES-CBC password encryption read_config_file (0x5302): Read values from config string_compare (0x329B): Compare strings
================================================================================ SERVER ANALYSIS ================================================================================
[SERVER BINARY INFO] File: server (ELF64 Linux executable) MD5: 7d31caa646134442a71ef88f4a2422da Listens on: 0.0.0.0:8080
[SERVER KEY FUNCTIONS] main (0x339C): Create socket, accept connections, spawn threads handle_client_login (0x29C0): Process login protocol rsa_decrypt_with_keys (0x73B2): RSA decryption rsa_private_decrypt (0x71E4): RSA_private_decrypt wrapper rc4_encrypt_and_send (0x2949): RC4 encrypt and send rc4_decrypt (0x6F5C): RC4 decrypt
[SERVER VERIFICATION DATA] byte_C0A0 (256 bytes): Expected RSA encrypted AES IV byte_C1A0 (256 bytes): Expected RSA encrypted AES Key byte_C2A0 (48 bytes): Expected AES encrypted password
[RSA PRIVATE KEY d] Address: 0x8420 (off_C2F0) Value: 28c7df24a5798679db2a44979275f5f3179db180d91335702942fb1b70e985de 825da90f2eb65d20ddf8be1d9d4e15bc1d84e95795ff8c0c28ce3c33fde054f6 e82a4f4cc22597b350c9c62ccc0188bd4152a701a3601558f22aa9fae8b9fdac 6c2bc09b1637f71e0511805e04b203c4fdb2b36ad232fe819b06ed4e57c74f39 fd9b72623c16ff2100f148f622bf12876260c4859672360dc0da3da6b45c5c8c 6215ccda072765840c213fba11a91d6bf598a8a8065797566c8950a34ea0a072 a9ed0c38bdc58662f186ec578ca55d5098443fd566cc722ace9c4e89afc4e302 c8a4870e11a003b935f4a102695bfd64bb0fa74dcc372682e2b24ff45a1a69 Note: This d doesn't satisfy d*e == 1 mod phi(n), need to recalculate!
[SERVER PROTOCOL FLOW] 1. Accept client connection 2. Receive RC4 encrypted "req login..." -> RC4 decrypt -> verify 3. Send "inp u account" (RC4 encrypted) 4. Receive RSA encrypted AES Key -> compare with byte_C1A0 -> RSA decrypt with private key -> store AES Key 5. Send "inp u key" (RC4 encrypted) 6. Receive RSA encrypted AES IV -> compare with byte_C0A0 -> RSA decrypt with private key -> store AES IV 7. Send "inp u passwd" (RC4 encrypted) 8. Receive AES encrypted password (48 bytes) -> Compare with byte_C2A0 (no decryption!) 9. If match: send "login success", else: send "login error"
================================================================================ SOLUTION ================================================================================
[DECRYPTION STEPS] 1. RSA decrypt byte_C1A0 -> AES Key: "aassddffgghhjjll" (16 bytes) 2. RSA decrypt byte_C0A0 -> AES IV: "qqwweerrttyyuuii" (16 bytes) 3. AES-CBC decrypt byte_C2A0 with SWAPPED key/iv (Client code uses IV as Key and Key as IV internally)
[IMPORTANT NOTE] Client swaps AES Key and IV when calling encryption function! Must use: AES.new(IV_value, MODE_CBC, Key_value) to decrypt
[ENCRYPTED PASSWORD (byte_C2A0)] add1d11960c22d9166dac3c26725c81909176b238e3003aa57aacba0a226b7c3 1c220b8d209cb495b55db4e27d4e438e
================================================================================ FLAG ================================================================================
DASCTF{dqmaxfwkm921kr21m;df1m1dqmlk1d12d1}
================================================================================ CORRECT CONFIG FILE ================================================================================
To successfully login, config file should contain: key:qqwweerrttyyuuii (offset 4-19, used as AES IV) iv:aassddffgghhjjll (offset 23-38, used as AES Key) passwd:DASCTF{dqmaxfwkm921kr21m;df1m1dqmlk1d12d1} (offset 46-87)
================================================================================ #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ CTF Client-Server Login Challenge Solver Decrypts the password from server data using RSA and AES-CBC
Analysis: 1. Server has RSA encrypted AES Key (byte_C1A0) and AES IV (byte_C0A0) 2. Server has AES-CBC encrypted password (byte_C2A0, 48 bytes) 3. RSA private key d is available in server binary 4. Need to: RSA decrypt -> get AES key/iv -> AES decrypt -> get flag """
from Crypto.PublicKey import RSA from Crypto.Cipher import AES, PKCS1_OAEP from Crypto.Util.Padding import unpad import binascii
# RSA parameters from binary (all in hex) n_hex = "9a49428cadd84b7a81cb80f916e645a6a9dd23c2fe679f93af6a77eff0f0bb1309b77fb7861275f07ab41e98ae5c2ecf933f27d47b9ce0a55a3e06569cacbb4c9183f8ee9a47f2cfbb3a5965c9326f45d2d608cfeabea1a1879eae95b70224d2e7736b9bc4109756f55a3f70f11a9b9c6564fb6456d329c336fbb59859db5fde1f2338294e863c4f05b4a89e6c3b761d52a2081a0af0a320fde831daa741fad77aa7ef2dd30b3e33d1a6e7b44ed44ef40de4557a4fd65b63db63d105386bbd81071739ec3d0fe44b6a0952a2b065bededfecea6e22229fea32adfc9a6e2ccfdf5da437a56ad41d7ef08c2c4635d3a0218aab2a5ed6e9dd42d684bc918efe24d3" e_hex = "10001" p_hex = "b782eca6a75067d398dd8ef00e9d024cc554f292d7820a72848d3c619dafaf61ab8f7d719d4cd8ac44351281afd64f8cf23bc8aa5ec48bbd9eb301af50b96f528a108e6643223130a84addd5b9e1ad108c44d706adc5fb097a17ab990f395f3781296e356ac60d64b9a2a641c3e2f593bbe98d38df528a1c67e583ef623b667f" q_hex = "d73b03a9b0c4b7e9236d56938d6264e6c8ecaab709effcf02f4e5ec26310273b81089e1cb3d4c050e852721d3daf1d5b7a2be2df02bafcffb77e17d1a8e6428bf87579c859cbe778d3b9ea93aff0d934a0e7b83a1d7a39d0a1779ea18db5fffd99b118c4c2361a22308f54f7ae568e7bf2de6d1b6eb0be1d77eca8edd94f9fad"
# RSA private key d from server binary (at offset 0x8420) d_hex = "28c7df24a5798679db2a44979275f5f3179db180d91335702942fb1b70e985de825da90f2eb65d20ddf8be1d9d4e15bc1d84e95795ff8c0c28ce3c33fde054f6e82a4f4cc22597b350c9c62ccc0188bd4152a701a3601558f22aa9fae8b9fdac6c2bc09b1637f71e0511805e04b203c4fdb2b36ad232fe819b06ed4e57c74f39fd9b72623c16ff2100f148f622bf12876260c4859672360dc0da3da6b45c5c8c6215ccda072765840c213fba11a91d6bf598a8a8065797566c8950a34ea0a072a9ed0c38bdc58662f186ec578ca55d5098443fd566cc722ace9c4e89afc4e302c8a4870e11a003b935f4a102695bfd64bb0fa74dcc372682e2b24ff45a1a69"
# Encrypted data from server binary (read from IDA) # byte_C0A0: RSA encrypted AES IV (256 bytes) encrypted_iv_bytes = [ 0x37, 0x3a, 0x2a, 0x27, 0xb3, 0x8f, 0xd7, 0x78, 0xc7, 0x16, 0x72, 0x8e, 0xbb, 0x95, 0xbe, 0x89, 0xa0, 0xa0, 0x57, 0x10, 0x91, 0x19, 0xa0, 0x8d, 0x5c, 0xe4, 0x92, 0x61, 0xeb, 0xb0, 0xe0, 0x77, 0x6d, 0x25, 0x4a, 0x40, 0xc4, 0xd2, 0x1b, 0xd2, 0x46, 0x3e, 0x61, 0x60, 0x87, 0x71, 0xde, 0x40, 0x1e, 0xed, 0x13, 0xac, 0x66, 0x60, 0xd9, 0x96, 0xbe, 0xa8, 0xc8, 0xb8, 0x2b, 0xdd, 0x0e, 0xaf, 0x56, 0xc3, 0x84, 0x66, 0x77, 0x6e, 0xba, 0x31, 0xf7, 0xb2, 0x21, 0x92, 0x30, 0xb6, 0x54, 0xa7, 0x7e, 0xc0, 0xaf, 0x39, 0x5a, 0x01, 0xc3, 0x1c, 0x13, 0x9a, 0x4f, 0x6b, 0x7b, 0x8b, 0xa8, 0x45, 0x19, 0x20, 0x96, 0x16, 0x5d, 0xd7, 0xac, 0xd0, 0x33, 0x1e, 0x79, 0xdb, 0xe4, 0x34, 0xed, 0x8c, 0x9a, 0x66, 0x58, 0x1d, 0x26, 0xf6, 0x9e, 0x5f, 0xaa, 0x29, 0x5f, 0x66, 0x01, 0x00, 0x76, 0xb9, 0x1a, 0x6d, 0xd6, 0x1d, 0xb7, 0xab, 0xd3, 0x25, 0xf8, 0xbd, 0x25, 0xd9, 0x28, 0xde, 0xbc, 0xc0, 0x2e, 0x55, 0x55, 0xff, 0x81, 0xf7, 0xae, 0x3e, 0x54, 0x8e, 0x3e, 0x46, 0x59, 0xa3, 0x7f, 0x5d, 0x3d, 0x3c, 0x39, 0xfb, 0xca, 0xd1, 0xb5, 0x83, 0xe4, 0x2f, 0xb0, 0x4f, 0xa3, 0x28, 0xeb, 0xb7, 0x7e, 0x78, 0x41, 0xf4, 0x5b, 0x71, 0x1e, 0x77, 0xee, 0x23, 0xe1, 0x19, 0x89, 0xdb, 0x2c, 0x0e, 0x06, 0xb8, 0x19, 0x1a, 0x45, 0x6d, 0x56, 0xbd, 0x1a, 0x7d, 0x42, 0xc4, 0x7f, 0xdf, 0xdf, 0x11, 0x79, 0x22, 0x8b, 0x57, 0xc6, 0xef, 0xca, 0x9b, 0x9b, 0x6a, 0x7d, 0x22, 0x68, 0x2e, 0x5b, 0x67, 0xc7, 0xc4, 0x6a, 0x87, 0x7f, 0xb6, 0x77, 0xf5, 0xf3, 0x17, 0xb4, 0x82, 0x3f, 0xcd, 0xc8, 0x12, 0xf0, 0x36, 0x2b, 0xe2, 0x7c, 0x0f, 0x54, 0x53, 0x03, 0x71, 0x48, 0xed, 0x30, 0x12, 0x7b, 0x26 ]
# byte_C1A0: RSA encrypted AES Key (256 bytes) encrypted_key_bytes = [ 0x16, 0x38, 0xe0, 0xeb, 0x93, 0x61, 0x40, 0xb5, 0x52, 0x70, 0x33, 0x29, 0x2c, 0xbe, 0xfc, 0xd7, 0x3b, 0x55, 0xcf, 0xc7, 0xfb, 0x79, 0xdf, 0x51, 0xae, 0x37, 0x68, 0xa0, 0xdd, 0x9c, 0x84, 0xae, 0x45, 0x80, 0xe4, 0x7a, 0x51, 0x33, 0xb4, 0x25, 0xf4, 0xc9, 0x3e, 0xac, 0x97, 0xe4, 0xb1, 0xaa, 0x0b, 0x4c, 0xd3, 0x05, 0x89, 0xd0, 0x04, 0xf6, 0xd0, 0xd1, 0x9f, 0xcb, 0xc7, 0x09, 0xe8, 0x6c, 0xc2, 0x99, 0x6b, 0x43, 0x3d, 0x29, 0xf6, 0x50, 0xb6, 0x99, 0x87, 0xa4, 0x66, 0xf0, 0x5b, 0xef, 0x7f, 0x69, 0x94, 0x58, 0x60, 0xdc, 0xc4, 0x47, 0x42, 0xa5, 0x11, 0xf3, 0x62, 0x13, 0x85, 0xc8, 0x9f, 0xbd, 0x4d, 0x73, 0x15, 0x36, 0x15, 0x78, 0x96, 0x34, 0xb2, 0x5c, 0xfc, 0x31, 0x51, 0xa4, 0x11, 0x5b, 0xc3, 0x0c, 0x96, 0x97, 0x9e, 0x5f, 0x96, 0x52, 0x90, 0xf3, 0x6a, 0x86, 0x3e, 0x33, 0x78, 0xb5, 0xcf, 0xc9, 0xba, 0x31, 0x43, 0x8c, 0x4b, 0xae, 0x22, 0xb2, 0x3e, 0xf8, 0x15, 0xed, 0xf7, 0xcf, 0x17, 0x71, 0x80, 0x3b, 0xd3, 0x92, 0xa5, 0x07, 0x2b, 0x46, 0x89, 0x00, 0xb7, 0x5f, 0x5a, 0x43, 0x77, 0xd1, 0xda, 0xf3, 0xd6, 0xf7, 0xb7, 0xb6, 0x85, 0x0d, 0x1a, 0x4a, 0x41, 0x34, 0xf2, 0xf6, 0x58, 0x40, 0xef, 0xaa, 0x9b, 0x83, 0xd3, 0x10, 0x83, 0x05, 0x1d, 0xf0, 0xfc, 0x80, 0xa7, 0x86, 0x52, 0x91, 0x59, 0x48, 0x4f, 0x62, 0xbb, 0xb9, 0x52, 0x4f, 0x68, 0x28, 0x5f, 0x48, 0xc7, 0xab, 0x8e, 0x03, 0xbd, 0xfe, 0xca, 0x1a, 0x60, 0x25, 0xaa, 0xed, 0x9f, 0x97, 0x28, 0xb3, 0x90, 0x68, 0x9c, 0x0c, 0x96, 0x39, 0x20, 0xc7, 0x28, 0xeb, 0x56, 0x95, 0xfc, 0xb9, 0x41, 0x3f, 0x9f, 0x4e, 0x06, 0xd3, 0xb9, 0x3d, 0xb4, 0x0e, 0x26, 0xd6, 0x27, 0x5c, 0x84, 0xe6, 0x12, 0x6a ]
# byte_C2A0: AES-CBC encrypted password (48 bytes) encrypted_password_bytes = [ 0xad, 0xd1, 0xd1, 0x19, 0x60, 0xc2, 0x2d, 0x91, 0x66, 0xda, 0xc3, 0xc2, 0x67, 0x25, 0xc8, 0x19, 0x09, 0x17, 0x6b, 0x23, 0x8e, 0x30, 0x03, 0xaa, 0x57, 0xaa, 0xcb, 0xa0, 0xa2, 0x26, 0xb7, 0xc3, 0x1c, 0x22, 0x0b, 0x8d, 0x20, 0x9c, 0xb4, 0x95, 0xb5, 0x5d, 0xb4, 0xe2, 0x7d, 0x4e, 0x43, 0x8e ]
def main(): print("=" * 60) print("CTF Solver: Decrypting Login Password") print("=" * 60) # Convert hex to integers n = int(n_hex, 16) e = int(e_hex, 16) p = int(p_hex, 16) q = int(q_hex, 16) d = int(d_hex, 16) print("\n[*] RSA Key Parameters:") print(f" n = {n_hex[:32]}...") print(f" e = {e_hex}") print(f" d = {d_hex[:32]}...") # Verify: n == p * q if n == p * q: print("\n[+] Verified: n == p * q") else: print("\n[-] Error: n != p * q") return # Verify: d * e == 1 (mod phi(n)) phi_n = (p - 1) * (q - 1) if (d * e) % phi_n == 1: print("[+] Verified: d * e == 1 (mod phi(n))") else: print("[-] Warning: d * e != 1 (mod phi(n))") d_calc = pow(e, -1, phi_n) print(f"[*] Server d: {hex(d)[:40]}...") print(f"[*] Calculated d: {hex(d_calc)[:40]}...") # Use calculated d since server d might be wrong format d = d_calc # Create RSA key try: key = RSA.construct((n, e, d, p, q)) print("[+] RSA key constructed successfully") except Exception as ex: print(f"[-] Failed to construct RSA key: {ex}") return # Convert encrypted data to bytes encrypted_iv = bytes(encrypted_iv_bytes) encrypted_key = bytes(encrypted_key_bytes) encrypted_password = bytes(encrypted_password_bytes) print(f"\n[*] Encrypted data sizes:") print(f" RSA encrypted IV: {len(encrypted_iv)} bytes") print(f" RSA encrypted Key: {len(encrypted_key)} bytes") print(f" AES encrypted pwd: {len(encrypted_password)} bytes") # RSA decrypt with OAEP padding # Note: Server uses RSA_PKCS1_OAEP_PADDING (value 4) cipher_rsa = PKCS1_OAEP.new(key) try: aes_key = cipher_rsa.decrypt(encrypted_key) print(f"\n[+] RSA decrypted AES Key: {aes_key.hex()}") print(f" AES Key (ASCII): {aes_key}") except Exception as ex: print(f"[-] RSA decrypt key failed: {ex}") # Try raw RSA decryption print("[*] Trying raw RSA decryption...") c = int.from_bytes(encrypted_key, 'big') m = pow(c, d, n) aes_key = m.to_bytes((m.bit_length() + 7) // 8, 'big') print(f" Raw decrypted: {aes_key.hex()}") # Extract last 16 bytes (PKCS#1 padding stripped) aes_key = aes_key[-16:] if len(aes_key) > 16 else aes_key print(f" AES Key: {aes_key.hex()}") try: aes_iv = cipher_rsa.decrypt(encrypted_iv) print(f"\n[+] RSA decrypted AES IV: {aes_iv.hex()}") print(f" AES IV (ASCII): {aes_iv}") except Exception as ex: print(f"[-] RSA decrypt IV failed: {ex}") # Try raw RSA decryption print("[*] Trying raw RSA decryption...") c = int.from_bytes(encrypted_iv, 'big') m = pow(c, d, n) aes_iv = m.to_bytes((m.bit_length() + 7) // 8, 'big') print(f" Raw decrypted: {aes_iv.hex()}") aes_iv = aes_iv[-16:] if len(aes_iv) > 16 else aes_iv print(f" AES IV: {aes_iv.hex()}") # AES-CBC decrypt the password print(f"\n[*] Decrypting password with AES-CBC...") print(f" Key: {aes_key.hex() if isinstance(aes_key, bytes) else aes_key}") print(f" IV: {aes_iv.hex() if isinstance(aes_iv, bytes) else aes_iv}") print(f" Ciphertext: {encrypted_password.hex()}") try: # Standard AES-CBC decrypt cipher_aes = AES.new(aes_key, AES.MODE_CBC, aes_iv) decrypted = cipher_aes.decrypt(encrypted_password) print(f"\n[+] Decrypted (raw hex): {decrypted.hex()}") print(f"[+] Decrypted (raw bytes): {decrypted}") # Try to unpad PKCS7 try: decrypted_unpadded = unpad(decrypted, 16) print(f"[+] Decrypted (unpadded): {decrypted_unpadded}") except Exception as pe: print(f"[-] Unpad failed: {pe}") decrypted_unpadded = decrypted # Note: In client code, the key/iv parameters are swapped! # Client uses "key" from config as IV and "account" as Key # But the actual AES usage is swapped internally print(f"\n[*] Note: Client swaps Key/IV internally") cipher_correct = AES.new(aes_iv, AES.MODE_CBC, aes_key) decrypted_correct = cipher_correct.decrypt(encrypted_password) try: flag = unpad(decrypted_correct, 16).decode('utf-8') except: flag = decrypted_correct.decode('utf-8', errors='replace') print(f"\n{'=' * 60}") print(f"[+] FLAG: {flag}") print(f"{'=' * 60}") except Exception as ex: print(f"[-] AES decrypt failed: {ex}") import traceback traceback.print_exc()
if __name__ == "__main__": main()
|