mirror of
https://github.com/ValdikSS/GoodbyeDPI.git
synced 2024-11-23 10:29:38 +01:00
Add TLS ClientHello fake packet generator
This commit is contained in:
parent
c0f43a293e
commit
810aef6aed
@ -67,6 +67,10 @@ Usage: goodbyedpi.exe [OPTION...]
|
||||
--fake-from-hex <value> Load fake packets for Fake Request Mode from HEX values (like 1234abcDEF).
|
||||
This option can be supplied multiple times, in this case each fake packet
|
||||
would be sent on every request in the command line argument order.
|
||||
--fake-with-sni <value> Generate fake packets for Fake Request Mode with given SNI domain name.
|
||||
The packets mimic Mozilla Firefox 130 TLS ClientHello packet
|
||||
(with random generated fake SessionID, key shares and ECH grease).
|
||||
Can be supplied multiple times for multiple fake packets.
|
||||
--fake-gen <value> Generate random-filled fake packets for Fake Request Mode, value of them
|
||||
(up to 30).
|
||||
--fake-resend <value> Send each fake packet value number of times.
|
||||
|
@ -57,6 +57,91 @@ static const unsigned char fake_https_request[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
// Captured from Firefox 130.0.1
|
||||
static const unsigned char fake_clienthello_part0[] = { // 116 bytes
|
||||
// TLS 1.2 ClientHello header (DD for length placeholder)
|
||||
0x16, 0x03, 0x01, 0xDD, 0xDD, 0x01, 0x00, 0xDD, 0xDD, 0x03, 0x03,
|
||||
// Random bytes (AA for placeholder)
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||
// Random Session ID
|
||||
0x20,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||
// Cipher Suites
|
||||
0x00, 0x22, 0x13, 0x01, 0x13, 0x03, 0x13, 0x02, 0xC0, 0x2B, 0xC0, 0x2F, 0xCC, 0xA9, 0xCC, 0xA8,
|
||||
0xC0, 0x2C, 0xC0, 0x30, 0xC0, 0x0A, 0xC0, 0x09, 0xC0, 0x13, 0xC0, 0x14, 0x00, 0x9C, 0x00, 0x9D,
|
||||
0x00, 0x2F, 0x00, 0x35,
|
||||
// Compression Methods
|
||||
0x01, 0x00,
|
||||
// Extensions Length
|
||||
0xDD, 0xDD,
|
||||
};
|
||||
// SNI: 00 00 L1 L1 L2 L2 00 L3 L3 (sni)
|
||||
// L1 = L+5, L2 = L+3, L3 = L // 9 + L bytes
|
||||
static const unsigned char fake_clienthello_part1[] = { // 523 bytes
|
||||
// extended_master_secret
|
||||
0x00, 0x17, 0x00, 0x00,
|
||||
// renegotiation_info
|
||||
0xFF, 0x01, 0x00, 0x01, 0x00,
|
||||
// supported_groups
|
||||
0x00, 0x0A, 0x00, 0x0E,
|
||||
0x00, 0x0C, 0x00, 0x1D, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x01, 0x00, 0x01, 0x01,
|
||||
// ex_point_formats
|
||||
0x00, 0x0B, 0x00, 0x02, 0x01, 0x00,
|
||||
// session_ticket
|
||||
0x00, 0x23, 0x00, 0x00,
|
||||
// ALPN
|
||||
0x00, 0x10, 0x00, 0x0E,
|
||||
0x00, 0x0C, 0x02, 0x68, 0x32, 0x08, 0x68, 0x74, 0x74, 0x70, 0x2F, 0x31, 0x2E, 0x31,
|
||||
// status_request
|
||||
0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
// delegated_credentials
|
||||
0x00, 0x22, 0x00, 0x0A, 0x00, 0x08, 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x02, 0x03,
|
||||
// key_share
|
||||
0x00, 0x33, 0x00, 0x6B, 0x00, 0x69, 0x00, 0x1D, 0x00, 0x20,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||
0x00, 0x17, 0x00, 0x41, 0x04,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||
// supported_versions
|
||||
0x00, 0x2B, 0x00, 0x05, 0x04, 0x03, 0x04, 0x03, 0x03,
|
||||
// signature_algorithms
|
||||
0x00, 0x0D, 0x00, 0x18, 0x00, 0x16, 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x08, 0x04, 0x08, 0x05,
|
||||
0x08, 0x06, 0x04, 0x01, 0x05, 0x01, 0x06, 0x01, 0x02, 0x03, 0x02, 0x01,
|
||||
// psk_key_exchange_modes
|
||||
0x00, 0x2D, 0x00, 0x02, 0x01, 0x01,
|
||||
// record_size_limit
|
||||
0x00, 0x1C, 0x00, 0x02, 0x40, 0x01,
|
||||
// encrypted_client_hello
|
||||
0xFE, 0x0D, 0x01, 0x19, 0x00, 0x00, 0x01, 0x00, 0x01, 0xAA, 0x00, 0x20,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||
0x00, 0xEF,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
|
||||
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA
|
||||
};
|
||||
// JA4: t13d1715h2_5b57614c22b0_5c2c66f702b0
|
||||
// JA4_r: t13d1715h2_002f,0035,009c,009d,1301,1302,1303,c009,c00a,c013,c014,c02b,c02c,c02f,c030,cca8,cca9_0005,000a,000b,000d,0017,001c,0022,0023,002b,002d,0033,fe0d,ff01_0403,0503,0603,0804,0805,0806,0401,0501,0601,0203,0201
|
||||
// JA3 Fullstring: 771,4865-4867-4866-49195-49199-52393-52392-49196-49200-49162-49161-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-34-51-43-13-45-28-65037,29-23-24-25-256-257,0
|
||||
// JA3: b5001237acdf006056b409cc433726b0
|
||||
|
||||
static int send_fake_data(const HANDLE w_filter,
|
||||
const PWINDIVERT_ADDRESS addr,
|
||||
const char *pkt,
|
||||
@ -311,3 +396,46 @@ int fake_load_random(unsigned int count, unsigned int maxsize) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void set_uint16be(unsigned char *buffer, int offset, int value) {
|
||||
buffer[offset] = (value >> 8) & 0xFF;
|
||||
buffer[offset + 1] = value & 0xFF;
|
||||
}
|
||||
|
||||
int fake_load_from_sni(const char *domain_name) {
|
||||
if (!domain_name) {
|
||||
return 1; // just extra safeguard against NPE
|
||||
}
|
||||
// calculate sizes
|
||||
const int name_size = strlen(domain_name);
|
||||
const int part0_size = sizeof(fake_clienthello_part0);
|
||||
const int part1_size = sizeof(fake_clienthello_part1);
|
||||
const int sni_head_size = 9;
|
||||
const int packet_size = part0_size + part1_size + sni_head_size + name_size;
|
||||
// allocate memory
|
||||
unsigned char *packet = malloc(packet_size);
|
||||
// copy major parts of packet
|
||||
memcpy(packet, fake_clienthello_part0, part0_size);
|
||||
memcpy(&packet[part0_size + sni_head_size + name_size], fake_clienthello_part1, part1_size);
|
||||
// replace placeholders with random generated values
|
||||
unsigned int random = 0;
|
||||
for (int i = 0; i < packet_size; i++) {
|
||||
if (packet[i] == 0xAA) {
|
||||
rand_s(&random);
|
||||
packet[i] = random & 0xFF;
|
||||
}
|
||||
}
|
||||
// write size fields into packet
|
||||
set_uint16be(packet, 0x0003, packet_size - 5);
|
||||
set_uint16be(packet, 0x0007, packet_size - 9);
|
||||
set_uint16be(packet, 0x0072, packet_size - 116);
|
||||
// write SNI extension
|
||||
set_uint16be(packet, part0_size + 0, 0x0000);
|
||||
set_uint16be(packet, part0_size + 2, name_size + 5);
|
||||
set_uint16be(packet, part0_size + 4, name_size + 3);
|
||||
packet[part0_size + 6] = 0x00;
|
||||
set_uint16be(packet, part0_size + 7, name_size);
|
||||
memcpy(&packet[part0_size + sni_head_size], domain_name, name_size);
|
||||
// add packet to fakes
|
||||
return fake_add(packet, packet_size);
|
||||
}
|
||||
|
@ -19,4 +19,5 @@ int send_fake_https_request(const HANDLE w_filter,
|
||||
const BYTE set_seq
|
||||
);
|
||||
int fake_load_from_hex(const char *data);
|
||||
int fake_load_from_sni(const char *domain_name);
|
||||
int fake_load_random(unsigned int count, unsigned int maxsize);
|
||||
|
@ -189,6 +189,7 @@ static struct option long_options[] = {
|
||||
{"reverse-frag",no_argument, 0, '(' },
|
||||
{"max-payload", optional_argument, 0, '|' },
|
||||
{"fake-from-hex", required_argument, 0, 'u' },
|
||||
{"fake-with-sni", required_argument, 0, '}' },
|
||||
{"fake-gen", required_argument, 0, 'j' },
|
||||
{"fake-resend", required_argument, 0, 't' },
|
||||
{"debug-exit", optional_argument, 0, 'x' },
|
||||
@ -948,6 +949,11 @@ int main(int argc, char *argv[]) {
|
||||
printf("WARNING: bad fake HEX value %s\n", optarg);
|
||||
}
|
||||
break;
|
||||
case '}': // --fake-with-sni
|
||||
if (fake_load_from_sni(optarg)) {
|
||||
printf("WARNING: bad domain name for SNI: %s\n", optarg);
|
||||
}
|
||||
break;
|
||||
case 'j': // --fake-gen
|
||||
if (fake_load_random(atoub(optarg, "Fake generator parameter error!"), 200)) {
|
||||
puts("WARNING: fake generator has failed!");
|
||||
@ -1013,6 +1019,10 @@ int main(int argc, char *argv[]) {
|
||||
" --fake-from-hex <value> Load fake packets for Fake Request Mode from HEX values (like 1234abcDEF).\n"
|
||||
" This option can be supplied multiple times, in this case each fake packet\n"
|
||||
" would be sent on every request in the command line argument order.\n"
|
||||
" --fake-with-sni <value> Generate fake packets for Fake Request Mode with given SNI domain name.\n"
|
||||
" The packets mimic Mozilla Firefox 130 TLS ClientHello packet\n"
|
||||
" (with random generated fake SessionID, key shares and ECH grease).\n"
|
||||
" Can be supplied multiple times for multiple fake packets.\n"
|
||||
" --fake-gen <value> Generate random-filled fake packets for Fake Request Mode, value of them\n"
|
||||
" (up to 30).\n"
|
||||
" --fake-resend <value> Send each fake packet value number of times.\n"
|
||||
|
Loading…
Reference in New Issue
Block a user