From c467e696e3115a451627f2a291757a62472a5dcd Mon Sep 17 00:00:00 2001 From: bol-van Date: Tue, 23 Sep 2025 14:06:23 +0300 Subject: [PATCH] nfqws: --dpi-desync-fakedsplit-mod=altorder --- docs/changes.txt | 1 + nfq/desync.c | 45 ++++++++++++++++++++++++---------------- nfq/nfqws.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++- nfq/params.h | 6 +++++- 4 files changed, 86 insertions(+), 20 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 825567bf..3ff128f6 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -548,5 +548,6 @@ winws: --wf-raw-part nfqws: --dpi-desync=hostfakesplit nfqws: --dpi-desync-fake-tcp-mod=seq nfqws: --dpi-desync-fake-tls=!+offset +nfqws: --dpi-desync-fakedsplit-mod=altorder blockcheck: new strategies blockcheck: curl test simulation : SIMULATE=1 diff --git a/nfq/desync.c b/nfq/desync.c index 06f62550..83a26c1f 100644 --- a/nfq/desync.c +++ b/nfq/desync.c @@ -2418,11 +2418,15 @@ send_orig_clean: dp->desync_fooling_mode,dp->desync_ts_increment,dp->desync_badseq_increment,dp->desync_badseq_ack_increment, pat, split_pos, fakeseg, &fakeseg_len)) goto send_orig; - ip_id=IP4_IP_ID_NEXT(ip_id); - DLOG("sending fake(1) 1st tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos); - hexdump_limited_dlog(pat,split_pos,PKTDATA_MAXDUMP); DLOG("\n"); - if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, fakeseg_len)) - goto send_orig; + + if (dp->fs_mod.ordering==0) + { + ip_id=IP4_IP_ID_NEXT(ip_id); + DLOG("sending fake(1) 1st tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos); + hexdump_limited_dlog(pat,split_pos,PKTDATA_MAXDUMP); DLOG("\n"); + if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, fakeseg_len)) + goto send_orig; + } unsigned int seqovl = reasm_offset ? 0 : seqovl_pos; #ifdef __linux__ @@ -2435,7 +2439,7 @@ send_orig_clean: seg_len = split_pos+seqovl; if (seg_len>sizeof(ovlseg)) { - DLOG("seqovl is too large"); + DLOG("seqovl is too large\n"); goto send_orig; } fill_pattern(ovlseg,seqovl,dp->seqovl_pattern,sizeof(dp->seqovl_pattern)); @@ -2472,12 +2476,15 @@ send_orig_clean: break; } #endif - if (dis->ip) ((struct ip*)fakeseg)->ip_id = ip_id; - ip_id=IP4_IP_ID_NEXT(ip_id); - DLOG("sending fake(2) 1st tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos); - hexdump_limited_dlog(pat,split_pos,PKTDATA_MAXDUMP); DLOG("\n"); - if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, fakeseg_len)) - goto send_orig; + if (dp->fs_mod.ordering<=1) + { + if (dis->ip) ((struct ip*)fakeseg)->ip_id = ip_id; + ip_id=IP4_IP_ID_NEXT(ip_id); + DLOG("sending fake(2) 1st tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos); + hexdump_limited_dlog(pat,split_pos,PKTDATA_MAXDUMP); DLOG("\n"); + if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, fakeseg_len)) + goto send_orig; + } fakeseg_len = sizeof(fakeseg); if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, false, 0, net32_add(dis->tcp->th_seq,split_pos), dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps, @@ -2503,12 +2510,14 @@ send_orig_clean: if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len)) goto send_orig; - if (dis->ip) ((struct ip*)fakeseg)->ip_id = ip_id; - - DLOG("sending fake(2) 2nd tcp segment %zu-%zu len=%zu : ",split_pos,dis->len_payload-1, dis->len_payload-split_pos); - hexdump_limited_dlog(pat+split_pos,dis->len_payload-split_pos,PKTDATA_MAXDUMP); DLOG("\n"); - if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, fakeseg_len)) - goto send_orig; + if (dp->fs_mod.ordering<=2) + { + if (dis->ip) ((struct ip*)fakeseg)->ip_id = ip_id; + DLOG("sending fake(2) 2nd tcp segment %zu-%zu len=%zu : ",split_pos,dis->len_payload-1, dis->len_payload-split_pos); + hexdump_limited_dlog(pat+split_pos,dis->len_payload-split_pos,PKTDATA_MAXDUMP); DLOG("\n"); + if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, fakeseg_len)) + goto send_orig; + } return VERDICT_DROP; } diff --git a/nfq/nfqws.c b/nfq/nfqws.c index d93ca464..aa12aa9c 100644 --- a/nfq/nfqws.c +++ b/nfq/nfqws.c @@ -1147,6 +1147,48 @@ err: return false; } +static bool parse_fakedsplit_mod(char *opt, struct fakedsplit_mod *fs_mod) +{ + char *e,*e2,*p,c,c2; + + for (p=opt ; p ; ) + { + for (e2=p ; *e2 && *e2!=',' && *e2!='=' ; e2++); + + if ((e = strchr(e2,','))) + { + c=*e; + *e=0; + } + + if (*e2=='=') + { + c2=*e2; + *e2=0; + } + else + e2=NULL; + + if (!strcmp(p,"altorder")) + { + if (!e2 || !e2[1] || e2[1]==',') goto err; + fs_mod->ordering = atoi(e2+1); + if (fs_mod->ordering<0 || fs_mod->ordering>3) goto err; + } + else if (strcmp(p,"none")) + goto err; + + if (e2) *e2=c2; + if (e) *e++=c; + p = e; + } + return true; +err: + if (e2) *e2=c2; + if (e) *e++=c; + return false; +} + static bool parse_tcpmod(char *opt, struct tcp_mod *tcp_mod) { char *e,*e2,*p,c,c2; @@ -1735,6 +1777,7 @@ static void exithelp(void) " --dpi-desync-split-seqovl=N|-N|marker+N|marker-N ; use sequence overlap before first sent original split segment\n" " --dpi-desync-split-seqovl-pattern=|0xHEX ; pattern for the fake part of overlap\n" " --dpi-desync-fakedsplit-pattern=|0xHEX ; fake pattern for fakedsplit/fakeddisorder\n" + " --dpi-desync-fakedsplit-mod=mod[,mod]\t\t; mods can be none,altorder=0|1|2|3\n" " --dpi-desync-hostfakesplit-midhost=marker+N|marker-N ; additionally split real hostname at specified marker. must be within host..endhost or won't be splitted.\n" " --dpi-desync-hostfakesplit-mod=mod[,mod]\t; mods can be none,host=,altorder=0|1\n" " --dpi-desync-ipfrag-pos-tcp=<8..%u>\t\t; ip frag position starting from the transport header. multiple of 8, default %u.\n" @@ -1916,6 +1959,7 @@ enum opt_indices { IDX_DPI_DESYNC_SPLIT_SEQOVL, IDX_DPI_DESYNC_SPLIT_SEQOVL_PATTERN, IDX_DPI_DESYNC_FAKEDSPLIT_PATTERN, + IDX_DPI_DESYNC_FAKEDSPLIT_MOD, IDX_DPI_DESYNC_HOSTFAKESPLIT_MIDHOST, IDX_DPI_DESYNC_HOSTFAKESPLIT_MOD, IDX_DPI_DESYNC_IPFRAG_POS_TCP, @@ -2047,6 +2091,7 @@ static const struct option long_options[] = { [IDX_DPI_DESYNC_SPLIT_SEQOVL] = {"dpi-desync-split-seqovl", required_argument, 0, 0}, [IDX_DPI_DESYNC_SPLIT_SEQOVL_PATTERN] = {"dpi-desync-split-seqovl-pattern", required_argument, 0, 0}, [IDX_DPI_DESYNC_FAKEDSPLIT_PATTERN] = {"dpi-desync-fakedsplit-pattern", required_argument, 0, 0}, + [IDX_DPI_DESYNC_FAKEDSPLIT_MOD] = {"dpi-desync-fakedsplit-mod", required_argument, 0, 0}, [IDX_DPI_DESYNC_HOSTFAKESPLIT_MIDHOST] = {"dpi-desync-hostfakesplit-midhost", required_argument, 0, 0}, [IDX_DPI_DESYNC_HOSTFAKESPLIT_MOD] = {"dpi-desync-hostfakesplit-mod", required_argument, 0, 0}, [IDX_DPI_DESYNC_IPFRAG_POS_TCP] = {"dpi-desync-ipfrag-pos-tcp", required_argument, 0, 0}, @@ -2686,6 +2731,13 @@ int main(int argc, char **argv) fill_pattern(dp->fsplit_pattern,sizeof(dp->fsplit_pattern),buf,sz); } break; + case IDX_DPI_DESYNC_FAKEDSPLIT_MOD: + if (!parse_fakedsplit_mod(optarg,&dp->fs_mod)) + { + DLOG_ERR("Invalid fakedsplit mod : %s\n",optarg); + exit_clean(1); + } + break; case IDX_DPI_DESYNC_HOSTFAKESPLIT_MIDHOST: if (!strcmp(optarg,"0")) { @@ -2702,7 +2754,7 @@ int main(int argc, char **argv) case IDX_DPI_DESYNC_HOSTFAKESPLIT_MOD: if (!parse_hostfakesplit_mod(optarg,&dp->hfs_mod)) { - DLOG_ERR("Invalid fakehostsplit mod : %s\n",optarg); + DLOG_ERR("Invalid hostfakesplit mod : %s\n",optarg); exit_clean(1); } break; diff --git a/nfq/params.h b/nfq/params.h index c2e6571c..8e3f5373 100644 --- a/nfq/params.h +++ b/nfq/params.h @@ -85,6 +85,10 @@ struct hostfakesplit_mod size_t host_size; int ordering; }; +struct fakedsplit_mod +{ + int ordering; +}; struct tcp_mod { bool seq; @@ -143,7 +147,7 @@ struct desync_profile struct blob_item *tls_fake_last; struct hostfakesplit_mod hfs_mod; - + struct fakedsplit_mod fs_mod; struct tcp_mod tcp_mod; int udplen_increment;