nfqws: --dpi-desync-start

This commit is contained in:
bol-van 2024-04-13 11:13:11 +03:00
parent 18cf986fec
commit 9088d40940
14 changed files with 79 additions and 59 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -192,6 +192,7 @@ nfqws takes the following parameters:
--dpi-desync-fake-unknown-udp=<filename>|0xHEX ; file containing unknown udp protocol fake payload --dpi-desync-fake-unknown-udp=<filename>|0xHEX ; file containing unknown udp protocol fake payload
--dpi-desync-udplen-increment=<int> ; increase or decrease udp packet length by N bytes (default 2). negative values decrease length. --dpi-desync-udplen-increment=<int> ; increase or decrease udp packet length by N bytes (default 2). negative values decrease length.
--dpi-desync-udplen-pattern=<filename>|0xHEX ; udp tail fill pattern --dpi-desync-udplen-pattern=<filename>|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 --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=<filename> ; apply dpi desync only to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed) --hostlist=<filename> ; apply dpi desync only to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)
--hostlist-exclude=<filename> ; do not apply dpi desync to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed) --hostlist-exclude=<filename> ; do not apply dpi desync to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)

View File

@ -262,6 +262,7 @@ nfqws
--dpi-desync-fake-unknown-udp=<filename>|0xHEX ; файл, содержащий фейковый пейлоад неизвестного udp протокола для dpi-desync=fake, на замену стандартным нулям 64 байт --dpi-desync-fake-unknown-udp=<filename>|0xHEX ; файл, содержащий фейковый пейлоад неизвестного udp протокола для dpi-desync=fake, на замену стандартным нулям 64 байт
--dpi-desync-udplen-increment=<int> ; насколько увеличивать длину udp пейлоада в режиме udplen --dpi-desync-udplen-increment=<int> ; насколько увеличивать длину udp пейлоада в режиме udplen
--dpi-desync-udplen-pattern=<filename>|0xHEX ; чем добивать udp пакет в режиме udplen. по умолчанию - нули --dpi-desync-udplen-pattern=<filename>|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 --dpi-desync-cutoff=[n|d|s]N ; применять dpi desync только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N
--hostlist=<filename> ; применять дурение только к хостам из листа. может быть множество листов, они обьединяются. пустой обший лист = его отсутствие --hostlist=<filename> ; применять дурение только к хостам из листа. может быть множество листов, они обьединяются. пустой обший лист = его отсутствие
--hostlist-exclude=<filename> ; не применять дурение к хостам из листа. может быть множество листов, они обьединяются --hostlist-exclude=<filename> ; не применять дурение к хостам из листа. может быть множество листов, они обьединяются

View File

@ -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) switch(mode)
{ {
@ -126,7 +126,7 @@ static uint64_t cutoff_get_limit(t_ctrack *ctrack, char mode)
default: return 0; 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; 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 // 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) 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; 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 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) if (!(tcphdr->th_flags & TH_SYN) && len_payload)
{ {
const uint8_t *fake; const uint8_t *fake;
@ -991,26 +1015,11 @@ uint8_t dpi_desync_udp_packet(uint32_t fwmark, const char *ifout, uint8_t *data_
if (bReverse) return res; // nothing to do. do not waste cpu 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 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) if (len_payload)
{ {
const uint8_t *fake; const uint8_t *fake;

View File

@ -565,6 +565,7 @@ static void exithelp(void)
" --dpi-desync-fake-unknown-udp=<filename>|0xHEX\t; file containing unknown udp protocol fake payload\n" " --dpi-desync-fake-unknown-udp=<filename>|0xHEX\t; file containing unknown udp protocol fake payload\n"
" --dpi-desync-udplen-increment=<int>\t\t; increase or decrease udp packet length by N bytes (default %u). negative values decrease length.\n" " --dpi-desync-udplen-increment=<int>\t\t; increase or decrease udp packet length by N bytes (default %u). negative values decrease length.\n"
" --dpi-desync-udplen-pattern=<filename>|0xHEX\t; udp tail fill pattern\n" " --dpi-desync-udplen-pattern=<filename>|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" " --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=<filename>\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=<filename>\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=<filename>\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" " --hostlist-exclude=<filename>\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_ttl6 = 0xFF; // unused
params.desync_badseq_increment = BADSEQ_INCREMENT_DEFAULT; params.desync_badseq_increment = BADSEQ_INCREMENT_DEFAULT;
params.desync_badseq_ack_increment = BADSEQ_ACK_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.udplen_increment = UDPLEN_INCREMENT_DEFAULT;
params.hostlist_auto_fail_threshold = HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT; params.hostlist_auto_fail_threshold = HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT;
params.hostlist_auto_fail_time = HOSTLIST_AUTO_FAIL_TIME_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-increment",required_argument,0,0},// optidx=38
{"dpi-desync-udplen-pattern",required_argument,0,0},// optidx=39 {"dpi-desync-udplen-pattern",required_argument,0,0},// optidx=39
{"dpi-desync-cutoff",required_argument,0,0},// optidx=40 {"dpi-desync-cutoff",required_argument,0,0},// optidx=40
{"hostlist",required_argument,0,0}, // optidx=41 {"dpi-desync-start",required_argument,0,0},// optidx=41
{"hostlist-exclude",required_argument,0,0}, // optidx=42 {"hostlist",required_argument,0,0}, // optidx=42
{"hostlist-auto",required_argument,0,0}, // optidx=43 {"hostlist-exclude",required_argument,0,0}, // optidx=43
{"hostlist-auto-fail-threshold",required_argument,0,0}, // optidx=44 {"hostlist-auto",required_argument,0,0}, // optidx=44
{"hostlist-auto-fail-time",required_argument,0,0}, // optidx=45 {"hostlist-auto-fail-threshold",required_argument,0,0}, // optidx=45
{"hostlist-auto-retrans-threshold",required_argument,0,0}, // optidx=46 {"hostlist-auto-fail-time",required_argument,0,0}, // optidx=46
{"hostlist-auto-debug",required_argument,0,0}, // optidx=47 {"hostlist-auto-retrans-threshold",required_argument,0,0}, // optidx=47
{"hostlist-auto-debug",required_argument,0,0}, // optidx=48
#ifdef __linux__ #ifdef __linux__
{"bind-fix4",no_argument,0,0}, // optidx=48 {"bind-fix4",no_argument,0,0}, // optidx=49
{"bind-fix6",no_argument,0,0}, // optidx=49 {"bind-fix6",no_argument,0,0}, // optidx=50
#endif #endif
{NULL,0,NULL,0} {NULL,0,NULL,0}
}; };
@ -1127,21 +1129,28 @@ int main(int argc, char **argv)
exit_clean(1); exit_clean(1);
} }
break; break;
case 41: /* hostlist */ case 41: /* desync-start */
if (!parse_cutoff(optarg, &params.desync_start, &params.desync_start_mode))
{
fprintf(stderr, "invalid desync-start value\n");
exit_clean(1);
}
break;
case 42: /* hostlist */
if (!strlist_add(&params.hostlist_files, optarg)) if (!strlist_add(&params.hostlist_files, optarg))
{ {
fprintf(stderr, "strlist_add failed\n"); fprintf(stderr, "strlist_add failed\n");
exit_clean(1); exit_clean(1);
} }
break; break;
case 42: /* hostlist-exclude */ case 43: /* hostlist-exclude */
if (!strlist_add(&params.hostlist_exclude_files, optarg)) if (!strlist_add(&params.hostlist_exclude_files, optarg))
{ {
fprintf(stderr, "strlist_add failed\n"); fprintf(stderr, "strlist_add failed\n");
exit_clean(1); exit_clean(1);
} }
break; break;
case 43: /* hostlist-auto */ case 44: /* hostlist-auto */
if (*params.hostlist_auto_filename) if (*params.hostlist_auto_filename)
{ {
fprintf(stderr, "only one auto hostlist is supported\n"); 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)); strncpy(params.hostlist_auto_filename, optarg, sizeof(params.hostlist_auto_filename));
params.hostlist_auto_filename[sizeof(params.hostlist_auto_filename) - 1] = '\0'; params.hostlist_auto_filename[sizeof(params.hostlist_auto_filename) - 1] = '\0';
break; break;
case 44: /* hostlist-auto-fail-threshold */ case 45: /* hostlist-auto-fail-threshold */
params.hostlist_auto_fail_threshold = (uint8_t)atoi(optarg); params.hostlist_auto_fail_threshold = (uint8_t)atoi(optarg);
if (params.hostlist_auto_fail_threshold<1 || params.hostlist_auto_fail_threshold>20) 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); exit_clean(1);
} }
break; break;
case 45: /* hostlist-auto-fail-time */ case 46: /* hostlist-auto-fail-time */
params.hostlist_auto_fail_time = (uint8_t)atoi(optarg); params.hostlist_auto_fail_time = (uint8_t)atoi(optarg);
if (params.hostlist_auto_fail_time<1) if (params.hostlist_auto_fail_time<1)
{ {
@ -1188,7 +1197,7 @@ int main(int argc, char **argv)
exit_clean(1); exit_clean(1);
} }
break; break;
case 46: /* hostlist-auto-retrans-threshold */ case 47: /* hostlist-auto-retrans-threshold */
params.hostlist_auto_retrans_threshold = (uint8_t)atoi(optarg); params.hostlist_auto_retrans_threshold = (uint8_t)atoi(optarg);
if (params.hostlist_auto_retrans_threshold<2 || params.hostlist_auto_retrans_threshold>10) 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); exit_clean(1);
} }
break; break;
case 47: /* hostlist-auto-debug */ case 48: /* hostlist-auto-debug */
{ {
FILE *F = fopen(optarg,"a+t"); FILE *F = fopen(optarg,"a+t");
if (!F) if (!F)
@ -1212,10 +1221,10 @@ int main(int argc, char **argv)
} }
break; break;
#ifdef __linux__ #ifdef __linux__
case 48: /* bind-fix4 */ case 49: /* bind-fix4 */
params.bind_fix4 = true; params.bind_fix4 = true;
break; break;
case 49: /* bind-fix6 */ case 50: /* bind-fix6 */
params.bind_fix6 = true; params.bind_fix6 = true;
break; break;
#endif #endif

View File

@ -50,8 +50,8 @@ struct params_s
enum dpi_desync_mode desync_mode0,desync_mode,desync_mode2; enum dpi_desync_mode desync_mode0,desync_mode,desync_mode2;
bool desync_retrans,desync_skip_nosni,desync_any_proto; bool desync_retrans,desync_skip_nosni,desync_any_proto;
unsigned int desync_repeats,desync_split_pos,desync_ipfrag_pos_tcp,desync_ipfrag_pos_udp; 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 char desync_start_mode, desync_cutoff_mode; // n - packets, d - data packets, s - relative sequence
unsigned int desync_cutoff; unsigned int desync_start, desync_cutoff;
uint8_t desync_ttl, desync_ttl6; uint8_t desync_ttl, desync_ttl6;
autottl desync_autottl, desync_autottl6; autottl desync_autottl, desync_autottl6;
uint32_t desync_fooling_mode; uint32_t desync_fooling_mode;