diff --git a/binaries/aarch64/nfqws b/binaries/aarch64/nfqws index 129067a..4775f42 100755 Binary files a/binaries/aarch64/nfqws and b/binaries/aarch64/nfqws differ diff --git a/binaries/arm/nfqws b/binaries/arm/nfqws index bdd05c5..f1a7254 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 f67f53c..1a0009f 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 8adb811..c860312 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 d27fe18..d52dc21 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 e057bec..e932e4e 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 f4ac1ea..f476aeb 100755 Binary files a/binaries/ppc/nfqws and b/binaries/ppc/nfqws differ diff --git a/binaries/x86/nfqws b/binaries/x86/nfqws index 57b2801..772075e 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 3c85c5d..6f97d6a 100755 Binary files a/binaries/x86_64/nfqws and b/binaries/x86_64/nfqws differ diff --git a/docs/readme.eng.md b/docs/readme.eng.md index 3455dcd..d2736ad 100644 --- a/docs/readme.eng.md +++ b/docs/readme.eng.md @@ -192,6 +192,7 @@ nfqws takes the following parameters: --dpi-desync-fake-unknown-udp=|0xHEX ; file containing unknown udp protocol fake payload --dpi-desync-udplen-increment= ; increase or decrease udp packet length by N bytes (default 2). negative values decrease length. --dpi-desync-udplen-pattern=|0xHEX ; udp tail fill pattern + --dpi-desync-start=[n|d|s]N ; apply dpi desync only to packet numbers (n, default), data packet numbers (d), relative sequence (s) greater or equal than N --dpi-desync-cutoff=[n|d|s]N ; apply dpi desync only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N --hostlist= ; apply dpi desync only to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed) --hostlist-exclude= ; do not apply dpi desync to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed) diff --git a/docs/readme.txt b/docs/readme.txt index 5fb00e8..0369bb6 100644 --- a/docs/readme.txt +++ b/docs/readme.txt @@ -262,6 +262,7 @@ nfqws --dpi-desync-fake-unknown-udp=|0xHEX ; файл, содержащий фейковый пейлоад неизвестного udp протокола для dpi-desync=fake, на замену стандартным нулям 64 байт --dpi-desync-udplen-increment= ; насколько увеличивать длину udp пейлоада в режиме udplen --dpi-desync-udplen-pattern=|0xHEX ; чем добивать udp пакет в режиме udplen. по умолчанию - нули + --dpi-desync-start=[n|d|s]N ; применять dpi desync только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру больше или равно N --dpi-desync-cutoff=[n|d|s]N ; применять dpi desync только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N --hostlist= ; применять дурение только к хостам из листа. может быть множество листов, они обьединяются. пустой обший лист = его отсутствие --hostlist-exclude= ; не применять дурение к хостам из листа. может быть множество листов, они обьединяются diff --git a/nfq/desync.c b/nfq/desync.c index d6cd539..e32d38e 100644 --- a/nfq/desync.c +++ b/nfq/desync.c @@ -116,7 +116,7 @@ static bool rawsend_rep(const struct sockaddr* dst,uint32_t fwmark,const char *i } -static uint64_t cutoff_get_limit(t_ctrack *ctrack, char mode) +static uint64_t cutoff_get_limit(const t_ctrack *ctrack, char mode) { switch(mode) { @@ -126,7 +126,7 @@ static uint64_t cutoff_get_limit(t_ctrack *ctrack, char mode) default: return 0; } } -static bool cutoff_test(t_ctrack *ctrack, uint64_t cutoff, char mode) +static bool cutoff_test(const t_ctrack *ctrack, uint64_t cutoff, char mode) { return cutoff && cutoff_get_limit(ctrack, mode)>=cutoff; } @@ -361,6 +361,45 @@ static uint8_t ct_new_postnat_fix_udp(const t_ctrack *ctrack, struct ip *ip, str } +static bool check_desync_interval(const t_ctrack *ctrack) +{ + if (params.desync_start) + { + if (ctrack) + { + if (!cutoff_test(ctrack, params.desync_start, params.desync_start_mode)) + { + DLOG("desync-start not reached (mode %c): %llu/%u . not desyncing\n", params.desync_start_mode, (unsigned long long)cutoff_get_limit(ctrack,params.desync_start_mode), params.desync_start); + return false; + } + DLOG("desync-start reached (mode %c): %llu/%u\n", params.desync_start_mode, (unsigned long long)cutoff_get_limit(ctrack,params.desync_start_mode), params.desync_start); + } + else + { + DLOG("not desyncing. desync-start is set but conntrack entry is missing\n"); + return false; + } + } + if (params.desync_cutoff) + { + if (ctrack) + { + if (ctrack->b_desync_cutoff) + { + DLOG("desync-cutoff reached (mode %c): %llu/%u . not desyncing\n", params.desync_cutoff_mode, (unsigned long long)cutoff_get_limit(ctrack,params.desync_cutoff_mode), params.desync_cutoff); + return false; + } + DLOG("desync-cutoff not reached (mode %c): %llu/%u\n", params.desync_cutoff_mode, (unsigned long long)cutoff_get_limit(ctrack,params.desync_cutoff_mode), params.desync_cutoff); + } + else + { + DLOG("not desyncing. desync-cutoff is set but conntrack entry is missing\n"); + return false; + } + } + return true; +} + // result : true - drop original packet, false = dont drop uint8_t dpi_desync_tcp_packet(uint32_t fwmark, const char *ifout, uint8_t *data_pkt, size_t *len_pkt, struct ip *ip, struct ip6_hdr *ip6hdr, struct tcphdr *tcphdr, size_t len_tcp, uint8_t *data_payload, size_t len_payload) @@ -526,26 +565,11 @@ uint8_t dpi_desync_tcp_packet(uint32_t fwmark, const char *ifout, uint8_t *data_ return res; } - if (params.desync_cutoff) - { - if (ctrack) - { - if (ctrack->b_desync_cutoff) - { - DLOG("not desyncing. desync-cutoff reached (mode %c): %llu/%u\n", params.desync_cutoff_mode, (unsigned long long)cutoff_get_limit(ctrack,params.desync_cutoff_mode), params.desync_cutoff); - return res; - } - DLOG("desync-cutoff not reached (mode %c): %llu/%u\n", params.desync_cutoff_mode, (unsigned long long)cutoff_get_limit(ctrack,params.desync_cutoff_mode), params.desync_cutoff); - } - else - { - DLOG("not desyncing. desync-cutoff is set but conntrack entry is missing\n"); - return res; - } - } - if (!params.wssize && params.desync_mode==DESYNC_NONE && !params.hostcase && !params.hostnospace && !params.domcase && !*params.hostlist_auto_filename) return res; // nothing to do. do not waste cpu + // start and cutoff limiters + if (!check_desync_interval(ctrack)) return res; + if (!(tcphdr->th_flags & TH_SYN) && len_payload) { const uint8_t *fake; @@ -990,27 +1014,12 @@ uint8_t dpi_desync_udp_packet(uint32_t fwmark, const char *ifout, uint8_t *data_ //ConntrackPoolDump(¶ms.conntrack); if (bReverse) return res; // nothing to do. do not waste cpu - - if (params.desync_cutoff) - { - if (ctrack) - { - if (ctrack->b_desync_cutoff) - { - DLOG("not desyncing. desync-cutoff reached (mode %c): %llu/%u\n", params.desync_cutoff_mode, (unsigned long long)cutoff_get_limit(ctrack,params.desync_cutoff_mode), params.desync_cutoff); - return res; - } - DLOG("desync-cutoff not reached (mode %c): %llu/%u\n", params.desync_cutoff_mode, (unsigned long long)cutoff_get_limit(ctrack,params.desync_cutoff_mode), params.desync_cutoff); - } - else - { - DLOG("not desyncing. desync-cutoff is set but conntrack entry is missing\n"); - return res; - } - } if (params.desync_mode==DESYNC_NONE && !*params.hostlist_auto_filename) return res; // do not waste cpu + // start and cutoff limiters + if (!check_desync_interval(ctrack)) return res; + if (len_payload) { const uint8_t *fake; diff --git a/nfq/nfqws.c b/nfq/nfqws.c index 3a90ffb..4037d67 100644 --- a/nfq/nfqws.c +++ b/nfq/nfqws.c @@ -565,6 +565,7 @@ static void exithelp(void) " --dpi-desync-fake-unknown-udp=|0xHEX\t; file containing unknown udp protocol fake payload\n" " --dpi-desync-udplen-increment=\t\t; increase or decrease udp packet length by N bytes (default %u). negative values decrease length.\n" " --dpi-desync-udplen-pattern=|0xHEX\t; udp tail fill pattern\n" + " --dpi-desync-start=[n|d|s]N\t\t\t; apply dpi desync only to packet numbers (n, default), data packet numbers (d), relative sequence (s) greater or equal than N\n" " --dpi-desync-cutoff=[n|d|s]N\t\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\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\t; do not apply dpi desync to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)\n" @@ -712,7 +713,7 @@ int main(int argc, char **argv) params.desync_ttl6 = 0xFF; // unused params.desync_badseq_increment = BADSEQ_INCREMENT_DEFAULT; params.desync_badseq_ack_increment = BADSEQ_ACK_INCREMENT_DEFAULT; - params.wssize_cutoff_mode = params.desync_cutoff_mode = 'n'; // packet number by default + params.wssize_cutoff_mode = params.desync_start_mode = params.desync_cutoff_mode = 'n'; // packet number by default params.udplen_increment = UDPLEN_INCREMENT_DEFAULT; params.hostlist_auto_fail_threshold = HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT; params.hostlist_auto_fail_time = HOSTLIST_AUTO_FAIL_TIME_DEFAULT; @@ -781,17 +782,18 @@ int main(int argc, char **argv) {"dpi-desync-udplen-increment",required_argument,0,0},// optidx=38 {"dpi-desync-udplen-pattern",required_argument,0,0},// optidx=39 {"dpi-desync-cutoff",required_argument,0,0},// optidx=40 - {"hostlist",required_argument,0,0}, // optidx=41 - {"hostlist-exclude",required_argument,0,0}, // optidx=42 - {"hostlist-auto",required_argument,0,0}, // optidx=43 - {"hostlist-auto-fail-threshold",required_argument,0,0}, // optidx=44 - {"hostlist-auto-fail-time",required_argument,0,0}, // optidx=45 - {"hostlist-auto-retrans-threshold",required_argument,0,0}, // optidx=46 - {"hostlist-auto-debug",required_argument,0,0}, // optidx=47 + {"dpi-desync-start",required_argument,0,0},// optidx=41 + {"hostlist",required_argument,0,0}, // optidx=42 + {"hostlist-exclude",required_argument,0,0}, // optidx=43 + {"hostlist-auto",required_argument,0,0}, // optidx=44 + {"hostlist-auto-fail-threshold",required_argument,0,0}, // optidx=45 + {"hostlist-auto-fail-time",required_argument,0,0}, // optidx=46 + {"hostlist-auto-retrans-threshold",required_argument,0,0}, // optidx=47 + {"hostlist-auto-debug",required_argument,0,0}, // optidx=48 #ifdef __linux__ - {"bind-fix4",no_argument,0,0}, // optidx=48 - {"bind-fix6",no_argument,0,0}, // optidx=49 + {"bind-fix4",no_argument,0,0}, // optidx=49 + {"bind-fix6",no_argument,0,0}, // optidx=50 #endif {NULL,0,NULL,0} }; @@ -1127,21 +1129,28 @@ int main(int argc, char **argv) exit_clean(1); } break; - case 41: /* hostlist */ + case 41: /* desync-start */ + if (!parse_cutoff(optarg, ¶ms.desync_start, ¶ms.desync_start_mode)) + { + fprintf(stderr, "invalid desync-start value\n"); + exit_clean(1); + } + break; + case 42: /* hostlist */ if (!strlist_add(¶ms.hostlist_files, optarg)) { fprintf(stderr, "strlist_add failed\n"); exit_clean(1); } break; - case 42: /* hostlist-exclude */ + case 43: /* hostlist-exclude */ if (!strlist_add(¶ms.hostlist_exclude_files, optarg)) { fprintf(stderr, "strlist_add failed\n"); exit_clean(1); } break; - case 43: /* hostlist-auto */ + case 44: /* hostlist-auto */ if (*params.hostlist_auto_filename) { fprintf(stderr, "only one auto hostlist is supported\n"); @@ -1172,7 +1181,7 @@ int main(int argc, char **argv) strncpy(params.hostlist_auto_filename, optarg, sizeof(params.hostlist_auto_filename)); params.hostlist_auto_filename[sizeof(params.hostlist_auto_filename) - 1] = '\0'; break; - case 44: /* hostlist-auto-fail-threshold */ + case 45: /* hostlist-auto-fail-threshold */ params.hostlist_auto_fail_threshold = (uint8_t)atoi(optarg); if (params.hostlist_auto_fail_threshold<1 || params.hostlist_auto_fail_threshold>20) { @@ -1180,7 +1189,7 @@ int main(int argc, char **argv) exit_clean(1); } break; - case 45: /* hostlist-auto-fail-time */ + case 46: /* hostlist-auto-fail-time */ params.hostlist_auto_fail_time = (uint8_t)atoi(optarg); if (params.hostlist_auto_fail_time<1) { @@ -1188,7 +1197,7 @@ int main(int argc, char **argv) exit_clean(1); } break; - case 46: /* hostlist-auto-retrans-threshold */ + case 47: /* hostlist-auto-retrans-threshold */ params.hostlist_auto_retrans_threshold = (uint8_t)atoi(optarg); if (params.hostlist_auto_retrans_threshold<2 || params.hostlist_auto_retrans_threshold>10) { @@ -1196,7 +1205,7 @@ int main(int argc, char **argv) exit_clean(1); } break; - case 47: /* hostlist-auto-debug */ + case 48: /* hostlist-auto-debug */ { FILE *F = fopen(optarg,"a+t"); if (!F) @@ -1212,10 +1221,10 @@ int main(int argc, char **argv) } break; #ifdef __linux__ - case 48: /* bind-fix4 */ + case 49: /* bind-fix4 */ params.bind_fix4 = true; break; - case 49: /* bind-fix6 */ + case 50: /* bind-fix6 */ params.bind_fix6 = true; break; #endif diff --git a/nfq/params.h b/nfq/params.h index 026e8bb..458957b 100644 --- a/nfq/params.h +++ b/nfq/params.h @@ -50,8 +50,8 @@ struct params_s enum dpi_desync_mode desync_mode0,desync_mode,desync_mode2; bool desync_retrans,desync_skip_nosni,desync_any_proto; unsigned int desync_repeats,desync_split_pos,desync_ipfrag_pos_tcp,desync_ipfrag_pos_udp; - char desync_cutoff_mode; // n - packets, d - data packets, s - relative sequence - unsigned int desync_cutoff; + char desync_start_mode, desync_cutoff_mode; // n - packets, d - data packets, s - relative sequence + unsigned int desync_start, desync_cutoff; uint8_t desync_ttl, desync_ttl6; autottl desync_autottl, desync_autottl6; uint32_t desync_fooling_mode;