From f0d42129aa3241c8e48513f08a9587039a23a55a Mon Sep 17 00:00:00 2001 From: ValdikSS Date: Sat, 14 Sep 2024 22:31:15 +0300 Subject: [PATCH] --fake-from-hex option: load Fake Packet from HEX data This option replaces built-in fake packets with the user-supplied ones, could be used multiple times (up to 30). Each fake packet loaded with this option is sent in command line order, every time (on each TLS ClientHello or HTTP GET/POST). --- README.md | 3 ++ src/fakepackets.c | 109 +++++++++++++++++++++++++++++++++++++++++----- src/goodbyedpi.c | 9 ++++ 3 files changed, 111 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 1fb625f..0c0dabb 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,9 @@ Usage: goodbyedpi.exe [OPTION...] --reverse-frag fragment (split) the packets just as --native-frag, but send them in the reversed order. Works with the websites which could not handle segmented HTTPS TLS ClientHello (because they receive the TCP flow "combined"). + --fake-from-hex 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. --max-payload [value] packets with TCP payload data more than [value] won't be processed. Use this option to reduce CPU usage by skipping huge amount of data (like file transfers) in already established sessions. diff --git a/src/fakepackets.c b/src/fakepackets.c index 6d59cd8..b7fb1e2 100644 --- a/src/fakepackets.c +++ b/src/fakepackets.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -7,6 +8,14 @@ #include "windivert.h" #include "goodbyedpi.h" +struct fake_t { + const unsigned char* data; + size_t size; +}; + +static struct fake_t *fakes[30] = {0}; +int fakes_count = 0; + static const unsigned char fake_http_request[] = "GET / HTTP/1.1\r\nHost: www.w3.org\r\n" "User-Agent: curl/7.65.3\r\nAccept: */*\r\n" "Accept-Encoding: deflate, gzip, br\r\n\r\n"; @@ -54,7 +63,8 @@ static int send_fake_data(const HANDLE w_filter, const BOOL is_https, const BYTE set_ttl, const BYTE set_checksum, - const BYTE set_seq + const BYTE set_seq, + const struct fake_t *fake_data ) { char packet_fake[MAX_PACKET_SIZE]; WINDIVERT_ADDRESS addr_new; @@ -66,6 +76,10 @@ static int send_fake_data(const HANDLE w_filter, PWINDIVERT_TCPHDR ppTcpHdr; unsigned const char *fake_request_data = is_https ? fake_https_request : fake_http_request; UINT fake_request_size = is_https ? sizeof(fake_https_request) : sizeof(fake_http_request) - 1; + if (fake_data) { + fake_request_data = fake_data->data; + fake_request_size = fake_data->size; + } memcpy(&addr_new, addr, sizeof(WINDIVERT_ADDRESS)); memcpy(packet_fake, pkt, packetLen); @@ -148,22 +162,26 @@ static int send_fake_request(const HANDLE w_filter, const BOOL is_https, const BYTE set_ttl, const BYTE set_checksum, - const BYTE set_seq + const BYTE set_seq, + const struct fake_t *fake_data ) { if (set_ttl) { send_fake_data(w_filter, addr, pkt, packetLen, is_ipv6, is_https, - set_ttl, FALSE, FALSE); + set_ttl, FALSE, FALSE, + fake_data); } if (set_checksum) { send_fake_data(w_filter, addr, pkt, packetLen, is_ipv6, is_https, - FALSE, set_checksum, FALSE); + FALSE, set_checksum, FALSE, + fake_data); } if (set_seq) { send_fake_data(w_filter, addr, pkt, packetLen, is_ipv6, is_https, - FALSE, FALSE, set_seq); + FALSE, FALSE, set_seq, + fake_data); } return 0; } @@ -177,9 +195,17 @@ int send_fake_http_request(const HANDLE w_filter, const BYTE set_checksum, const BYTE set_seq ) { - return send_fake_request(w_filter, addr, pkt, packetLen, - is_ipv6, FALSE, - set_ttl, set_checksum, set_seq); + int ret = 0; + for (int i=0; isize = size; + fake->data = data; + + for (size_t k = 0; k <= sizeof(fakes) / sizeof(*fakes); k++) { + if (!fakes[k]) { + fakes[k] = fake; + fakes_count++; + return 0; + } + } + return 3; +} + +int fake_load_from_hex(const char *data) { + size_t len = strlen(data); + if (len < 2 || len % 2 || len > 1420) + return 1; + + unsigned char *finaldata = calloc((len + 2) / 2, 1); + + for (size_t i = 0; i= '0' && curchar <= '9') + curchar -= '0'; + else if (curchar >= 'a' && curchar <= 'f') + curchar -= 'a' - 0xA; + else if (curchar >= 'A' && curchar <= 'F') + curchar -= 'A' - 0xA; + else + return 2; // incorrect character, not a hex data + + if (!j) { + num1 = curchar; + curchar = num2; + continue; + } + num2 = curchar; + } + debug("Processed num1: %X, num2: %X\n", num1, num2); + finalchar = (num1 << 4) | num2; + debug("Final char: %X\n", finalchar); + finaldata[i/2] = finalchar; + } + + return fake_add(finaldata, len / 2); } diff --git a/src/goodbyedpi.c b/src/goodbyedpi.c index 03c85be..bf43e19 100644 --- a/src/goodbyedpi.c +++ b/src/goodbyedpi.c @@ -188,6 +188,7 @@ static struct option long_options[] = { {"native-frag", no_argument, 0, '*' }, {"reverse-frag",no_argument, 0, '(' }, {"max-payload", optional_argument, 0, '|' }, + {"fake-from-hex", required_argument, 0, 'u' }, {"debug-exit", optional_argument, 0, 'x' }, {0, 0, 0, 0 } }; @@ -940,6 +941,11 @@ int main(int argc, char *argv[]) { else max_payload_size = 1200; break; + case 'u': // --fake-from-hex + if (fake_load_from_hex(optarg)) { + printf("WARNING: bad fake HEX value %s\n", optarg); + } + break; case 'x': // --debug-exit debug_exit = true; break; @@ -988,6 +994,9 @@ int main(int argc, char *argv[]) { " --reverse-frag fragment (split) the packets just as --native-frag, but send them in the\n" " reversed order. Works with the websites which could not handle segmented\n" " HTTPS TLS ClientHello (because they receive the TCP flow \"combined\").\n" + " --fake-from-hex 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" " --max-payload [value] packets with TCP payload data more than [value] won't be processed.\n" " Use this option to reduce CPU usage by skipping huge amount of data\n" " (like file transfers) in already established sessions.\n"