diff --git a/docs/changes.txt b/docs/changes.txt index 2a4a92c5..b932b877 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -546,6 +546,6 @@ v71.5 winws: --wf-raw-part nfqws: --dpi-desync=hostfakesplit +nfqws: --dpi-desync-fake-tcp-mod=seq blockcheck: new strategies blockcheck: curl test simulation : SIMULATE=1 -blockcheck: print strategies that work for all tested domains. can be trusted only if SCANLEVEL=force. diff --git a/nfq/desync.c b/nfq/desync.c index 13d1e29d..5f79f63f 100644 --- a/nfq/desync.c +++ b/nfq/desync.c @@ -1900,7 +1900,9 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint uint8_t *fake_data; uint8_t fake_data_buf[FAKE_MAX_TCP]; int n=0; + uint32_t sequence, sequence0; + sequence = sequence0 = ntohl(dis->tcp->th_seq); ip_id = IP4_IP_ID_FIX(dis->ip); LIST_FOREACH(fake_item, fake, next) @@ -1919,7 +1921,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint fake_data = fake_item->data; } pkt1_len = sizeof(pkt1); - if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, false, 0, dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps, + if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, false, 0, htonl(sequence), dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps, DF,ttl_fake,IP4_TOS(dis->ip),ip_id,IP6_FLOW(dis->ip6), dp->desync_fooling_mode,dp->desync_ts_increment,dp->desync_badseq_increment,dp->desync_badseq_ack_increment, fake_data, fake_item->size, pkt1, &pkt1_len)) @@ -1927,7 +1929,8 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint reasm_orig_cancel(ctrack); goto send_orig; } - DLOG("sending fake[%d] : ", n); + + DLOG("sending fake[%d] seq=+%u : ", n, sequence-sequence0); hexdump_limited_dlog(fake_data,fake_item->size,PKTDATA_MAXDUMP); DLOG("\n"); if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len)) { @@ -1935,6 +1938,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint goto send_orig; } ip_id=IP4_IP_ID_NEXT(ip_id); + if (dp->tcp_mod.seq) sequence += fake_item->size; } } bFake = true; diff --git a/nfq/nfqws.c b/nfq/nfqws.c index 9f370f1a..465ac183 100644 --- a/nfq/nfqws.c +++ b/nfq/nfqws.c @@ -1147,6 +1147,46 @@ err: return false; } +static bool parse_tcpmod(char *opt, struct tcp_mod *tcp_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,"seq")) + { + tcp_mod->seq = true; + } + 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_fooling(char *opt, unsigned int *fooling_mode) { char *e,*p = opt; @@ -1698,6 +1738,7 @@ static void exithelp(void) " --dpi-desync-badseq-increment=\t; badseq fooling seq signed increment. default %d\n" " --dpi-desync-badack-increment=\t; badseq fooling ackseq signed increment. default %d\n" " --dpi-desync-any-protocol=0|1\t\t\t; 0(default)=desync only http and tls 1=desync any nonempty data packet\n" + " --dpi-desync-fake-tcp-mod=mod[,mod]\t\t; comma separated list of tcp fake mods. available mods : none,seq\n" " --dpi-desync-fake-http=|0xHEX\t; file containing fake http request\n" " --dpi-desync-fake-tls=|0xHEX|!\t; file containing fake TLS ClientHello (for https)\n" " --dpi-desync-fake-tls-mod=mod[,mod]\t\t; comma separated list of TLS fake mods. available mods : none,rnd,rndsni,sni=,dupsid,padencap\n" @@ -1878,6 +1919,7 @@ enum opt_indices { IDX_DPI_DESYNC_BADSEQ_INCREMENT, IDX_DPI_DESYNC_BADACK_INCREMENT, IDX_DPI_DESYNC_ANY_PROTOCOL, + IDX_DPI_DESYNC_FAKE_TCP_MOD, IDX_DPI_DESYNC_FAKE_HTTP, IDX_DPI_DESYNC_FAKE_TLS, IDX_DPI_DESYNC_FAKE_TLS_MOD, @@ -2008,6 +2050,7 @@ static const struct option long_options[] = { [IDX_DPI_DESYNC_BADSEQ_INCREMENT] = {"dpi-desync-badseq-increment", required_argument, 0, 0}, [IDX_DPI_DESYNC_BADACK_INCREMENT] = {"dpi-desync-badack-increment", required_argument, 0, 0}, [IDX_DPI_DESYNC_ANY_PROTOCOL] = {"dpi-desync-any-protocol", optional_argument, 0, 0}, + [IDX_DPI_DESYNC_FAKE_TCP_MOD] = {"dpi-desync-fake-tcp-mod", required_argument, 0, 0}, [IDX_DPI_DESYNC_FAKE_HTTP] = {"dpi-desync-fake-http", required_argument, 0, 0}, [IDX_DPI_DESYNC_FAKE_TLS] = {"dpi-desync-fake-tls", required_argument, 0, 0}, [IDX_DPI_DESYNC_FAKE_TLS_MOD] = {"dpi-desync-fake-tls-mod", required_argument, 0, 0}, @@ -2706,6 +2749,13 @@ int main(int argc, char **argv) case IDX_DPI_DESYNC_ANY_PROTOCOL: dp->desync_any_proto = !optarg || atoi(optarg); break; + case IDX_DPI_DESYNC_FAKE_TCP_MOD: + if (!parse_tcpmod(optarg,&dp->tcp_mod)) + { + DLOG_ERR("Invalid tcp mod : %s\n",optarg); + exit_clean(1); + } + break; case IDX_DPI_DESYNC_FAKE_HTTP: load_blob_to_collection(optarg, &dp->fake_http, FAKE_MAX_TCP,0); break; diff --git a/nfq/params.h b/nfq/params.h index 778ec54a..c2e6571c 100644 --- a/nfq/params.h +++ b/nfq/params.h @@ -85,6 +85,10 @@ struct hostfakesplit_mod size_t host_size; int ordering; }; +struct tcp_mod +{ + bool seq; +}; typedef enum {SS_NONE=0,SS_SYN,SS_SYNACK,SS_ACKSYN} t_synack_split; @@ -140,6 +144,8 @@ struct desync_profile struct hostfakesplit_mod hfs_mod; + struct tcp_mod tcp_mod; + int udplen_increment; bool filter_ipv4,filter_ipv6;