diff --git a/nfq/desync.c b/nfq/desync.c index 321cf328..920b442b 100644 --- a/nfq/desync.c +++ b/nfq/desync.c @@ -2036,9 +2036,36 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint DLOG("fakehost out of memory\n"); goto send_orig; } - fill_random_az(fakehost,1); - fill_random_az09(fakehost+1,host_size-1); - if (host_size>=7) fakehost[host_size-4] = '.'; + if (*dp->hfs_mod.host) + { + if (host_size<=dp->hfs_mod.host_size) + { + // "google.com" => "gle.com" + // "google.com" => "google.com" + memcpy(fakehost,dp->hfs_mod.host+dp->hfs_mod.host_size-host_size,host_size); + } + else + { + // "google.com" => "nb4auv9.google.com" + // "google.com" => ".google.com" + sz = host_size - dp->hfs_mod.host_size; + memcpy(fakehost+sz,dp->hfs_mod.host,dp->hfs_mod.host_size); + fakehost[--sz]='.'; + if (sz) + { + fill_random_az(fakehost,1); + sz--; + } + fill_random_az09(fakehost+1,sz); + } + } + else + { + fill_random_az(fakehost,1); + fill_random_az09(fakehost+1,host_size-1); + if (host_size>=7) fakehost[host_size-4] = '.'; + } + fakehost[host_size]=0; DLOG("generated fake host: %s\n",fakehost); pkt2_len = sizeof(pkt2); diff --git a/nfq/nfqws.c b/nfq/nfqws.c index ac3d558d..465b5d2b 100644 --- a/nfq/nfqws.c +++ b/nfq/nfqws.c @@ -1098,6 +1098,49 @@ err: return false; } +static bool parse_hostfakesplit_mod(char *opt, struct hostfakesplit_mod *hfs_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,"host")) + { + if (!e2 || !e2[1] || e2[1]==',') goto err; + strncpy(hfs_mod->host,e2+1,sizeof(hfs_mod->host)-1); + hfs_mod->host[sizeof(hfs_mod->host)-1-1]=0; + hfs_mod->host_size = strlen(hfs_mod->host); // cache value + } + 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; @@ -1642,6 +1685,7 @@ static void exithelp(void) " --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-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; can be none or host=\n" " --dpi-desync-ipfrag-pos-tcp=<8..%u>\t\t; ip frag position starting from the transport header. multiple of 8, default %u.\n" " --dpi-desync-ipfrag-pos-udp=<8..%u>\t\t; ip frag position starting from the transport header. multiple of 8, default %u.\n" " --dpi-desync-ts-increment=\t\t; ts fooling TSval signed increment. default %d\n" @@ -1821,6 +1865,7 @@ enum opt_indices { IDX_DPI_DESYNC_SPLIT_SEQOVL_PATTERN, IDX_DPI_DESYNC_FAKEDSPLIT_PATTERN, IDX_DPI_DESYNC_HOSTFAKESPLIT_MIDHOST, + IDX_DPI_DESYNC_HOSTFAKESPLIT_MOD, IDX_DPI_DESYNC_IPFRAG_POS_TCP, IDX_DPI_DESYNC_IPFRAG_POS_UDP, IDX_DPI_DESYNC_TS_INCREMENT, @@ -1950,6 +1995,7 @@ static const struct option long_options[] = { [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_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}, [IDX_DPI_DESYNC_IPFRAG_POS_UDP] = {"dpi-desync-ipfrag-pos-udp", required_argument, 0, 0}, [IDX_DPI_DESYNC_TS_INCREMENT] = {"dpi-desync-ts-increment", required_argument, 0, 0}, @@ -2599,6 +2645,13 @@ int main(int argc, char **argv) exit_clean(1); } break; + case IDX_DPI_DESYNC_HOSTFAKESPLIT_MOD: + if (!parse_hostfakesplit_mod(optarg,&dp->hfs_mod)) + { + DLOG_ERR("Invalid fakehostsplit mod : %s\n",optarg); + exit_clean(1); + } + break; case IDX_DPI_DESYNC_IPFRAG_POS_TCP: if (sscanf(optarg,"%u",&dp->desync_ipfrag_pos_tcp)<1 || dp->desync_ipfrag_pos_tcp<1 || dp->desync_ipfrag_pos_tcp>DPI_DESYNC_MAX_FAKE_LEN) { diff --git a/nfq/params.h b/nfq/params.h index cbf37a3f..1b6ccc84 100644 --- a/nfq/params.h +++ b/nfq/params.h @@ -76,9 +76,14 @@ struct fake_tls_mod_cache }; struct fake_tls_mod { - char sni[64]; + char sni[128]; uint32_t mod; }; +struct hostfakesplit_mod +{ + char host[128]; + size_t host_size; +}; typedef enum {SS_NONE=0,SS_SYN,SS_SYNACK,SS_ACKSYN} t_synack_split; @@ -132,6 +137,8 @@ struct desync_profile struct fake_tls_mod tls_mod_last; struct blob_item *tls_fake_last; + struct hostfakesplit_mod hfs_mod; + int udplen_increment; bool filter_ipv4,filter_ipv6;