Öffnen Sie die Client-Datei in IDA Pro und stellen Sie sicher, dass ein Teil der Datei flag.jpg vom Server https://ssltest.a1exdandy.me:443/ heruntergeladen werden kann. Welcher Teil der herunterzuladenden Datei (von welchem Byte) wird von der Befehlszeile übernommen.
signed __int64 __fastcall main(int argc, char **argv, char **a3) { size_t v4; // rsi __int64 v5; // ST48_8 int v6; // [rsp+10h] [rbp-450h] int v7; // [rsp+14h] [rbp-44Ch] __int64 v8; // [rsp+20h] [rbp-440h] __int64 v9; // [rsp+28h] [rbp-438h] __int64 v10; // [rsp+30h] [rbp-430h] __int64 v11; // [rsp+38h] [rbp-428h] __int64 v12; // [rsp+40h] [rbp-420h] char ptr; // [rsp+50h] [rbp-410h] unsigned __int64 v14; // [rsp+458h] [rbp-8h] v14 = __readfsqword(0x28u); if ( argc != 3 ) return 0xFFFFFFFFLL; v6 = atoi(argv[1]); v7 = atoi(argv[2]); if ( v6 < 0 || v7 < 0 || v7 <= v6 ) return 0xFFFFFFFFLL; v8 = 0LL; v9 = 0LL; v10 = 0LL; OPENSSL_init_ssl(0LL, 0LL); OPENSSL_init_crypto(2048LL, 0LL); v11 = ENGINE_get_default_DH(2048LL, 0LL); if ( v11 ) { if ( (unsigned int)ENGINE_init(v11) ) { v12 = ENGINE_get_DH(v11); if ( v12 ) { v8 = DH_meth_dup(v12); if ( v8 ) { if ( (unsigned int)DH_meth_set_generate_key(v8, dh_1) ) { if ( (unsigned int)ENGINE_set_DH(v11, v8) ) { v5 = TLSv1_2_client_method(v11, v8); v10 = SSL_CTX_new(v5); if ( (unsigned int)SSL_CTX_set_cipher_list(v10, "DHE-RSA-AES128-SHA256") ) { v9 = BIO_new_ssl_connect(v10); BIO_ctrl(v9, 100LL, 0LL, (__int64)"ssltest.a1exdandy.me:443"); if ( BIO_ctrl(v9, 101LL, 0LL, 0LL) >= 0 ) { BIO_ctrl(v9, 101LL, 0LL, 0LL); BIO_printf(v9, "GET /flag.jpg HTTP/1.1\n", argv); BIO_printf(v9, "Host: ssltest.a1exdandy.me\n"); BIO_printf(v9, "Range: bytes=%d-%d\n\n", (unsigned int)v6, (unsigned int)v7); v4 = (signed int)BIO_read(v9, &ptr, 1024LL); fwrite(&ptr, v4, 1uLL, stdout); } else { v4 = 1LL; fwrite("Can't do connect\n", 1uLL, 0x11uLL, stderr); } } else { v4 = 1LL; fwrite("Can't set cipher list\n", 1uLL, 0x16uLL, stderr); } } else { v4 = 1LL; fwrite("Can't set DH methods\n", 1uLL, 0x15uLL, stderr); } } else { v4 = 1LL; fwrite("Can't set generate_key method\n", 1uLL, 0x1EuLL, stderr); } } else { v4 = 1LL; fwrite("Can't dup dh meth\n", 1uLL, 0x12uLL, stderr); } } else { v4 = 1LL; fwrite("Can't get DH\n", 1uLL, 0xDuLL, stderr); } } else { v4 = 1LL; fwrite("Can't init engine\n", 1uLL, 0x12uLL, stderr); } } else { v4 = 1LL; fwrite("Can't get DH\n", 1uLL, 0xDuLL, stderr); } if ( v11 ) { ENGINE_finish(v11, v4); ENGINE_free(v11); } if ( v8 ) DH_meth_free(v8, v4); if ( v10 ) SSL_CTX_free(v10, v4); if ( v9 ) BIO_free_all(v9, v4); return 0LL; }
-44Ch] signed __int64 __fastcall main(int argc, char **argv, char **a3) { size_t v4; // rsi __int64 v5; // ST48_8 int v6; // [rsp+10h] [rbp-450h] int v7; // [rsp+14h] [rbp-44Ch] __int64 v8; // [rsp+20h] [rbp-440h] __int64 v9; // [rsp+28h] [rbp-438h] __int64 v10; // [rsp+30h] [rbp-430h] __int64 v11; // [rsp+38h] [rbp-428h] __int64 v12; // [rsp+40h] [rbp-420h] char ptr; // [rsp+50h] [rbp-410h] unsigned __int64 v14; // [rsp+458h] [rbp-8h] v14 = __readfsqword(0x28u); if ( argc != 3 ) return 0xFFFFFFFFLL; v6 = atoi(argv[1]); v7 = atoi(argv[2]); if ( v6 < 0 || v7 < 0 || v7 <= v6 ) return 0xFFFFFFFFLL; v8 = 0LL; v9 = 0LL; v10 = 0LL; OPENSSL_init_ssl(0LL, 0LL); OPENSSL_init_crypto(2048LL, 0LL); v11 = ENGINE_get_default_DH(2048LL, 0LL); if ( v11 ) { if ( (unsigned int)ENGINE_init(v11) ) { v12 = ENGINE_get_DH(v11); if ( v12 ) { v8 = DH_meth_dup(v12); if ( v8 ) { if ( (unsigned int)DH_meth_set_generate_key(v8, dh_1) ) { if ( (unsigned int)ENGINE_set_DH(v11, v8) ) { v5 = TLSv1_2_client_method(v11, v8); v10 = SSL_CTX_new(v5); if ( (unsigned int)SSL_CTX_set_cipher_list(v10, "DHE-RSA-AES128-SHA256") ) { v9 = BIO_new_ssl_connect(v10); BIO_ctrl(v9, 100LL, 0LL, (__int64)"ssltest.a1exdandy.me:443"); if ( BIO_ctrl(v9, 101LL, 0LL, 0LL) >= 0 ) { BIO_ctrl(v9, 101LL, 0LL, 0LL); BIO_printf(v9, "GET /flag.jpg HTTP/1.1\n", argv); BIO_printf(v9, "Host: ssltest.a1exdandy.me\n"); BIO_printf(v9, "Range: bytes=%d-%d\n\n", (unsigned int)v6, (unsigned int)v7); v4 = (signed int)BIO_read(v9, &ptr, 1024LL); fwrite(&ptr, v4, 1uLL, stdout); } else { v4 = 1LL; fwrite("Can't do connect\n", 1uLL, 0x11uLL, stderr); } } else { v4 = 1LL; fwrite("Can't set cipher list\n", 1uLL, 0x16uLL, stderr); } } else { v4 = 1LL; fwrite("Can't set DH methods\n", 1uLL, 0x15uLL, stderr); } } else { v4 = 1LL; fwrite("Can't set generate_key method\n", 1uLL, 0x1EuLL, stderr); } } else { v4 = 1LL; fwrite("Can't dup dh meth\n", 1uLL, 0x12uLL, stderr); } } else { v4 = 1LL; fwrite("Can't get DH\n", 1uLL, 0xDuLL, stderr); } } else { v4 = 1LL; fwrite("Can't init engine\n", 1uLL, 0x12uLL, stderr); } } else { v4 = 1LL; fwrite("Can't get DH\n", 1uLL, 0xDuLL, stderr); } if ( v11 ) { ENGINE_finish(v11, v4); ENGINE_free(v11); } if ( v8 ) DH_meth_free(v8, v4); if ( v10 ) SSL_CTX_free(v10, v4); if ( v9 ) BIO_free_all(v9, v4); return 0LL; }
; signed __int64 __fastcall main(int argc, char **argv, char **a3) { size_t v4; // rsi __int64 v5; // ST48_8 int v6; // [rsp+10h] [rbp-450h] int v7; // [rsp+14h] [rbp-44Ch] __int64 v8; // [rsp+20h] [rbp-440h] __int64 v9; // [rsp+28h] [rbp-438h] __int64 v10; // [rsp+30h] [rbp-430h] __int64 v11; // [rsp+38h] [rbp-428h] __int64 v12; // [rsp+40h] [rbp-420h] char ptr; // [rsp+50h] [rbp-410h] unsigned __int64 v14; // [rsp+458h] [rbp-8h] v14 = __readfsqword(0x28u); if ( argc != 3 ) return 0xFFFFFFFFLL; v6 = atoi(argv[1]); v7 = atoi(argv[2]); if ( v6 < 0 || v7 < 0 || v7 <= v6 ) return 0xFFFFFFFFLL; v8 = 0LL; v9 = 0LL; v10 = 0LL; OPENSSL_init_ssl(0LL, 0LL); OPENSSL_init_crypto(2048LL, 0LL); v11 = ENGINE_get_default_DH(2048LL, 0LL); if ( v11 ) { if ( (unsigned int)ENGINE_init(v11) ) { v12 = ENGINE_get_DH(v11); if ( v12 ) { v8 = DH_meth_dup(v12); if ( v8 ) { if ( (unsigned int)DH_meth_set_generate_key(v8, dh_1) ) { if ( (unsigned int)ENGINE_set_DH(v11, v8) ) { v5 = TLSv1_2_client_method(v11, v8); v10 = SSL_CTX_new(v5); if ( (unsigned int)SSL_CTX_set_cipher_list(v10, "DHE-RSA-AES128-SHA256") ) { v9 = BIO_new_ssl_connect(v10); BIO_ctrl(v9, 100LL, 0LL, (__int64)"ssltest.a1exdandy.me:443"); if ( BIO_ctrl(v9, 101LL, 0LL, 0LL) >= 0 ) { BIO_ctrl(v9, 101LL, 0LL, 0LL); BIO_printf(v9, "GET /flag.jpg HTTP/1.1\n", argv); BIO_printf(v9, "Host: ssltest.a1exdandy.me\n"); BIO_printf(v9, "Range: bytes=%d-%d\n\n", (unsigned int)v6, (unsigned int)v7); v4 = (signed int)BIO_read(v9, &ptr, 1024LL); fwrite(&ptr, v4, 1uLL, stdout); } else { v4 = 1LL; fwrite("Can't do connect\n", 1uLL, 0x11uLL, stderr); } } else { v4 = 1LL; fwrite("Can't set cipher list\n", 1uLL, 0x16uLL, stderr); } } else { v4 = 1LL; fwrite("Can't set DH methods\n", 1uLL, 0x15uLL, stderr); } } else { v4 = 1LL; fwrite("Can't set generate_key method\n", 1uLL, 0x1EuLL, stderr); } } else { v4 = 1LL; fwrite("Can't dup dh meth\n", 1uLL, 0x12uLL, stderr); } } else { v4 = 1LL; fwrite("Can't get DH\n", 1uLL, 0xDuLL, stderr); } } else { v4 = 1LL; fwrite("Can't init engine\n", 1uLL, 0x12uLL, stderr); } } else { v4 = 1LL; fwrite("Can't get DH\n", 1uLL, 0xDuLL, stderr); } if ( v11 ) { ENGINE_finish(v11, v4); ENGINE_free(v11); } if ( v8 ) DH_meth_free(v8, v4); if ( v10 ) SSL_CTX_free(v10, v4); if ( v9 ) BIO_free_all(v9, v4); return 0LL; }
(__int64) "ssltest.a1exdandy.me:443"); signed __int64 __fastcall main(int argc, char **argv, char **a3) { size_t v4; // rsi __int64 v5; // ST48_8 int v6; // [rsp+10h] [rbp-450h] int v7; // [rsp+14h] [rbp-44Ch] __int64 v8; // [rsp+20h] [rbp-440h] __int64 v9; // [rsp+28h] [rbp-438h] __int64 v10; // [rsp+30h] [rbp-430h] __int64 v11; // [rsp+38h] [rbp-428h] __int64 v12; // [rsp+40h] [rbp-420h] char ptr; // [rsp+50h] [rbp-410h] unsigned __int64 v14; // [rsp+458h] [rbp-8h] v14 = __readfsqword(0x28u); if ( argc != 3 ) return 0xFFFFFFFFLL; v6 = atoi(argv[1]); v7 = atoi(argv[2]); if ( v6 < 0 || v7 < 0 || v7 <= v6 ) return 0xFFFFFFFFLL; v8 = 0LL; v9 = 0LL; v10 = 0LL; OPENSSL_init_ssl(0LL, 0LL); OPENSSL_init_crypto(2048LL, 0LL); v11 = ENGINE_get_default_DH(2048LL, 0LL); if ( v11 ) { if ( (unsigned int)ENGINE_init(v11) ) { v12 = ENGINE_get_DH(v11); if ( v12 ) { v8 = DH_meth_dup(v12); if ( v8 ) { if ( (unsigned int)DH_meth_set_generate_key(v8, dh_1) ) { if ( (unsigned int)ENGINE_set_DH(v11, v8) ) { v5 = TLSv1_2_client_method(v11, v8); v10 = SSL_CTX_new(v5); if ( (unsigned int)SSL_CTX_set_cipher_list(v10, "DHE-RSA-AES128-SHA256") ) { v9 = BIO_new_ssl_connect(v10); BIO_ctrl(v9, 100LL, 0LL, (__int64)"ssltest.a1exdandy.me:443"); if ( BIO_ctrl(v9, 101LL, 0LL, 0LL) >= 0 ) { BIO_ctrl(v9, 101LL, 0LL, 0LL); BIO_printf(v9, "GET /flag.jpg HTTP/1.1\n", argv); BIO_printf(v9, "Host: ssltest.a1exdandy.me\n"); BIO_printf(v9, "Range: bytes=%d-%d\n\n", (unsigned int)v6, (unsigned int)v7); v4 = (signed int)BIO_read(v9, &ptr, 1024LL); fwrite(&ptr, v4, 1uLL, stdout); } else { v4 = 1LL; fwrite("Can't do connect\n", 1uLL, 0x11uLL, stderr); } } else { v4 = 1LL; fwrite("Can't set cipher list\n", 1uLL, 0x16uLL, stderr); } } else { v4 = 1LL; fwrite("Can't set DH methods\n", 1uLL, 0x15uLL, stderr); } } else { v4 = 1LL; fwrite("Can't set generate_key method\n", 1uLL, 0x1EuLL, stderr); } } else { v4 = 1LL; fwrite("Can't dup dh meth\n", 1uLL, 0x12uLL, stderr); } } else { v4 = 1LL; fwrite("Can't get DH\n", 1uLL, 0xDuLL, stderr); } } else { v4 = 1LL; fwrite("Can't init engine\n", 1uLL, 0x12uLL, stderr); } } else { v4 = 1LL; fwrite("Can't get DH\n", 1uLL, 0xDuLL, stderr); } if ( v11 ) { ENGINE_finish(v11, v4); ENGINE_free(v11); } if ( v8 ) DH_meth_free(v8, v4); if ( v10 ) SSL_CTX_free(v10, v4); if ( v9 ) BIO_free_all(v9, v4); return 0LL; }
\ n", 1uLL, 0x16uLL, Stderr); signed __int64 __fastcall main(int argc, char **argv, char **a3) { size_t v4; // rsi __int64 v5; // ST48_8 int v6; // [rsp+10h] [rbp-450h] int v7; // [rsp+14h] [rbp-44Ch] __int64 v8; // [rsp+20h] [rbp-440h] __int64 v9; // [rsp+28h] [rbp-438h] __int64 v10; // [rsp+30h] [rbp-430h] __int64 v11; // [rsp+38h] [rbp-428h] __int64 v12; // [rsp+40h] [rbp-420h] char ptr; // [rsp+50h] [rbp-410h] unsigned __int64 v14; // [rsp+458h] [rbp-8h] v14 = __readfsqword(0x28u); if ( argc != 3 ) return 0xFFFFFFFFLL; v6 = atoi(argv[1]); v7 = atoi(argv[2]); if ( v6 < 0 || v7 < 0 || v7 <= v6 ) return 0xFFFFFFFFLL; v8 = 0LL; v9 = 0LL; v10 = 0LL; OPENSSL_init_ssl(0LL, 0LL); OPENSSL_init_crypto(2048LL, 0LL); v11 = ENGINE_get_default_DH(2048LL, 0LL); if ( v11 ) { if ( (unsigned int)ENGINE_init(v11) ) { v12 = ENGINE_get_DH(v11); if ( v12 ) { v8 = DH_meth_dup(v12); if ( v8 ) { if ( (unsigned int)DH_meth_set_generate_key(v8, dh_1) ) { if ( (unsigned int)ENGINE_set_DH(v11, v8) ) { v5 = TLSv1_2_client_method(v11, v8); v10 = SSL_CTX_new(v5); if ( (unsigned int)SSL_CTX_set_cipher_list(v10, "DHE-RSA-AES128-SHA256") ) { v9 = BIO_new_ssl_connect(v10); BIO_ctrl(v9, 100LL, 0LL, (__int64)"ssltest.a1exdandy.me:443"); if ( BIO_ctrl(v9, 101LL, 0LL, 0LL) >= 0 ) { BIO_ctrl(v9, 101LL, 0LL, 0LL); BIO_printf(v9, "GET /flag.jpg HTTP/1.1\n", argv); BIO_printf(v9, "Host: ssltest.a1exdandy.me\n"); BIO_printf(v9, "Range: bytes=%d-%d\n\n", (unsigned int)v6, (unsigned int)v7); v4 = (signed int)BIO_read(v9, &ptr, 1024LL); fwrite(&ptr, v4, 1uLL, stdout); } else { v4 = 1LL; fwrite("Can't do connect\n", 1uLL, 0x11uLL, stderr); } } else { v4 = 1LL; fwrite("Can't set cipher list\n", 1uLL, 0x16uLL, stderr); } } else { v4 = 1LL; fwrite("Can't set DH methods\n", 1uLL, 0x15uLL, stderr); } } else { v4 = 1LL; fwrite("Can't set generate_key method\n", 1uLL, 0x1EuLL, stderr); } } else { v4 = 1LL; fwrite("Can't dup dh meth\n", 1uLL, 0x12uLL, stderr); } } else { v4 = 1LL; fwrite("Can't get DH\n", 1uLL, 0xDuLL, stderr); } } else { v4 = 1LL; fwrite("Can't init engine\n", 1uLL, 0x12uLL, stderr); } } else { v4 = 1LL; fwrite("Can't get DH\n", 1uLL, 0xDuLL, stderr); } if ( v11 ) { ENGINE_finish(v11, v4); ENGINE_free(v11); } if ( v8 ) DH_meth_free(v8, v4); if ( v10 ) SSL_CTX_free(v10, v4); if ( v9 ) BIO_free_all(v9, v4); return 0LL; }
Es gab keine Bilder mit der Flagge auf dem Server, aber dump.pcap hatte eine Menge SSL-Verkehr, vermutlich mit Teilen des Bildes. Nach einer kurzen Überprüfung des Servers auf Heartbleed (um einen privaten Schlüssel zum Entschlüsseln des Datenverkehrs zu stehlen) wurde festgestellt, dass der Server nicht anfällig ist. Darüber hinaus SSL-Sitzungen nach Dump-Traffic und Kunden mit Chiffre DHE-RSA-AES128-SHA256, wo RSA nur zum Signieren verwendet wird, und der Schlüsselaustausch erfolgen im Rahmen der Regelung Diffie-Hellman-Algorithmus (RSA private Schlüssel des Servers in diesem Modus werden uns nicht helfen )
Nachdem ich mir den Client genau angesehen hatte, stellte ich fest, dass er einen benutzerdefinierten Diffie-Hellman-Geheimgenerator verwendet:
int __fastcall rnd_work(__int64 a1) { __int64 v1; // rsi unsigned int i; // [rsp+10h] [rbp-10h] rnd_read(); BN_bin2bn(&RANDOM_512, 512LL, a1); BN_lshift1(a1, a1); v1 = (unsigned int)BITS_ind[0]; // BITS_ind dd 4096, 4095, 4081, 4069, 0 if ( (unsigned int)BN_is_bit_set(a1, (unsigned int)BITS_ind[0]) ) { for ( i = 0; i <= 4; ++i ) { if ( (unsigned int)BN_is_bit_set(a1, (unsigned int)BITS_ind[i]) ) { v1 = (unsigned int)BITS_ind[i]; BN_clear_bit(a1, v1); } else { v1 = (unsigned int)BITS_ind[i]; BN_set_bit(a1, v1); } } } if ( (unsigned int)((signed int)((unsigned __int64)BN_num_bits(a1) + 7) / 8) > 0x200 ) { printf("Err!", v1); exit(0); } BN_bn2binpad(a1, &RANDOM_512, 512LL); return rnd_write(); }
a1, (unsigned int) BITS_ind [i])) int __fastcall rnd_work(__int64 a1) { __int64 v1; // rsi unsigned int i; // [rsp+10h] [rbp-10h] rnd_read(); BN_bin2bn(&RANDOM_512, 512LL, a1); BN_lshift1(a1, a1); v1 = (unsigned int)BITS_ind[0]; // BITS_ind dd 4096, 4095, 4081, 4069, 0 if ( (unsigned int)BN_is_bit_set(a1, (unsigned int)BITS_ind[0]) ) { for ( i = 0; i <= 4; ++i ) { if ( (unsigned int)BN_is_bit_set(a1, (unsigned int)BITS_ind[i]) ) { v1 = (unsigned int)BITS_ind[i]; BN_clear_bit(a1, v1); } else { v1 = (unsigned int)BITS_ind[i]; BN_set_bit(a1, v1); } } } if ( (unsigned int)((signed int)((unsigned __int64)BN_num_bits(a1) + 7) / 8) > 0x200 ) { printf("Err!", v1); exit(0); } BN_bn2binpad(a1, &RANDOM_512, 512LL); return rnd_write(); }
); int __fastcall rnd_work(__int64 a1) { __int64 v1; // rsi unsigned int i; // [rsp+10h] [rbp-10h] rnd_read(); BN_bin2bn(&RANDOM_512, 512LL, a1); BN_lshift1(a1, a1); v1 = (unsigned int)BITS_ind[0]; // BITS_ind dd 4096, 4095, 4081, 4069, 0 if ( (unsigned int)BN_is_bit_set(a1, (unsigned int)BITS_ind[0]) ) { for ( i = 0; i <= 4; ++i ) { if ( (unsigned int)BN_is_bit_set(a1, (unsigned int)BITS_ind[i]) ) { v1 = (unsigned int)BITS_ind[i]; BN_clear_bit(a1, v1); } else { v1 = (unsigned int)BITS_ind[i]; BN_set_bit(a1, v1); } } } if ( (unsigned int)((signed int)((unsigned __int64)BN_num_bits(a1) + 7) / 8) > 0x200 ) { printf("Err!", v1); exit(0); } BN_bn2binpad(a1, &RANDOM_512, 512LL); return rnd_write(); }
Zunächst wird das Geheimnis (512 Bytes) aus / dev / urandom gelesen und in der Statusdatei gespeichert. Bei jeder nachfolgenden Anfrage geschieht die folgende Magie mit einem Geheimnis:
XOR = 2**4096 + 2**4095 + 2**4081 + 2**4069 + 1 CMP = 2**4096 state *= 2 if state > CMP: state ^= XOR
Das Geheimnis als lange Zahl wird um 1 Bit nach links verschoben, und wenn das höchstwertige Bit 1 war, liegt die Zahl bei einer Konstante von 5 Nicht-Null-Bits (XOR).