Browse Source

nfqws: fakeknown, udplen desync modes

pull/101/head
bol-van 3 years ago
parent
commit
ffda684a43
  1. BIN
      binaries/aarch64/nfqws
  2. BIN
      binaries/arm/nfqws
  3. BIN
      binaries/freebsd-x64/dvtws
  4. BIN
      binaries/mips32r1-lsb/nfqws
  5. BIN
      binaries/mips32r1-msb/nfqws
  6. BIN
      binaries/mips64r2-msb/nfqws
  7. BIN
      binaries/ppc/nfqws
  8. BIN
      binaries/x86/nfqws
  9. BIN
      binaries/x86_64/nfqws
  10. 20
      nfq/darkmagic.c
  11. 3
      nfq/darkmagic.h
  12. 59
      nfq/desync.c
  13. 6
      nfq/desync.h
  14. 19
      nfq/nfqws.c
  15. 3
      nfq/params.h

BIN
binaries/aarch64/nfqws

Binary file not shown.

BIN
binaries/arm/nfqws

Binary file not shown.

BIN
binaries/freebsd-x64/dvtws

Binary file not shown.

BIN
binaries/mips32r1-lsb/nfqws

Binary file not shown.

BIN
binaries/mips32r1-msb/nfqws

Binary file not shown.

BIN
binaries/mips64r2-msb/nfqws

Binary file not shown.

BIN
binaries/ppc/nfqws

Binary file not shown.

BIN
binaries/x86/nfqws

Binary file not shown.

BIN
binaries/x86_64/nfqws

Binary file not shown.

20
nfq/darkmagic.c

@ -298,10 +298,12 @@ bool prepare_udp_segment4(
const struct sockaddr_in *src, const struct sockaddr_in *dst, const struct sockaddr_in *src, const struct sockaddr_in *dst,
uint8_t ttl, uint8_t ttl,
uint8_t fooling, uint8_t fooling,
uint16_t padlen,
const void *data, uint16_t len, const void *data, uint16_t len,
uint8_t *buf, size_t *buflen) uint8_t *buf, size_t *buflen)
{ {
uint16_t ip_payload_len = sizeof(struct udphdr) + len; uint16_t datalen = len + padlen;
uint16_t ip_payload_len = sizeof(struct udphdr) + datalen;
uint16_t pktlen = sizeof(struct ip) + ip_payload_len; uint16_t pktlen = sizeof(struct ip) + ip_payload_len;
if (pktlen>*buflen) return false; if (pktlen>*buflen) return false;
@ -309,10 +311,12 @@ bool prepare_udp_segment4(
struct udphdr *udp = (struct udphdr*)(ip+1); struct udphdr *udp = (struct udphdr*)(ip+1);
uint8_t *payload = (uint8_t*)(udp+1); uint8_t *payload = (uint8_t*)(udp+1);
fill_iphdr(ip, &src->sin_addr, &dst->sin_addr, pktlen, IPPROTO_UDP, ttl); fill_iphdr(ip, &src->sin_addr, &dst->sin_addr, pktlen, IPPROTO_UDP, ttl);
fill_udphdr(udp, src->sin_port, dst->sin_port, len); fill_udphdr(udp, src->sin_port, dst->sin_port, datalen);
memcpy(payload,data,len); memcpy(payload,data,len);
memset(payload+len,0,padlen);
udp4_fix_checksum(udp,ip_payload_len,&ip->ip_src,&ip->ip_dst); udp4_fix_checksum(udp,ip_payload_len,&ip->ip_src,&ip->ip_dst);
if (fooling & FOOL_BADSUM) udp->uh_sum^=htons(0xBEAF); if (fooling & FOOL_BADSUM) udp->uh_sum^=htons(0xBEAF);
@ -323,10 +327,12 @@ bool prepare_udp_segment6(
const struct sockaddr_in6 *src, const struct sockaddr_in6 *dst, const struct sockaddr_in6 *src, const struct sockaddr_in6 *dst,
uint8_t ttl, uint8_t ttl,
uint8_t fooling, uint8_t fooling,
uint16_t padlen,
const void *data, uint16_t len, const void *data, uint16_t len,
uint8_t *buf, size_t *buflen) uint8_t *buf, size_t *buflen)
{ {
uint16_t transport_payload_len = sizeof(struct udphdr) + len; uint16_t datalen = len + padlen;
uint16_t transport_payload_len = sizeof(struct udphdr) + datalen;
uint16_t ip_payload_len = transport_payload_len + uint16_t ip_payload_len = transport_payload_len +
8*!!((fooling & (FOOL_HOPBYHOP|FOOL_HOPBYHOP2))==FOOL_HOPBYHOP) + 8*!!((fooling & (FOOL_HOPBYHOP|FOOL_HOPBYHOP2))==FOOL_HOPBYHOP) +
16*!!(fooling & FOOL_HOPBYHOP2) + 16*!!(fooling & FOOL_HOPBYHOP2) +
@ -384,9 +390,10 @@ bool prepare_udp_segment6(
uint8_t *payload = (uint8_t*)(udp+1); uint8_t *payload = (uint8_t*)(udp+1);
fill_ip6hdr(ip6, &src->sin6_addr, &dst->sin6_addr, ip_payload_len, proto, ttl); fill_ip6hdr(ip6, &src->sin6_addr, &dst->sin6_addr, ip_payload_len, proto, ttl);
fill_udphdr(udp, src->sin6_port, dst->sin6_port, len); fill_udphdr(udp, src->sin6_port, dst->sin6_port, datalen);
memcpy(payload,data,len); memcpy(payload,data,len);
memset(payload+len,0,padlen);
udp6_fix_checksum(udp,transport_payload_len,&ip6->ip6_src,&ip6->ip6_dst); udp6_fix_checksum(udp,transport_payload_len,&ip6->ip6_src,&ip6->ip6_dst);
if (fooling & FOOL_BADSUM) udp->uh_sum^=htons(0xBEAF); if (fooling & FOOL_BADSUM) udp->uh_sum^=htons(0xBEAF);
@ -397,13 +404,14 @@ bool prepare_udp_segment(
const struct sockaddr *src, const struct sockaddr *dst, const struct sockaddr *src, const struct sockaddr *dst,
uint8_t ttl, uint8_t ttl,
uint8_t fooling, uint8_t fooling,
uint16_t padlen,
const void *data, uint16_t len, const void *data, uint16_t len,
uint8_t *buf, size_t *buflen) uint8_t *buf, size_t *buflen)
{ {
return (src->sa_family==AF_INET && dst->sa_family==AF_INET) ? return (src->sa_family==AF_INET && dst->sa_family==AF_INET) ?
prepare_udp_segment4((struct sockaddr_in *)src,(struct sockaddr_in *)dst,ttl,fooling,data,len,buf,buflen) : prepare_udp_segment4((struct sockaddr_in *)src,(struct sockaddr_in *)dst,ttl,fooling,padlen,data,len,buf,buflen) :
(src->sa_family==AF_INET6 && dst->sa_family==AF_INET6) ? (src->sa_family==AF_INET6 && dst->sa_family==AF_INET6) ?
prepare_udp_segment6((struct sockaddr_in6 *)src,(struct sockaddr_in6 *)dst,ttl,fooling,data,len,buf,buflen) : prepare_udp_segment6((struct sockaddr_in6 *)src,(struct sockaddr_in6 *)dst,ttl,fooling,padlen,data,len,buf,buflen) :
false; false;
} }

3
nfq/darkmagic.h

@ -73,18 +73,21 @@ bool prepare_udp_segment4(
const struct sockaddr_in *src, const struct sockaddr_in *dst, const struct sockaddr_in *src, const struct sockaddr_in *dst,
uint8_t ttl, uint8_t ttl,
uint8_t fooling, uint8_t fooling,
uint16_t padlen,
const void *data, uint16_t len, const void *data, uint16_t len,
uint8_t *buf, size_t *buflen); uint8_t *buf, size_t *buflen);
bool prepare_udp_segment6( bool prepare_udp_segment6(
const struct sockaddr_in6 *src, const struct sockaddr_in6 *dst, const struct sockaddr_in6 *src, const struct sockaddr_in6 *dst,
uint8_t ttl, uint8_t ttl,
uint8_t fooling, uint8_t fooling,
uint16_t padlen,
const void *data, uint16_t len, const void *data, uint16_t len,
uint8_t *buf, size_t *buflen); uint8_t *buf, size_t *buflen);
bool prepare_udp_segment( bool prepare_udp_segment(
const struct sockaddr *src, const struct sockaddr *dst, const struct sockaddr *src, const struct sockaddr *dst,
uint8_t ttl, uint8_t ttl,
uint8_t fooling, uint8_t fooling,
uint16_t padlen,
const void *data, uint16_t len, const void *data, uint16_t len,
uint8_t *buf, size_t *buflen); uint8_t *buf, size_t *buflen);

59
nfq/desync.c

@ -67,22 +67,32 @@ bool desync_valid_zero_stage(enum dpi_desync_mode mode)
} }
bool desync_valid_first_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) bool desync_only_first_stage(enum dpi_desync_mode mode)
{ {
return false; return false;
} }
bool desync_valid_second_stage(enum dpi_desync_mode mode) 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; 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) enum dpi_desync_mode desync_mode_from_string(const char *s)
{ {
if (!s) if (!s)
return DESYNC_NONE; return DESYNC_NONE;
else if (!strcmp(s,"fake")) else if (!strcmp(s,"fake"))
return DESYNC_FAKE; return DESYNC_FAKE;
else if (!strcmp(s,"fakeknown"))
return DESYNC_FAKE_KNOWN;
else if (!strcmp(s,"rst")) else if (!strcmp(s,"rst"))
return DESYNC_RST; return DESYNC_RST;
else if (!strcmp(s,"rstack")) else if (!strcmp(s,"rstack"))
@ -105,6 +115,8 @@ enum dpi_desync_mode desync_mode_from_string(const char *s)
return DESYNC_DESTOPT; return DESYNC_DESTOPT;
else if (!strcmp(s,"ipfrag1")) else if (!strcmp(s,"ipfrag1"))
return DESYNC_IPFRAG1; return DESYNC_IPFRAG1;
else if (!strcmp(s,"udplen"))
return DESYNC_UDPLEN;
return DESYNC_INVALID; 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]; char host[256];
bool bHaveHost=false; bool bHaveHost=false;
bool bIsHttp; bool bIsHttp;
bool bKnownProtocol = false;
uint8_t *p, *phost; uint8_t *p, *phost;
if ((bIsHttp = IsHttp(data_payload,len_payload))) 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") DLOG("not applying tampering to HTTP without Host:\n")
return res; return res;
} }
bKnownProtocol = true;
} }
else if (IsTLSClientHello(data_payload,len_payload)) 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; return res;
} }
} }
bKnownProtocol = true;
} }
else else
{ {
@ -367,6 +382,13 @@ packet_process_result dpi_desync_tcp_packet(uint8_t *data_pkt, size_t len_pkt, s
b = false; b = false;
switch(desync_mode) 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: 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, 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, 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_DESTOPT:
case DESYNC_IPFRAG1: case DESYNC_IPFRAG1:
fooling_orig = (desync_mode==DESYNC_HOPBYHOP) ? FOOL_HOPBYHOP : (desync_mode==DESYNC_DESTOPT) ? FOOL_DESTOPT : FOOL_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, 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, 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)) if (!rawsend_rep((struct sockaddr *)&dst, params.desync_fwmark, pkt1, pkt1_len))
return res; 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) 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; bool b;
char host[256]; char host[256];
bool bHaveHost=false; bool bHaveHost=false;
bool bKnownProtocol=false;
if (IsQUICInitial(data_payload,len_payload)) 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; return res;
} }
} }
bKnownProtocol = true;
} }
else 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); pkt1_len = sizeof(pkt1);
b = false; b = false;
switch(desync_mode) 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: 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; return res;
DLOG("sending fake request : "); DLOG("sending fake request : ");
hexdump_limited_dlog(fake,fake_size,PKTDATA_MAXDUMP); DLOG("\n") 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; b = true;
break; break;
case DESYNC_HOPBYHOP: case DESYNC_HOPBYHOP:
case DESYNC_DESTOPT: case DESYNC_DESTOPT:
case DESYNC_IPFRAG1: case DESYNC_IPFRAG1:
fooling_orig = (desync_mode==DESYNC_HOPBYHOP) ? FOOL_HOPBYHOP : (desync_mode==DESYNC_DESTOPT) ? FOOL_DESTOPT : FOOL_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, 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)) data_payload, len_payload, pkt1, &pkt1_len))
{ {
return res; return res;
@ -767,14 +799,13 @@ packet_process_result dpi_desync_udp_packet(uint8_t *data_pkt, size_t len_pkt, s
return drop; return drop;
} }
desync_mode = params.desync_mode2; desync_mode = params.desync_mode2;
break;
} }
if (b) 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) DLOG("reinjecting original packet. len=%zu len_payload=%zu\n", len_pkt, len_payload)
#ifdef __FreeBSD__ #ifdef __FreeBSD__
// FreeBSD tend to pass ipv6 frames with wrong checksum // 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) 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: case DESYNC_IPFRAG2:
{ {

6
nfq/desync.h

@ -22,6 +22,7 @@ enum dpi_desync_mode {
DESYNC_NONE=0, DESYNC_NONE=0,
DESYNC_INVALID, DESYNC_INVALID,
DESYNC_FAKE, DESYNC_FAKE,
DESYNC_FAKE_KNOWN,
DESYNC_RST, DESYNC_RST,
DESYNC_RSTACK, DESYNC_RSTACK,
DESYNC_SYNACK, DESYNC_SYNACK,
@ -32,7 +33,8 @@ enum dpi_desync_mode {
DESYNC_IPFRAG2, DESYNC_IPFRAG2,
DESYNC_HOPBYHOP, DESYNC_HOPBYHOP,
DESYNC_DESTOPT, DESYNC_DESTOPT,
DESYNC_IPFRAG1 DESYNC_IPFRAG1,
DESYNC_UDPLEN
}; };
extern const char *fake_http_request_default; extern const char *fake_http_request_default;
@ -43,6 +45,8 @@ bool desync_valid_zero_stage(enum dpi_desync_mode mode);
bool desync_valid_first_stage(enum dpi_desync_mode mode); bool desync_valid_first_stage(enum dpi_desync_mode mode);
bool desync_only_first_stage(enum dpi_desync_mode mode); bool desync_only_first_stage(enum dpi_desync_mode mode);
bool desync_valid_second_stage(enum dpi_desync_mode mode); bool desync_valid_second_stage(enum dpi_desync_mode mode);
bool desync_valid_second_stage_tcp(enum dpi_desync_mode mode);
bool desync_valid_second_stage_udp(enum dpi_desync_mode mode);
void desync_init(); void desync_init();
packet_process_result dpi_desync_tcp_packet(uint8_t *data_pkt, size_t len_pkt, struct ip *ip, struct ip6_hdr *ip6hdr, struct tcphdr *tcphdr, size_t len_tcp, uint8_t *data_payload, size_t len_payload); packet_process_result dpi_desync_tcp_packet(uint8_t *data_pkt, size_t len_pkt, struct ip *ip, struct ip6_hdr *ip6hdr, struct tcphdr *tcphdr, size_t len_tcp, uint8_t *data_payload, size_t len_payload);

19
nfq/nfqws.c

@ -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" " --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" " --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" " --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 ipfrag1 disorder disorder2 split split2 ipfrag2\n" " --dpi-desync=[<mode0>,]<mode>[,<mode2>] ; try to desync dpi state. modes : synack fake fakeknown rst rstack hopbyhop destopt ipfrag1 disorder disorder2 split split2 ipfrag2 udplen\n"
#ifdef __linux__ #ifdef __linux__
" --dpi-desync-fwmark=<int|0xHEX>\t; override fwmark for desync packet. default = 0x%08X (%u)\n" " --dpi-desync-fwmark=<int|0xHEX>\t; override fwmark for desync packet. default = 0x%08X (%u)\n"
#elif defined(SO_USER_COOKIE) #elif defined(SO_USER_COOKIE)
@ -530,6 +530,7 @@ static void exithelp()
" --dpi-desync-fake-unknown=<filename>\t; file containing unknown protocol fake payload\n" " --dpi-desync-fake-unknown=<filename>\t; file containing unknown protocol fake payload\n"
" --dpi-desync-fake-quic=<filename>\t; file containing fake QUIC Initial\n" " --dpi-desync-fake-quic=<filename>\t; file containing fake QUIC Initial\n"
" --dpi-desync-fake-unknown-udp=<filename> ; file containing unknown udp protocol fake payload\n" " --dpi-desync-fake-unknown-udp=<filename> ; file containing unknown udp protocol fake payload\n"
" --dpi-desync-udplen-increment=<int>\t; increase udp packet length by N bytes (default %u)\n"
" --dpi-desync-cutoff=[n|d|s]N\t\t; apply dpi desync only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N\n" " --dpi-desync-cutoff=[n|d|s]N\t\t; apply dpi desync only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N\n"
" --hostlist=<filename>\t\t\t; apply dpi desync only to the listed hosts (one host per line, subdomains auto apply)\n", " --hostlist=<filename>\t\t\t; apply dpi desync only to the listed hosts (one host per line, subdomains auto apply)\n",
CTRACK_T_SYN, CTRACK_T_EST, CTRACK_T_FIN, CTRACK_T_UDP, CTRACK_T_SYN, CTRACK_T_EST, CTRACK_T_FIN, CTRACK_T_UDP,
@ -539,7 +540,8 @@ static void exithelp()
DPI_DESYNC_MAX_FAKE_LEN, DPI_DESYNC_MAX_FAKE_LEN,
DPI_DESYNC_MAX_FAKE_LEN, IPFRAG_UDP_DEFAULT, DPI_DESYNC_MAX_FAKE_LEN, IPFRAG_UDP_DEFAULT,
DPI_DESYNC_MAX_FAKE_LEN, IPFRAG_TCP_DEFAULT, DPI_DESYNC_MAX_FAKE_LEN, IPFRAG_TCP_DEFAULT,
BADSEQ_INCREMENT_DEFAULT, BADSEQ_ACK_INCREMENT_DEFAULT BADSEQ_INCREMENT_DEFAULT, BADSEQ_ACK_INCREMENT_DEFAULT,
UDPLEN_INCREMENT_DEFAULT
); );
exit(1); exit(1);
} }
@ -627,6 +629,7 @@ int main(int argc, char **argv)
params.desync_badseq_increment = BADSEQ_INCREMENT_DEFAULT; params.desync_badseq_increment = BADSEQ_INCREMENT_DEFAULT;
params.desync_badseq_ack_increment = BADSEQ_ACK_INCREMENT_DEFAULT; params.desync_badseq_ack_increment = BADSEQ_ACK_INCREMENT_DEFAULT;
params.wssize_cutoff_mode = params.desync_cutoff_mode = 'n'; // packet number by default params.wssize_cutoff_mode = params.desync_cutoff_mode = 'n'; // packet number by default
params.udplen_increment = UDPLEN_INCREMENT_DEFAULT;
if (can_drop_root()) // are we root ? if (can_drop_root()) // are we root ?
{ {
@ -680,8 +683,9 @@ int main(int argc, char **argv)
{"dpi-desync-fake-unknown",required_argument,0,0},// optidx=30 {"dpi-desync-fake-unknown",required_argument,0,0},// optidx=30
{"dpi-desync-fake-quic",required_argument,0,0},// optidx=31 {"dpi-desync-fake-quic",required_argument,0,0},// optidx=31
{"dpi-desync-fake-unknown-udp",required_argument,0,0},// optidx=32 {"dpi-desync-fake-unknown-udp",required_argument,0,0},// optidx=32
{"dpi-desync-cutoff",required_argument,0,0},// optidx=33 {"dpi-desync-udplen-increment",required_argument,0,0},// optidx=33
{"hostlist",required_argument,0,0}, // optidx=34 {"dpi-desync-cutoff",required_argument,0,0},// optidx=34
{"hostlist",required_argument,0,0}, // optidx=35
{NULL,0,NULL,0} {NULL,0,NULL,0}
}; };
if (argc < 2) exithelp(); if (argc < 2) exithelp();
@ -966,14 +970,17 @@ int main(int argc, char **argv)
params.fake_unknown_udp_size = sizeof(params.fake_unknown_udp); params.fake_unknown_udp_size = sizeof(params.fake_unknown_udp);
load_file_or_exit(optarg,params.fake_unknown_udp,&params.fake_unknown_udp_size); load_file_or_exit(optarg,params.fake_unknown_udp,&params.fake_unknown_udp_size);
break; break;
case 33: /* desync-cutoff */ case 33: /* dpi-desync-udplen-increment */
params.udplen_increment = (uint16_t)atoi(optarg);
break;
case 34: /* desync-cutoff */
if (!parse_cutoff(optarg, &params.desync_cutoff, &params.desync_cutoff_mode)) if (!parse_cutoff(optarg, &params.desync_cutoff, &params.desync_cutoff_mode))
{ {
fprintf(stderr, "invalid desync-cutoff value\n"); fprintf(stderr, "invalid desync-cutoff value\n");
exit_clean(1); exit_clean(1);
} }
break; break;
case 34: /* hostlist */ case 35: /* hostlist */
if (!LoadHostList(&params.hostlist, optarg)) if (!LoadHostList(&params.hostlist, optarg))
exit_clean(1); exit_clean(1);
strncpy(params.hostfile,optarg,sizeof(params.hostfile)); strncpy(params.hostfile,optarg,sizeof(params.hostfile));

3
nfq/params.h

@ -23,6 +23,8 @@
#define IPFRAG_UDP_DEFAULT 8 #define IPFRAG_UDP_DEFAULT 8
#define IPFRAG_TCP_DEFAULT 32 #define IPFRAG_TCP_DEFAULT 32
#define UDPLEN_INCREMENT_DEFAULT 2
struct params_s struct params_s
{ {
bool debug; bool debug;
@ -50,6 +52,7 @@ struct params_s
strpool *hostlist; strpool *hostlist;
uint8_t fake_http[1432],fake_tls[1432],fake_unknown[1432],fake_unknown_udp[1472],fake_quic[1472]; uint8_t fake_http[1432],fake_tls[1432],fake_unknown[1432],fake_unknown_udp[1472],fake_quic[1472];
size_t fake_http_size,fake_tls_size,fake_unknown_size,fake_unknown_udp_size,fake_quic_size; size_t fake_http_size,fake_tls_size,fake_unknown_size,fake_unknown_udp_size,fake_quic_size;
uint16_t udplen_increment;
bool droproot; bool droproot;
uid_t uid; uid_t uid;
gid_t gid; gid_t gid;

Loading…
Cancel
Save