diff --git a/binaries/aarch64/nfqws b/binaries/aarch64/nfqws index 0864aaf..c8bbf63 100755 Binary files a/binaries/aarch64/nfqws and b/binaries/aarch64/nfqws differ diff --git a/binaries/arm/nfqws b/binaries/arm/nfqws index f0f354d..cdbd25a 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 d326f5e..bf8b96f 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 a00f04c..6fc7030 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 60a5e33..d3180ec 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 d0ada4c..c981de0 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 689093b..7c4aae0 100755 Binary files a/binaries/ppc/nfqws and b/binaries/ppc/nfqws differ diff --git a/binaries/x86/nfqws b/binaries/x86/nfqws index 880ad15..abfffc5 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 ad0522d..d5ecddf 100755 Binary files a/binaries/x86_64/nfqws and b/binaries/x86_64/nfqws differ diff --git a/nfq/darkmagic.c b/nfq/darkmagic.c index 425cc5c..114178a 100644 --- a/nfq/darkmagic.c +++ b/nfq/darkmagic.c @@ -294,15 +294,23 @@ bool prepare_tcp_segment( } +// padlen<0 means payload shrinking bool prepare_udp_segment4( const struct sockaddr_in *src, const struct sockaddr_in *dst, uint8_t ttl, uint8_t fooling, - uint16_t padlen, + int padlen, const void *data, uint16_t len, uint8_t *buf, size_t *buflen) { - uint16_t datalen = len + padlen; + if ((len+padlen)<=0) padlen=-(int)len+1; // do not allow payload to be less that 1 byte + if ((len+padlen)>0xFFFF) padlen=0xFFFF-len; // do not allow payload size to exceed u16 range + if (padlen<0) + { + len+=padlen; + padlen=0; + } + uint16_t datalen = (uint16_t)(len + padlen); uint16_t ip_payload_len = sizeof(struct udphdr) + datalen; uint16_t pktlen = sizeof(struct ip) + ip_payload_len; if (pktlen>*buflen) return false; @@ -327,11 +335,18 @@ bool prepare_udp_segment6( const struct sockaddr_in6 *src, const struct sockaddr_in6 *dst, uint8_t ttl, uint8_t fooling, - uint16_t padlen, + int padlen, const void *data, uint16_t len, uint8_t *buf, size_t *buflen) { - uint16_t datalen = len + padlen; + if ((len+padlen)<=0) padlen=-(int)len+1; // do not allow payload to be less that 1 byte + if ((len+padlen)>0xFFFF) padlen=0xFFFF-len; // do not allow payload size to exceed u16 range + if (padlen<0) + { + len+=padlen; + padlen=0; + } + uint16_t datalen = (uint16_t)(len + padlen); uint16_t transport_payload_len = sizeof(struct udphdr) + datalen; uint16_t ip_payload_len = transport_payload_len + 8*!!((fooling & (FOOL_HOPBYHOP|FOOL_HOPBYHOP2))==FOOL_HOPBYHOP) + @@ -404,7 +419,7 @@ bool prepare_udp_segment( const struct sockaddr *src, const struct sockaddr *dst, uint8_t ttl, uint8_t fooling, - uint16_t padlen, + int padlen, const void *data, uint16_t len, uint8_t *buf, size_t *buflen) { diff --git a/nfq/darkmagic.h b/nfq/darkmagic.h index 90f60d0..6a46cb7 100644 --- a/nfq/darkmagic.h +++ b/nfq/darkmagic.h @@ -73,21 +73,21 @@ bool prepare_udp_segment4( const struct sockaddr_in *src, const struct sockaddr_in *dst, uint8_t ttl, uint8_t fooling, - uint16_t padlen, + int padlen, const void *data, uint16_t len, uint8_t *buf, size_t *buflen); bool prepare_udp_segment6( const struct sockaddr_in6 *src, const struct sockaddr_in6 *dst, uint8_t ttl, uint8_t fooling, - uint16_t padlen, + int padlen, const void *data, uint16_t len, uint8_t *buf, size_t *buflen); bool prepare_udp_segment( const struct sockaddr *src, const struct sockaddr *dst, uint8_t ttl, uint8_t fooling, - uint16_t padlen, + int padlen, const void *data, uint16_t len, uint8_t *buf, size_t *buflen); diff --git a/nfq/desync.c b/nfq/desync.c index a580647..9c5049f 100644 --- a/nfq/desync.c +++ b/nfq/desync.c @@ -831,8 +831,11 @@ packet_process_result dpi_desync_udp_packet(uint32_t fwmark, const char *ifout, case DESYNC_UDPLEN: pkt1_len = sizeof(pkt1); if (!prepare_udp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, ttl_orig,fooling_orig, params.udplen_increment, data_payload, len_payload, pkt1, &pkt1_len)) + { + DLOG("could not construct packet with modified length. too large ?\n"); return res; - DLOG("resending original packet with increased by %u length\n", params.udplen_increment); + } + DLOG("resending original packet with increased by %d length\n", params.udplen_increment); if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len)) return res; return drop; diff --git a/nfq/nfqws.c b/nfq/nfqws.c index 9e155d9..8bd6536 100644 --- a/nfq/nfqws.c +++ b/nfq/nfqws.c @@ -545,7 +545,7 @@ static void exithelp() " --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-unknown-udp= ; file containing unknown udp protocol fake payload\n" - " --dpi-desync-udplen-increment=\t; increase udp packet length by N bytes (default %u)\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" " --hostlist=\t\t\t; apply dpi desync only to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)\n" " --hostlist-exclude=\t\t; do not apply dpi desync to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)\n", @@ -1004,7 +1004,11 @@ int main(int argc, char **argv) load_file_or_exit(optarg,params.fake_unknown_udp,¶ms.fake_unknown_udp_size); break; case 33: /* dpi-desync-udplen-increment */ - params.udplen_increment = (uint16_t)atoi(optarg); + 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 */ if (!parse_cutoff(optarg, ¶ms.desync_cutoff, ¶ms.desync_cutoff_mode)) diff --git a/nfq/params.h b/nfq/params.h index c9ecc95..abf6042 100644 --- a/nfq/params.h +++ b/nfq/params.h @@ -52,7 +52,7 @@ struct params_s 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; - uint16_t udplen_increment; + int udplen_increment; bool droproot; uid_t uid; gid_t gid; diff --git a/nfq/strpool.c b/nfq/strpool.c index 6a219e0..183b17f 100644 --- a/nfq/strpool.c +++ b/nfq/strpool.c @@ -99,7 +99,7 @@ static void strlist_entry_destroy(struct str_list *entry) void strlist_destroy(struct str_list_head *head) { struct str_list *entry; - while (entry = LIST_FIRST(head)) + while ((entry = LIST_FIRST(head))) { LIST_REMOVE(entry, next); strlist_entry_destroy(entry); diff --git a/tpws/strpool.c b/tpws/strpool.c index 6a219e0..183b17f 100644 --- a/tpws/strpool.c +++ b/tpws/strpool.c @@ -99,7 +99,7 @@ static void strlist_entry_destroy(struct str_list *entry) void strlist_destroy(struct str_list_head *head) { struct str_list *entry; - while (entry = LIST_FIRST(head)) + while ((entry = LIST_FIRST(head))) { LIST_REMOVE(entry, next); strlist_entry_destroy(entry);