nfqws: ipfrag1 desync mode

This commit is contained in:
bol-van 2022-02-05 15:41:46 +03:00
parent 190b4e367f
commit 4aef7a96a4
5 changed files with 61 additions and 19 deletions

View File

@ -205,7 +205,11 @@ bool prepare_tcp_segment6(
{
uint16_t tcpoptlen = tcpopt_len(fooling,timestamps,scale_factor);
uint16_t transport_payload_len = sizeof(struct tcphdr) + tcpoptlen + len;
uint16_t ip_payload_len = transport_payload_len + 8*!!((fooling & (FOOL_HOPBYHOP|FOOL_HOPBYHOP2))==FOOL_HOPBYHOP) + 16*!!(fooling & FOOL_HOPBYHOP2) + 8*!!(fooling & FOOL_DESTOPT);
uint16_t ip_payload_len = transport_payload_len +
8*!!((fooling & (FOOL_HOPBYHOP|FOOL_HOPBYHOP2))==FOOL_HOPBYHOP) +
16*!!(fooling & FOOL_HOPBYHOP2) +
8*!!(fooling & FOOL_DESTOPT) +
8*!!(fooling & FOOL_IPFRAG1);
uint16_t pktlen = sizeof(struct ip6_hdr) + ip_payload_len;
if (pktlen>*buflen) return false;
@ -227,7 +231,7 @@ bool prepare_tcp_segment6(
}
hbh->ip6h_nxt = IPPROTO_TCP;
nexttype = &hbh->ip6h_nxt;
proto = 0; // hop by hop options
proto = IPPROTO_HOPOPTS;
}
if (fooling & FOOL_DESTOPT)
{
@ -236,9 +240,23 @@ bool prepare_tcp_segment6(
memset(dest,0,8);
dest->ip6d_nxt = IPPROTO_TCP;
if (nexttype)
*nexttype = 60; // destination options
*nexttype = IPPROTO_DSTOPTS;
else
proto = 60;
proto = IPPROTO_DSTOPTS;
nexttype = &dest->ip6d_nxt;
}
if (fooling & FOOL_IPFRAG1)
{
struct ip6_frag *frag = (struct ip6_frag*)tcp;
tcp = (struct tcphdr*)((uint8_t*)tcp+sizeof(struct ip6_frag));
frag->ip6f_nxt = IPPROTO_TCP;
frag->ip6f_ident = htonl(1+random()%0xFFFFFFFF);
frag->ip6f_reserved = 0;
frag->ip6f_offlg = 0;
if (nexttype)
*nexttype = IPPROTO_FRAGMENT;
else
proto = IPPROTO_FRAGMENT;
}
uint8_t *payload = (uint8_t*)(tcp+1)+tcpoptlen;
@ -309,7 +327,11 @@ bool prepare_udp_segment6(
uint8_t *buf, size_t *buflen)
{
uint16_t transport_payload_len = sizeof(struct udphdr) + len;
uint16_t ip_payload_len = transport_payload_len + 8*!!((fooling & (FOOL_HOPBYHOP|FOOL_HOPBYHOP2))==FOOL_HOPBYHOP) + 16*!!(fooling & FOOL_HOPBYHOP2) + 8*!!(fooling & FOOL_DESTOPT) ;
uint16_t ip_payload_len = transport_payload_len +
8*!!((fooling & (FOOL_HOPBYHOP|FOOL_HOPBYHOP2))==FOOL_HOPBYHOP) +
16*!!(fooling & FOOL_HOPBYHOP2) +
8*!!(fooling & FOOL_DESTOPT) +
8*!!(fooling & FOOL_IPFRAG1);
uint16_t pktlen = sizeof(struct ip6_hdr) + ip_payload_len;
if (pktlen>*buflen) return false;
@ -331,7 +353,7 @@ bool prepare_udp_segment6(
}
hbh->ip6h_nxt = IPPROTO_UDP;
nexttype = &hbh->ip6h_nxt;
proto = 0; // hop by hop options
proto = IPPROTO_HOPOPTS;
}
if (fooling & FOOL_DESTOPT)
{
@ -340,9 +362,23 @@ bool prepare_udp_segment6(
memset(dest,0,8);
dest->ip6d_nxt = IPPROTO_UDP;
if (nexttype)
*nexttype = 60; // destination options
*nexttype = IPPROTO_DSTOPTS;
else
proto = 60;
proto = IPPROTO_DSTOPTS;
nexttype = &dest->ip6d_nxt;
}
if (fooling & FOOL_IPFRAG1)
{
struct ip6_frag *frag = (struct ip6_frag*)udp;
udp = (struct udphdr*)((uint8_t*)udp+sizeof(struct ip6_frag));
frag->ip6f_nxt = IPPROTO_UDP;
frag->ip6f_ident = htonl(1+random()%0xFFFFFFFF);
frag->ip6f_reserved = 0;
frag->ip6f_offlg = 0;
if (nexttype)
*nexttype = IPPROTO_FRAGMENT;
else
proto = IPPROTO_FRAGMENT;
}
uint8_t *payload = (uint8_t*)(udp+1);

View File

@ -23,6 +23,7 @@ uint32_t net16_add(uint16_t netorder_value, uint16_t cpuorder_increment);
#define FOOL_HOPBYHOP 0x10
#define FOOL_HOPBYHOP2 0x20
#define FOOL_DESTOPT 0x40
#define FOOL_IPFRAG1 0x80
#define SCALE_NONE ((uint8_t)-1)

View File

@ -67,7 +67,7 @@ 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;
return mode==DESYNC_FAKE || 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)
{
@ -103,6 +103,8 @@ enum dpi_desync_mode desync_mode_from_string(const char *s)
return DESYNC_HOPBYHOP;
else if (!strcmp(s,"destopt"))
return DESYNC_DESTOPT;
else if (!strcmp(s,"ipfrag1"))
return DESYNC_IPFRAG1;
return DESYNC_INVALID;
}
@ -389,7 +391,8 @@ packet_process_result dpi_desync_tcp_packet(uint8_t *data_pkt, size_t len_pkt, s
break;
case DESYNC_HOPBYHOP:
case DESYNC_DESTOPT:
fooling_orig = (desync_mode==DESYNC_HOPBYHOP) ? FOOL_HOPBYHOP : FOOL_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 (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->th_seq, tcphdr->th_ack, tcphdr->th_win, scale_factor, timestamps,
@ -562,15 +565,15 @@ packet_process_result dpi_desync_tcp_packet(uint8_t *data_pkt, size_t len_pkt, s
size_t pkt_orig_len;
size_t ipfrag_pos = (params.desync_ipfrag_pos_tcp && params.desync_ipfrag_pos_tcp<len_tcp) ? params.desync_ipfrag_pos_tcp : 24;
uint32_t ident = ip ? ip->ip_id ? ip->ip_id : htons(1+random()%0xFFFF) : htonl(1+random()&0xFFFFFFFF);
uint32_t ident = ip ? ip->ip_id ? ip->ip_id : htons(1+random()%0xFFFF) : htonl(1+random()%0xFFFFFFFF);
pkt1_len = sizeof(pkt1);
pkt2_len = sizeof(pkt2);
if (ip6hdr && fooling_orig!=FOOL_NONE)
if (ip6hdr && (fooling_orig==FOOL_HOPBYHOP || fooling_orig==FOOL_DESTOPT))
{
pkt_orig_len = sizeof(pkt3);
if (!ip6_insert_simple_hdr(fooling_orig==FOOL_HOPBYHOP ? 0 : 60, data_pkt, len_pkt, pkt3, &pkt_orig_len))
if (!ip6_insert_simple_hdr(fooling_orig==FOOL_HOPBYHOP ? IPPROTO_HOPOPTS : IPPROTO_DSTOPTS, data_pkt, len_pkt, pkt3, &pkt_orig_len))
return res;
pkt_orig = pkt3;
}
@ -690,7 +693,8 @@ packet_process_result dpi_desync_udp_packet(uint8_t *data_pkt, size_t len_pkt, s
break;
case DESYNC_HOPBYHOP:
case DESYNC_DESTOPT:
fooling_orig = (desync_mode==DESYNC_HOPBYHOP) ? FOOL_HOPBYHOP : FOOL_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 (!prepare_udp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst,
@ -750,15 +754,15 @@ packet_process_result dpi_desync_udp_packet(uint8_t *data_pkt, size_t len_pkt, s
size_t len_transport = len_payload + sizeof(struct udphdr);
size_t ipfrag_pos = (params.desync_ipfrag_pos_udp && params.desync_ipfrag_pos_udp<len_transport) ? params.desync_ipfrag_pos_udp : sizeof(struct udphdr);
// freebsd do not set ip.id
uint32_t ident = ip ? ip->ip_id ? ip->ip_id : htons(1+random()%0xFFFF) : htonl(1+random()&0xFFFFFFFF);
uint32_t ident = ip ? ip->ip_id ? ip->ip_id : htons(1+random()%0xFFFF) : htonl(1+random()%0xFFFFFFFF);
pkt1_len = sizeof(pkt1);
pkt2_len = sizeof(pkt2);
if (ip6hdr && fooling_orig!=FOOL_NONE)
if (ip6hdr && (fooling_orig==FOOL_HOPBYHOP || fooling_orig==FOOL_DESTOPT))
{
pkt_orig_len = sizeof(pkt3);
if (!ip6_insert_simple_hdr(fooling_orig==FOOL_HOPBYHOP ? 0 : 60, data_pkt, len_pkt, pkt3, &pkt_orig_len))
if (!ip6_insert_simple_hdr(fooling_orig==FOOL_HOPBYHOP ? IPPROTO_HOPOPTS : IPPROTO_DSTOPTS, data_pkt, len_pkt, pkt3, &pkt_orig_len))
return res;
pkt_orig = pkt3;
}

View File

@ -31,7 +31,8 @@ enum dpi_desync_mode {
DESYNC_SPLIT2,
DESYNC_IPFRAG2,
DESYNC_HOPBYHOP,
DESYNC_DESTOPT
DESYNC_DESTOPT,
DESYNC_IPFRAG1
};
extern const char *fake_http_request_default;

View File

@ -505,7 +505,7 @@ static void exithelp()
" --hostspell\t\t\t\t; exact spelling of \"Host\" header. must be 4 chars. default is \"host\"\n"
" --hostnospace\t\t\t\t; remove space after Host: and add it to User-Agent: to preserve packet size\n"
" --domcase\t\t\t\t; mix domain case : Host: TeSt.cOm\n"
" --dpi-desync=[<mode0>,]<mode>[,<mode2>] ; try to desync dpi state. modes : synack fake rst rstack hopbyhop destopt disorder disorder2 split split2 ipfrag2\n"
" --dpi-desync=[<mode0>,]<mode>[,<mode2>] ; try to desync dpi state. modes : synack fake rst rstack hopbyhop destopt ipfrag1 disorder disorder2 split split2 ipfrag2\n"
#ifdef __linux__
" --dpi-desync-fwmark=<int|0xHEX>\t; override fwmark for desync packet. default = 0x%08X (%u)\n"
#elif defined(SO_USER_COOKIE)