From cc1676ad92c85011f14c5fa2c9628ba34d3412ae Mon Sep 17 00:00:00 2001 From: ValdikSS Date: Wed, 29 Dec 2021 16:18:56 +0300 Subject: [PATCH] --allow-no-sni option. Useful with --blacklist and undetectable SNI. This option is added specially for protonmail.com, as it sends low Window Size in SYN-ACK for requests from Russia, to force the client to fragment the packet. GoodbyeDPI doesn't do reassembling and can't extract SNI in this case, thus won't circumvent the censorship if --blacklist option is used. --- README.md | 1 + src/goodbyedpi.c | 37 ++++++++++++++++++++++++++----------- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 15e4eca..1593167 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ Usage: goodbyedpi.exe [OPTION...] --blacklist perform circumvention tricks only to host names and subdomains from supplied text file (HTTP Host/TLS SNI). This option can be supplied multiple times. + --allow-no-sni perform circumvention if TLS SNI can't be detected with --blacklist enabled. --set-ttl activate Fake Request Mode and send it with supplied TTL value. DANGEROUS! May break websites in unexpected ways. Use with care. --auto-ttl [a1-a2-m] activate Fake Request Mode, automatically detect TTL and decrease diff --git a/src/goodbyedpi.c b/src/goodbyedpi.c index 2327f92..8f1bbec 100644 --- a/src/goodbyedpi.c +++ b/src/goodbyedpi.c @@ -160,6 +160,7 @@ static struct option long_options[] = { {"dnsv6-port", required_argument, 0, '@' }, {"dns-verb", no_argument, 0, 'v' }, {"blacklist", required_argument, 0, 'b' }, + {"allow-no-sni",no_argument, 0, ']' }, {"ip-id", required_argument, 0, 'i' }, {"set-ttl", required_argument, 0, '$' }, {"min-ttl", required_argument, 0, '[' }, @@ -523,6 +524,7 @@ int main(int argc, char *argv[]) { ipv6_tcp, ipv6_tcp_data, ipv6_udp_data } packet_type; int i, should_reinject, should_recalc_checksum = 0; + int sni_ok = 0; int opt; int packet_v4, packet_v6; HANDLE w_filter = NULL; @@ -547,6 +549,7 @@ int main(int argc, char *argv[]) { do_host_mixedcase = 0, do_dnsv4_redirect = 0, do_dnsv6_redirect = 0, do_dns_verb = 0, do_tcp_verb = 0, do_blacklist = 0, + do_allow_no_sni = 0, do_fake_packet = 0, do_auto_ttl = 0, do_wrong_chksum = 0, @@ -778,6 +781,9 @@ int main(int argc, char *argv[]) { exit(EXIT_FAILURE); } break; + case ']': // --allow-no-sni + do_allow_no_sni = 1; + break; case '$': // --set-ttl do_fake_packet = 1; ttl_of_fake_packet = atoub(optarg, "Set TTL parameter error!"); @@ -861,6 +867,7 @@ int main(int argc, char *argv[]) { " --blacklist perform circumvention tricks only to host names and subdomains from\n" " supplied text file (HTTP Host/TLS SNI).\n" " This option can be supplied multiple times.\n" + " --allow-no-sni perform circumvention if TLS SNI can't be detected with --blacklist enabled.\n" " --set-ttl activate Fake Request Mode and send it with supplied TTL value.\n" " DANGEROUS! May break websites in unexpected ways. Use with care (or --blacklist).\n" " --auto-ttl [a1-a2-m] activate Fake Request Mode, automatically detect TTL and decrease\n" @@ -925,9 +932,10 @@ int main(int argc, char *argv[]) { "HTTP Persistent Nowait: %d\n" /* 12 */ "DNS redirect: %d\n" /* 13 */ "DNSv6 redirect: %d\n" /* 14 */ - "Fake requests, TTL: %s (fixed: %hu, auto: %hu-%hu-%hu, min distance: %hu)\n" /* 15 */ - "Fake requests, wrong checksum: %d\n" /* 16 */ - "Fake requests, wrong SEQ/ACK: %d\n", /* 17 */ + "Allow missing SNI: %d\n" /* 15 */ + "Fake requests, TTL: %s (fixed: %hu, auto: %hu-%hu-%hu, min distance: %hu)\n" /* 16 */ + "Fake requests, wrong checksum: %d\n" /* 17 */ + "Fake requests, wrong SEQ/ACK: %d\n", /* 18 */ do_passivedpi, /* 1 */ (do_fragment_http ? http_fragment_size : 0), /* 2 */ (do_fragment_http_persistent ? http_fragment_size : 0),/* 3 */ @@ -942,11 +950,12 @@ int main(int argc, char *argv[]) { do_fragment_http_persistent_nowait, /* 12 */ do_dnsv4_redirect, /* 13 */ do_dnsv6_redirect, /* 14 */ - ttl_of_fake_packet ? "fixed" : (do_auto_ttl ? "auto" : "disabled"), /* 15 */ + do_allow_no_sni, /* 15 */ + ttl_of_fake_packet ? "fixed" : (do_auto_ttl ? "auto" : "disabled"), /* 16 */ ttl_of_fake_packet, do_auto_ttl ? auto_ttl_1 : 0, do_auto_ttl ? auto_ttl_2 : 0, do_auto_ttl ? auto_ttl_max : 0, ttl_min_nhops, - do_wrong_chksum, /* 16 */ - do_wrong_seq /* 17 */ + do_wrong_chksum, /* 17 */ + do_wrong_seq /* 18 */ ); if (do_fragment_http && http_fragment_size > 2 && !do_native_frag) { @@ -1083,11 +1092,17 @@ int main(int argc, char *argv[]) { if ((packet_dataLen == 2 && memcmp(packet_data, "\x16\x03", 2) == 0) || (packet_dataLen >= 3 && memcmp(packet_data, "\x16\x03\x01", 3) == 0)) { - if (do_blacklist - ? (extract_sni(packet_data, packet_dataLen, - &host_addr, &host_len) && - blackwhitelist_check_hostname(host_addr, host_len)) - : 1) + if (do_blacklist) { + sni_ok = extract_sni(packet_data, packet_dataLen, + &host_addr, &host_len); + } + if ( + (do_blacklist && sni_ok && + blackwhitelist_check_hostname(host_addr, host_len) + ) || + (do_blacklist && !sni_ok && do_allow_no_sni) || + (!do_blacklist) + ) { #ifdef DEBUG char lsni[HOST_MAXLEN + 1] = {0};