mirror of
https://github.com/bol-van/zapret.git
synced 2025-12-06 11:36:46 +03:00
nfqws: --dpi-desync=hostfakesplit
This commit is contained in:
@@ -545,3 +545,4 @@ readme: hardware problems description
|
||||
v71.5
|
||||
|
||||
winws: --wf-raw-part
|
||||
nfqws: --dpi-desync=hostfakesplit
|
||||
|
||||
168
nfq/desync.c
168
nfq/desync.c
@@ -170,18 +170,20 @@ bool desync_only_first_stage(enum dpi_desync_mode mode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool desync_valid_second_stage(enum dpi_desync_mode mode)
|
||||
{
|
||||
return mode==DESYNC_NONE || mode==DESYNC_FAKEDDISORDER || mode==DESYNC_FAKEDSPLIT || mode==DESYNC_MULTISPLIT || mode==DESYNC_MULTIDISORDER || mode==DESYNC_IPFRAG2 || mode==DESYNC_UDPLEN || mode==DESYNC_TAMPER;
|
||||
}
|
||||
bool desync_valid_second_stage_tcp(enum dpi_desync_mode mode)
|
||||
{
|
||||
return mode==DESYNC_NONE || mode==DESYNC_FAKEDDISORDER || mode==DESYNC_FAKEDSPLIT || mode==DESYNC_MULTISPLIT || mode==DESYNC_MULTIDISORDER || mode==DESYNC_IPFRAG2;
|
||||
return
|
||||
mode==DESYNC_NONE || mode==DESYNC_FAKEDDISORDER || mode==DESYNC_FAKEDSPLIT || mode==DESYNC_MULTISPLIT || mode==DESYNC_MULTIDISORDER || mode==DESYNC_HOSTFAKESPLIT ||
|
||||
mode==DESYNC_IPFRAG2;
|
||||
}
|
||||
bool desync_valid_second_stage_udp(enum dpi_desync_mode mode)
|
||||
{
|
||||
return mode==DESYNC_NONE || mode==DESYNC_UDPLEN || mode==DESYNC_TAMPER || mode==DESYNC_IPFRAG2;
|
||||
}
|
||||
bool desync_valid_second_stage(enum dpi_desync_mode mode)
|
||||
{
|
||||
return desync_valid_second_stage_tcp(mode) || desync_valid_second_stage_udp(mode);
|
||||
}
|
||||
enum dpi_desync_mode desync_mode_from_string(const char *s)
|
||||
{
|
||||
if (!s)
|
||||
@@ -206,6 +208,8 @@ enum dpi_desync_mode desync_mode_from_string(const char *s)
|
||||
return DESYNC_MULTISPLIT;
|
||||
else if (!strcmp(s,"multidisorder") || !strcmp(s,"disorder2"))
|
||||
return DESYNC_MULTIDISORDER;
|
||||
else if (!strcmp(s,"hostfakesplit"))
|
||||
return DESYNC_HOSTFAKESPLIT;
|
||||
else if (!strcmp(s,"ipfrag2"))
|
||||
return DESYNC_IPFRAG2;
|
||||
else if (!strcmp(s,"hopbyhop"))
|
||||
@@ -1813,6 +1817,51 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
else
|
||||
DLOG("regular split pos is outside of this packet\n");
|
||||
}
|
||||
else if (dp->desync_mode==DESYNC_HOSTFAKESPLIT || dp->desync_mode2==DESYNC_HOSTFAKESPLIT)
|
||||
{
|
||||
struct proto_pos splits[2] = {
|
||||
{ marker: PM_HOST, pos: 0},
|
||||
{ marker: PM_HOST_END, pos: 0}
|
||||
};
|
||||
split_pos=0;
|
||||
ResolveMultiPos(rdata_payload, rlen_payload, l7proto, splits, 2, multisplit_pos, &multisplit_count);
|
||||
if (multisplit_count!=2)
|
||||
{
|
||||
DLOG("hostfakesplit: host and endhost positions not found\n");
|
||||
multisplit_count=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int j;
|
||||
for (i=j=0;i<multisplit_count;i++)
|
||||
{
|
||||
multisplit_pos[j]=pos_normalize(multisplit_pos[i],reasm_offset,dis->len_payload);
|
||||
if (multisplit_pos[j]) j++;
|
||||
}
|
||||
multisplit_count=j;
|
||||
if (multisplit_count!=2)
|
||||
{
|
||||
DLOG("hostfakesplit: host or endhost are outside of this packet\n");
|
||||
multisplit_count=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
DLOG("normalized hostfakesplit pos: ");
|
||||
for (i=0;i<multisplit_count;i++) DLOG("%zu ",multisplit_pos[i]);
|
||||
DLOG("\n");
|
||||
multisplit_pos[2]=ResolvePos(rdata_payload,rlen_payload,l7proto,&dp->hostfakesplit_midhost);
|
||||
if (multisplit_pos[2])
|
||||
{
|
||||
multisplit_pos[2]=pos_normalize(multisplit_pos[2],reasm_offset,dis->len_payload);
|
||||
if (multisplit_pos[2]>multisplit_pos[0] && multisplit_pos[2]<multisplit_pos[1])
|
||||
{
|
||||
DLOG("normalized hostfakesplit midhost pos: %zu\n",multisplit_pos[2]);
|
||||
multisplit_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
multisplit_count=0;
|
||||
@@ -1916,6 +1965,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
fooling_orig = (dp->desync_mode==DESYNC_HOPBYHOP) ? FOOL_HOPBYHOP : (dp->desync_mode==DESYNC_DESTOPT) ? FOOL_DESTOPT : FOOL_IPFRAG1;
|
||||
if (dis->ip6 && (dp->desync_mode2==DESYNC_NONE || !desync_valid_second_stage_tcp(dp->desync_mode2) ||
|
||||
(!split_pos && (dp->desync_mode2==DESYNC_FAKEDSPLIT || dp->desync_mode2==DESYNC_FAKEDDISORDER)) ||
|
||||
(multisplit_count<2 && dp->desync_mode2==DESYNC_HOSTFAKESPLIT) ||
|
||||
(!multisplit_count && (dp->desync_mode2==DESYNC_MULTISPLIT || dp->desync_mode2==DESYNC_MULTIDISORDER))))
|
||||
{
|
||||
reasm_orig_cancel(ctrack);
|
||||
@@ -1947,6 +1997,114 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
enum dpi_desync_mode desync_mode = dp->desync_mode2==DESYNC_NONE ? dp->desync_mode : dp->desync_mode2;
|
||||
switch(desync_mode)
|
||||
{
|
||||
case DESYNC_HOSTFAKESPLIT:
|
||||
// can be 2 or 3 split pos
|
||||
// if 2 split pos : host, endhost
|
||||
// if 3 split pos : host, endhost, midhost
|
||||
if (multisplit_count>=2)
|
||||
{
|
||||
uint8_t *seg;
|
||||
size_t seg_len, host_size, pos_host, pos_endhost, pos_split_host, sz;
|
||||
char *fakehost;
|
||||
|
||||
seg = dis->data_payload;
|
||||
seg_len = dis->len_payload;
|
||||
pos_host = multisplit_pos[0];
|
||||
pos_endhost = multisplit_pos[1];
|
||||
pos_split_host = multisplit_count>=3 ? multisplit_pos[2] : 0;
|
||||
host_size = pos_endhost-pos_host;
|
||||
|
||||
ip_id = IP4_IP_ID_FIX(dis->ip);
|
||||
|
||||
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,
|
||||
DF,ttl_orig,IP4_TOS(dis->ip),ip_id,IP6_FLOW(dis->ip6),
|
||||
fooling_orig,0,0,0,
|
||||
seg, pos_host, pkt1, &pkt1_len))
|
||||
goto send_orig;
|
||||
ip_id=IP4_IP_ID_NEXT(ip_id);
|
||||
DLOG("sending hostfakesplit before_host part 0-%zu len=%zu : ",pos_host-1,pos_host);
|
||||
hexdump_limited_dlog(seg,pos_host,PKTDATA_MAXDUMP); DLOG("\n");
|
||||
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
||||
goto send_orig;
|
||||
|
||||
if (!(fakehost=malloc(host_size+1)))
|
||||
{
|
||||
DLOG("fakehost out of memory\n");
|
||||
goto send_orig;
|
||||
}
|
||||
fill_random_az09(fakehost,host_size);
|
||||
if (host_size>=7) fakehost[host_size-4] = '.';
|
||||
DLOG("generated fake host: %s\n",fakehost);
|
||||
|
||||
pkt1_len = sizeof(pkt1);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, false, 0,
|
||||
net32_add(dis->tcp->th_seq,pos_host), 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,
|
||||
fakehost, host_size, pkt1, &pkt1_len))
|
||||
{
|
||||
free(fakehost);
|
||||
goto send_orig;
|
||||
}
|
||||
ip_id=IP4_IP_ID_NEXT(ip_id);
|
||||
DLOG("sending hostfakesplit fake host %zu-%zu len=%zu : ",pos_host,pos_endhost-1,host_size);
|
||||
hexdump_limited_dlog(fakehost,host_size,PKTDATA_MAXDUMP); DLOG("\n");
|
||||
free(fakehost);
|
||||
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
||||
goto send_orig;
|
||||
|
||||
sz = pos_split_host ? pos_split_host-pos_host : host_size;
|
||||
pkt1_len = sizeof(pkt1);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, false, 0,
|
||||
net32_add(dis->tcp->th_seq,pos_host), dis->tcp->th_ack,
|
||||
dis->tcp->th_win, scale_factor, timestamps,
|
||||
DF,ttl_orig,IP4_TOS(dis->ip),ip_id,IP6_FLOW(dis->ip6),
|
||||
fooling_orig,0,0,0,
|
||||
seg+pos_host, sz, pkt1, &pkt1_len))
|
||||
goto send_orig;
|
||||
ip_id=IP4_IP_ID_NEXT(ip_id);
|
||||
DLOG("sending hostfakesplit real host %s%zu-%zu len=%zu : ",pos_split_host ? "part 1 " : "",pos_host,pos_host+sz-1,sz);
|
||||
hexdump_limited_dlog(seg+pos_host,sz,PKTDATA_MAXDUMP); DLOG("\n");
|
||||
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
||||
goto send_orig;
|
||||
|
||||
if (pos_split_host)
|
||||
{
|
||||
sz = pos_endhost - pos_split_host;
|
||||
pkt1_len = sizeof(pkt1);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, false, 0,
|
||||
net32_add(dis->tcp->th_seq,pos_split_host), dis->tcp->th_ack,
|
||||
dis->tcp->th_win, scale_factor, timestamps,
|
||||
DF,ttl_orig,IP4_TOS(dis->ip),ip_id,IP6_FLOW(dis->ip6),
|
||||
fooling_orig,0,0,0,
|
||||
seg+pos_split_host, sz, pkt1, &pkt1_len))
|
||||
goto send_orig;
|
||||
ip_id=IP4_IP_ID_NEXT(ip_id);
|
||||
DLOG("sending hostfakesplit real host part 2 %zu-%zu len=%zu : ",pos_split_host,pos_endhost-1,sz);
|
||||
hexdump_limited_dlog(seg+pos_split_host,sz,PKTDATA_MAXDUMP); DLOG("\n");
|
||||
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
||||
goto send_orig;
|
||||
}
|
||||
|
||||
pkt1_len = sizeof(pkt1);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, false, 0,
|
||||
net32_add(dis->tcp->th_seq,pos_endhost), dis->tcp->th_ack,
|
||||
dis->tcp->th_win, scale_factor, timestamps,
|
||||
DF,ttl_orig,IP4_TOS(dis->ip),ip_id,IP6_FLOW(dis->ip6),
|
||||
fooling_orig,0,0,0,
|
||||
seg+pos_endhost, seg_len-pos_endhost, pkt1, &pkt1_len))
|
||||
goto send_orig;
|
||||
DLOG("sending hostfakesplit after_host part %zu-%zu len=%zu : ",pos_endhost,seg_len-1,seg_len-pos_endhost);
|
||||
hexdump_limited_dlog(seg+pos_endhost,seg_len-pos_endhost,PKTDATA_MAXDUMP); DLOG("\n");
|
||||
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
||||
goto send_orig;
|
||||
|
||||
return VERDICT_DROP;
|
||||
}
|
||||
break;
|
||||
case DESYNC_MULTISPLIT:
|
||||
if (multisplit_count)
|
||||
{
|
||||
|
||||
@@ -32,6 +32,7 @@ enum dpi_desync_mode {
|
||||
DESYNC_FAKEDDISORDER,
|
||||
DESYNC_MULTISPLIT,
|
||||
DESYNC_MULTIDISORDER,
|
||||
DESYNC_HOSTFAKESPLIT,
|
||||
DESYNC_IPFRAG2,
|
||||
DESYNC_HOPBYHOP,
|
||||
DESYNC_DESTOPT,
|
||||
|
||||
22
nfq/nfqws.c
22
nfq/nfqws.c
@@ -1165,6 +1165,7 @@ static void SplitDebug(void)
|
||||
for(int x=0;x<dp->split_count;x++)
|
||||
DLOG("profile %d multisplit %s %d\n",dp->n,posmarker_name(dp->splits[x].marker),dp->splits[x].pos);
|
||||
if (!PROTO_POS_EMPTY(&dp->seqovl)) DLOG("profile %d seqovl %s %d\n",dp->n,posmarker_name(dp->seqovl.marker),dp->seqovl.pos);
|
||||
if (!PROTO_POS_EMPTY(&dp->hostfakesplit_midhost)) DLOG("profile %d hostfakesplit midhost %s %d\n",dp->n,posmarker_name(dp->hostfakesplit_midhost.marker),dp->hostfakesplit_midhost.pos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1620,7 +1621,7 @@ static void exithelp(void)
|
||||
" --methodeol\t\t\t\t\t; add '\\n' before method and remove space from Host:\n"
|
||||
" --dpi-desync=[<mode0>,]<mode>[,<mode2>]\t; try to desync dpi state. modes :\n"
|
||||
"\t\t\t\t\t\t; synack syndata fake fakeknown rst rstack hopbyhop destopt ipfrag1\n"
|
||||
"\t\t\t\t\t\t; multisplit multidisorder fakedsplit fakeddisorder ipfrag2 udplen tamper\n"
|
||||
"\t\t\t\t\t\t; multisplit multidisorder fakedsplit fakeddisorder hostfakesplit ipfrag2 udplen tamper\n"
|
||||
#ifdef __linux__
|
||||
" --dpi-desync-fwmark=<int|0xHEX>\t\t; override fwmark for desync packet. default = 0x%08X (%u)\n"
|
||||
#elif defined(SO_USER_COOKIE)
|
||||
@@ -1640,6 +1641,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=<filename>|0xHEX ; pattern for the fake part of overlap\n"
|
||||
" --dpi-desync-fakedsplit-pattern=<filename>|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-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=<int|0xHEX>\t\t; ts fooling TSval signed increment. default %d\n"
|
||||
@@ -1716,7 +1718,8 @@ void check_dp(const struct desync_profile *dp)
|
||||
// only linux has connbytes limiter
|
||||
if ((dp->desync_any_proto && !dp->desync_cutoff &&
|
||||
(dp->desync_mode==DESYNC_FAKE || dp->desync_mode==DESYNC_RST || dp->desync_mode==DESYNC_RSTACK ||
|
||||
dp->desync_mode==DESYNC_FAKEDSPLIT || dp->desync_mode==DESYNC_FAKEDDISORDER || dp->desync_mode2==DESYNC_FAKEDSPLIT || dp->desync_mode2==DESYNC_FAKEDDISORDER))
|
||||
dp->desync_mode==DESYNC_FAKEDSPLIT || dp->desync_mode==DESYNC_FAKEDDISORDER || dp->desync_mode==DESYNC_HOSTFAKESPLIT ||
|
||||
dp->desync_mode2==DESYNC_FAKEDSPLIT || dp->desync_mode2==DESYNC_FAKEDDISORDER || dp->desync_mode2==DESYNC_HOSTFAKESPLIT))
|
||||
||
|
||||
dp->dup_repeats && !dp->dup_cutoff)
|
||||
{
|
||||
@@ -1817,6 +1820,7 @@ enum opt_indices {
|
||||
IDX_DPI_DESYNC_SPLIT_SEQOVL,
|
||||
IDX_DPI_DESYNC_SPLIT_SEQOVL_PATTERN,
|
||||
IDX_DPI_DESYNC_FAKEDSPLIT_PATTERN,
|
||||
IDX_DPI_DESYNC_HOSTFAKESPLIT_MIDHOST,
|
||||
IDX_DPI_DESYNC_IPFRAG_POS_TCP,
|
||||
IDX_DPI_DESYNC_IPFRAG_POS_UDP,
|
||||
IDX_DPI_DESYNC_TS_INCREMENT,
|
||||
@@ -1945,6 +1949,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_HOSTFAKESPLIT_MIDHOST] = {"dpi-desync-hostfakesplit-midhost", 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},
|
||||
@@ -2581,6 +2586,19 @@ int main(int argc, char **argv)
|
||||
fill_pattern(dp->fsplit_pattern,sizeof(dp->fsplit_pattern),buf,sz);
|
||||
}
|
||||
break;
|
||||
case IDX_DPI_DESYNC_HOSTFAKESPLIT_MIDHOST:
|
||||
if (!strcmp(optarg,"0"))
|
||||
{
|
||||
// allow zero = disable midhost split
|
||||
dp->hostfakesplit_midhost.marker=PM_ABS;
|
||||
dp->hostfakesplit_midhost.pos=0;
|
||||
}
|
||||
else if (!parse_split_pos(optarg, &dp->hostfakesplit_midhost))
|
||||
{
|
||||
DLOG_ERR("Invalid argument for dpi-desync-hostfakesplit-midhost\n");
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -102,7 +102,7 @@ struct desync_profile
|
||||
// multisplit
|
||||
struct proto_pos splits[MAX_SPLITS];
|
||||
int split_count;
|
||||
struct proto_pos seqovl;
|
||||
struct proto_pos seqovl,hostfakesplit_midhost;
|
||||
|
||||
char dup_start_mode, dup_cutoff_mode; // n - packets, d - data packets, s - relative sequence
|
||||
bool dup_replace;
|
||||
|
||||
Reference in New Issue
Block a user