diff --git a/binaries/aarch64/nfqws b/binaries/aarch64/nfqws index ff96992..09cfb98 100755 Binary files a/binaries/aarch64/nfqws and b/binaries/aarch64/nfqws differ diff --git a/binaries/arm/nfqws b/binaries/arm/nfqws index b07a67f..108cf31 100755 Binary files a/binaries/arm/nfqws and b/binaries/arm/nfqws differ diff --git a/binaries/freebsd-x64/dvtws b/binaries/freebsd-x64/dvtws index bf8b96f..e1e9939 100755 Binary files a/binaries/freebsd-x64/dvtws and b/binaries/freebsd-x64/dvtws differ diff --git a/binaries/mips32r1-lsb/nfqws b/binaries/mips32r1-lsb/nfqws index 1be2cdc..166bef0 100755 Binary files a/binaries/mips32r1-lsb/nfqws and b/binaries/mips32r1-lsb/nfqws differ diff --git a/binaries/mips32r1-msb/nfqws b/binaries/mips32r1-msb/nfqws index ce16612..9385ced 100755 Binary files a/binaries/mips32r1-msb/nfqws and b/binaries/mips32r1-msb/nfqws differ diff --git a/binaries/mips64r2-msb/nfqws b/binaries/mips64r2-msb/nfqws index f6d589d..ca5cad2 100755 Binary files a/binaries/mips64r2-msb/nfqws and b/binaries/mips64r2-msb/nfqws differ diff --git a/binaries/ppc/nfqws b/binaries/ppc/nfqws index 09ce807..d3fb237 100755 Binary files a/binaries/ppc/nfqws and b/binaries/ppc/nfqws differ diff --git a/binaries/x86/nfqws b/binaries/x86/nfqws index 5ac0630..14729f0 100755 Binary files a/binaries/x86/nfqws and b/binaries/x86/nfqws differ diff --git a/binaries/x86_64/nfqws b/binaries/x86_64/nfqws index 229de62..22610ae 100755 Binary files a/binaries/x86_64/nfqws and b/binaries/x86_64/nfqws differ diff --git a/nfq/desync.c b/nfq/desync.c index 9c5049f..ff9db68 100644 --- a/nfq/desync.c +++ b/nfq/desync.c @@ -727,6 +727,13 @@ packet_process_result dpi_desync_udp_packet(uint32_t fwmark, const char *ifout, } bKnownProtocol = true; } + else if (IsWireguardHandshakeInitiation(data_payload,len_payload)) + { + DLOG("packet contains wireguard handshake initiation\n") + fake = params.fake_wg; + fake_size = params.fake_wg_size; + bKnownProtocol = true; + } else { if (!params.desync_any_proto) return res; diff --git a/nfq/nfqws.c b/nfq/nfqws.c index 8623fb0..a65104b 100644 --- a/nfq/nfqws.c +++ b/nfq/nfqws.c @@ -546,6 +546,7 @@ static void exithelp() " --dpi-desync-fake-tls=\t; file containing fake TLS ClientHello (for https)\n" " --dpi-desync-fake-unknown=\t; file containing unknown protocol fake payload\n" " --dpi-desync-fake-quic=\t; file containing fake QUIC Initial\n" + " --dpi-desync-fake-wireguard=\t; file containing fake wireguard handshake initiation\n" " --dpi-desync-fake-unknown-udp= ; file containing unknown udp protocol fake payload\n" " --dpi-desync-udplen-increment=\t; increase or decrease udp packet length by N bytes (default %u). negative values decrease length.\n" " --dpi-desync-cutoff=[n|d|s]N\t\t; apply dpi desync only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N\n" @@ -645,6 +646,7 @@ int main(int argc, char **argv) memcpy(params.fake_http,fake_http_request_default,params.fake_http_size); params.fake_quic_size = 620; // must be 601+ for TSPU hack params.fake_quic[0] = 0x40; // russian TSPU QUIC short header fake + params.fake_wg_size = 64; params.fake_unknown_size = 256; params.fake_unknown_udp_size = 64; params.wscale=-1; // default - dont change scale factor (client) @@ -712,14 +714,15 @@ int main(int argc, char **argv) {"dpi-desync-fake-tls",required_argument,0,0},// optidx=29 {"dpi-desync-fake-unknown",required_argument,0,0},// optidx=30 {"dpi-desync-fake-quic",required_argument,0,0},// optidx=31 - {"dpi-desync-fake-unknown-udp",required_argument,0,0},// optidx=32 - {"dpi-desync-udplen-increment",required_argument,0,0},// optidx=33 - {"dpi-desync-cutoff",required_argument,0,0},// optidx=34 - {"hostlist",required_argument,0,0}, // optidx=35 - {"hostlist-exclude",required_argument,0,0}, // optidx=36 + {"dpi-desync-fake-wireguard",required_argument,0,0},// optidx=32 + {"dpi-desync-fake-unknown-udp",required_argument,0,0},// optidx=33 + {"dpi-desync-udplen-increment",required_argument,0,0},// optidx=34 + {"dpi-desync-cutoff",required_argument,0,0},// optidx=35 + {"hostlist",required_argument,0,0}, // optidx=36 + {"hostlist-exclude",required_argument,0,0}, // optidx=37 #ifdef __linux__ - {"bind-fix4",no_argument,0,0}, // optidx=37 - {"bind-fix6",no_argument,0,0}, // optidx=38 + {"bind-fix4",no_argument,0,0}, // optidx=38 + {"bind-fix6",no_argument,0,0}, // optidx=39 #endif {NULL,0,NULL,0} }; @@ -1001,32 +1004,36 @@ int main(int argc, char **argv) params.fake_quic_size = sizeof(params.fake_quic); load_file_or_exit(optarg,params.fake_quic,¶ms.fake_quic_size); break; - case 32: /* dpi-desync-fake-unknown-udp */ + case 32: /* dpi-desync-fake-wireguard */ + params.fake_wg_size = sizeof(params.fake_wg); + load_file_or_exit(optarg,params.fake_wg,¶ms.fake_wg_size); + break; + case 33: /* dpi-desync-fake-unknown-udp */ params.fake_unknown_udp_size = sizeof(params.fake_unknown_udp); load_file_or_exit(optarg,params.fake_unknown_udp,¶ms.fake_unknown_udp_size); break; - case 33: /* dpi-desync-udplen-increment */ + case 34: /* dpi-desync-udplen-increment */ if (sscanf(optarg,"%d",¶ms.udplen_increment)<1 || params.udplen_increment>0x7FFF || params.udplen_increment<-0x8000) { fprintf(stderr, "dpi-desync-udplen-increment must be integer within -32768..32767 range\n"); exit_clean(1); } break; - case 34: /* desync-cutoff */ + case 35: /* desync-cutoff */ if (!parse_cutoff(optarg, ¶ms.desync_cutoff, ¶ms.desync_cutoff_mode)) { fprintf(stderr, "invalid desync-cutoff value\n"); exit_clean(1); } break; - case 35: /* hostlist */ + case 36: /* hostlist */ if (!strlist_add(¶ms.hostlist_files, optarg)) { fprintf(stderr, "strlist_add failed\n"); exit_clean(1); } break; - case 36: /* hostlist-exclude */ + case 37: /* hostlist-exclude */ if (!strlist_add(¶ms.hostlist_exclude_files, optarg)) { fprintf(stderr, "strlist_add failed\n"); @@ -1034,10 +1041,10 @@ int main(int argc, char **argv) } break; #ifdef __linux__ - case 37: /* bind-fix4 */ + case 38: /* bind-fix4 */ params.bind_fix4 = true; break; - case 38: /* bind-fix6 */ + case 39: /* bind-fix6 */ params.bind_fix6 = true; break; #endif diff --git a/nfq/params.h b/nfq/params.h index abf6042..321d4cb 100644 --- a/nfq/params.h +++ b/nfq/params.h @@ -50,8 +50,8 @@ struct params_s uint8_t desync_fooling_mode; uint32_t desync_fwmark; // unused in BSD uint32_t desync_badseq_increment, desync_badseq_ack_increment; - uint8_t fake_http[1432],fake_tls[1432],fake_unknown[1432],fake_unknown_udp[1472],fake_quic[1472]; - size_t fake_http_size,fake_tls_size,fake_unknown_size,fake_unknown_udp_size,fake_quic_size; + uint8_t fake_http[1432],fake_tls[1432],fake_quic[1472],fake_wg[1472],fake_unknown[1432],fake_unknown_udp[1472]; + size_t fake_http_size,fake_tls_size,fake_quic_size,fake_wg_size,fake_unknown_size,fake_unknown_udp_size; int udplen_increment; bool droproot; uid_t uid; diff --git a/nfq/protocol.c b/nfq/protocol.c index 3a2a243..2782b37 100644 --- a/nfq/protocol.c +++ b/nfq/protocol.c @@ -188,6 +188,12 @@ bool TLSHelloExtractHostFromHandshake(const uint8_t *data, size_t len, char *hos } +bool IsWireguardHandshakeInitiation(const uint8_t *data, size_t len) +{ + return len==148 && data[0]==1 && data[1]==0 && data[2]==0 && data[3]==0; +} + + /* Returns the QUIC draft version or 0 if not applicable. */ uint8_t QUICDraftVersion(uint32_t version) { diff --git a/nfq/protocol.h b/nfq/protocol.h index 79f8574..0bb746a 100644 --- a/nfq/protocol.h +++ b/nfq/protocol.h @@ -15,6 +15,8 @@ bool TLSFindExtInHandshake(const uint8_t *data, size_t len, uint16_t type, const bool TLSHelloExtractHost(const uint8_t *data, size_t len, char *host, size_t len_host); bool TLSHelloExtractHostFromHandshake(const uint8_t *data, size_t len, char *host, size_t len_host); +bool IsWireguardHandshakeInitiation(const uint8_t *data, size_t len); + #define QUIC_MAX_CID_LENGTH 20 typedef struct quic_cid { uint8_t len;