mirror of
https://github.com/bol-van/zapret.git
synced 2024-11-26 20:20:53 +03:00
nfqws: ipfrag1 desync mode
This commit is contained in:
parent
190b4e367f
commit
4aef7a96a4
@ -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);
|
||||
|
@ -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)
|
||||
|
||||
|
22
nfq/desync.c
22
nfq/desync.c
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user