nfqws: fakeknown, udplen desync modes

This commit is contained in:
bol-van
2022-04-12 15:52:06 +03:00
parent 9919f3bc14
commit ffda684a43
15 changed files with 87 additions and 23 deletions

View File

@@ -67,22 +67,32 @@ bool desync_valid_zero_stage(enum dpi_desync_mode mode)
}
bool desync_valid_first_stage(enum dpi_desync_mode mode)
{
return mode==DESYNC_FAKE || mode==DESYNC_RST || mode==DESYNC_RSTACK || mode==DESYNC_HOPBYHOP || mode==DESYNC_DESTOPT || mode==DESYNC_IPFRAG1;
return mode==DESYNC_FAKE || mode==DESYNC_FAKE_KNOWN || mode==DESYNC_RST || mode==DESYNC_RSTACK || mode==DESYNC_HOPBYHOP || mode==DESYNC_DESTOPT || mode==DESYNC_IPFRAG1;
}
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_DISORDER || mode==DESYNC_DISORDER2 || mode==DESYNC_SPLIT || mode==DESYNC_SPLIT2 || mode==DESYNC_IPFRAG2 || mode==DESYNC_UDPLEN;
}
bool desync_valid_second_stage_tcp(enum dpi_desync_mode mode)
{
return mode==DESYNC_NONE || mode==DESYNC_DISORDER || mode==DESYNC_DISORDER2 || mode==DESYNC_SPLIT || mode==DESYNC_SPLIT2 || mode==DESYNC_IPFRAG2;
}
bool desync_valid_second_stage_udp(enum dpi_desync_mode mode)
{
return mode==DESYNC_NONE || mode==DESYNC_UDPLEN || mode==DESYNC_IPFRAG2;
}
enum dpi_desync_mode desync_mode_from_string(const char *s)
{
if (!s)
return DESYNC_NONE;
else if (!strcmp(s,"fake"))
return DESYNC_FAKE;
else if (!strcmp(s,"fakeknown"))
return DESYNC_FAKE_KNOWN;
else if (!strcmp(s,"rst"))
return DESYNC_RST;
else if (!strcmp(s,"rstack"))
@@ -105,6 +115,8 @@ enum dpi_desync_mode desync_mode_from_string(const char *s)
return DESYNC_DESTOPT;
else if (!strcmp(s,"ipfrag1"))
return DESYNC_IPFRAG1;
else if (!strcmp(s,"udplen"))
return DESYNC_UDPLEN;
return DESYNC_INVALID;
}
@@ -262,6 +274,7 @@ packet_process_result dpi_desync_tcp_packet(uint8_t *data_pkt, size_t len_pkt, s
char host[256];
bool bHaveHost=false;
bool bIsHttp;
bool bKnownProtocol = false;
uint8_t *p, *phost;
if ((bIsHttp = IsHttp(data_payload,len_payload)))
@@ -277,6 +290,7 @@ packet_process_result dpi_desync_tcp_packet(uint8_t *data_pkt, size_t len_pkt, s
DLOG("not applying tampering to HTTP without Host:\n")
return res;
}
bKnownProtocol = true;
}
else if (IsTLSClientHello(data_payload,len_payload))
{
@@ -294,6 +308,7 @@ packet_process_result dpi_desync_tcp_packet(uint8_t *data_pkt, size_t len_pkt, s
return res;
}
}
bKnownProtocol = true;
}
else
{
@@ -367,6 +382,13 @@ packet_process_result dpi_desync_tcp_packet(uint8_t *data_pkt, size_t len_pkt, s
b = false;
switch(desync_mode)
{
case DESYNC_FAKE_KNOWN:
if (!bKnownProtocol)
{
DLOG("not applying fake because of unknown protocol\n");
desync_mode = params.desync_mode2;
break;
}
case DESYNC_FAKE:
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->th_seq, tcphdr->th_ack, tcphdr->th_win, scale_factor, timestamps,
ttl_fake,params.desync_fooling_mode,params.desync_badseq_increment,params.desync_badseq_ack_increment,
@@ -393,7 +415,7 @@ packet_process_result dpi_desync_tcp_packet(uint8_t *data_pkt, size_t len_pkt, s
case DESYNC_DESTOPT:
case DESYNC_IPFRAG1:
fooling_orig = (desync_mode==DESYNC_HOPBYHOP) ? FOOL_HOPBYHOP : (desync_mode==DESYNC_DESTOPT) ? FOOL_DESTOPT : FOOL_IPFRAG1;
if (ip6hdr && params.desync_mode2==DESYNC_NONE)
if (ip6hdr && (params.desync_mode2==DESYNC_NONE || !desync_valid_second_stage_tcp(params.desync_mode2)))
{
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->th_seq, tcphdr->th_ack, tcphdr->th_win, scale_factor, timestamps,
ttl_orig,fooling_orig,0,0,
@@ -414,7 +436,7 @@ packet_process_result dpi_desync_tcp_packet(uint8_t *data_pkt, size_t len_pkt, s
{
if (!rawsend_rep((struct sockaddr *)&dst, params.desync_fwmark, pkt1, pkt1_len))
return res;
if (params.desync_mode2==DESYNC_NONE)
if (params.desync_mode2==DESYNC_NONE || !desync_valid_second_stage_tcp(params.desync_mode2))
{
if (params.desync_retrans)
{
@@ -657,6 +679,7 @@ packet_process_result dpi_desync_udp_packet(uint8_t *data_pkt, size_t len_pkt, s
bool b;
char host[256];
bool bHaveHost=false;
bool bKnownProtocol=false;
if (IsQUICInitial(data_payload,len_payload))
{
@@ -700,6 +723,7 @@ packet_process_result dpi_desync_udp_packet(uint8_t *data_pkt, size_t len_pkt, s
return res;
}
}
bKnownProtocol = true;
}
else
{
@@ -738,24 +762,32 @@ packet_process_result dpi_desync_udp_packet(uint8_t *data_pkt, size_t len_pkt, s
pkt1_len = sizeof(pkt1);
b = false;
switch(desync_mode)
{
case DESYNC_FAKE_KNOWN:
if (!bKnownProtocol)
{
DLOG("not applying fake because of unknown protocol\n");
desync_mode = params.desync_mode2;
break;
}
case DESYNC_FAKE:
if (!prepare_udp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, ttl_fake, params.desync_fooling_mode, fake, fake_size, pkt1, &pkt1_len))
if (!prepare_udp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, ttl_fake, params.desync_fooling_mode, 0, fake, fake_size, pkt1, &pkt1_len))
return res;
DLOG("sending fake request : ");
hexdump_limited_dlog(fake,fake_size,PKTDATA_MAXDUMP); DLOG("\n")
if (!rawsend_rep((struct sockaddr *)&dst, params.desync_fwmark, pkt1, pkt1_len))
return res;
b = true;
break;
case DESYNC_HOPBYHOP:
case DESYNC_DESTOPT:
case DESYNC_IPFRAG1:
fooling_orig = (desync_mode==DESYNC_HOPBYHOP) ? FOOL_HOPBYHOP : (desync_mode==DESYNC_DESTOPT) ? FOOL_DESTOPT : FOOL_IPFRAG1;
if (ip6hdr && params.desync_mode2==DESYNC_NONE)
if (ip6hdr && (params.desync_mode2==DESYNC_NONE || !desync_valid_second_stage_udp(params.desync_mode2)))
{
if (!prepare_udp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst,
ttl_orig,fooling_orig,
ttl_orig,fooling_orig,0,
data_payload, len_payload, pkt1, &pkt1_len))
{
return res;
@@ -767,14 +799,13 @@ packet_process_result dpi_desync_udp_packet(uint8_t *data_pkt, size_t len_pkt, s
return drop;
}
desync_mode = params.desync_mode2;
break;
}
if (b)
{
if (params.desync_mode2==DESYNC_NONE)
if (params.desync_mode2==DESYNC_NONE || !desync_valid_second_stage_udp(params.desync_mode2))
{
if (!rawsend_rep((struct sockaddr *)&dst, params.desync_fwmark, pkt1, pkt1_len))
return res;
DLOG("reinjecting original packet. len=%zu len_payload=%zu\n", len_pkt, len_payload)
#ifdef __FreeBSD__
// FreeBSD tend to pass ipv6 frames with wrong checksum
@@ -793,6 +824,14 @@ packet_process_result dpi_desync_udp_packet(uint8_t *data_pkt, size_t len_pkt, s
switch(desync_mode)
{
case DESYNC_UDPLEN:
pkt1_len = sizeof(pkt1);
if (!prepare_udp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, ttl_orig,fooling_orig, params.udplen_increment, data_payload, len_payload, pkt1, &pkt1_len))
return res;
DLOG("resending original packet with increased by %u length\n", params.udplen_increment);
if (!rawsend((struct sockaddr *)&dst, params.desync_fwmark, pkt1, pkt1_len))
return res;
return drop;
case DESYNC_IPFRAG2:
{