Browse Source

Revert "nfqws: separate 4,6 sockets, new dpi fooling modes"

This reverts commit 0d8ffde17a.
pull/53/head
bol-van 5 years ago
parent
commit
2595d0ebd0
  1. BIN
      binaries/aarch64/nfqws
  2. BIN
      binaries/armhf/nfqws
  3. BIN
      binaries/mips32r1-lsb/nfqws
  4. BIN
      binaries/mips32r1-msb/nfqws
  5. BIN
      binaries/mips64r2-msb/nfqws
  6. BIN
      binaries/ppc/nfqws
  7. BIN
      binaries/x86/nfqws
  8. BIN
      binaries/x86_64/nfqws
  9. 5
      docs/readme.eng.txt
  10. 7
      docs/readme.txt
  11. 146
      nfq/darkmagic.c
  12. 22
      nfq/darkmagic.h
  13. 46
      nfq/nfqws.c

BIN
binaries/aarch64/nfqws

Binary file not shown.

BIN
binaries/armhf/nfqws

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.

5
docs/readme.eng.txt

@ -142,7 +142,7 @@ It takes the following parameters:
--dpi-desync[=<mode>] ; try to desync dpi state. modes : fake rst rstack disorder disorder2
--dpi-desync-fwmark=<int|0xHEX> ; override fwmark for desync packet. default = 0x40000000
--dpi-desync-ttl=<int> ; set ttl for desync packet
--dpi-desync-fooling=none|md5sig|ts|badseq|badsum ; can take multiple comma separated values
--dpi-desync-fooling=none|md5sig|badsum
--dpi-desync-retrans=0|1 ; (fake,rst,rstack only) 0(default)=reinject original data packet after fake 1=drop original data packet to force its retransmission
--dpi-desync-skip-nosni=0|1 ; 1(default)=do not apply desync to requests without hostname in the SNI
--dpi-desync-split-pos=<1..1500> ; (for disorder only) split TCP packet at specified position
@ -174,14 +174,11 @@ add tcp option "MD5 signature". All of them have their own disadvantages :
If nfqws is on the router, its not neccessary to switch of "net.netfilter.nf_conntrack_checksum".
Fake packet doesn't go through FORWARD chain, it goes through OUTPUT. But if your router is behind another NAT, for example ISP NAT,
and that NAT does not pass invalid packets, you cant do anything.
* badseq packets will be dropped by server, but DPI also can ignore them
* TTL looks like the best option, but it requires special tuning for earch ISP. If DPI is further than local ISP websites
you can cut access to them. Manual IP exclude list is required. Its possible to use md5sig with ttl.
This way you cant hurt anything, but good chances it will help to open local ISP websites.
If automatic solution cannot be found then use zapret-hosts-user-exclude.txt.
--dpi-desync-fooling takes multiple comma separated values.
For fake,rst,rstack modes original packet can be sent after the fake one or just dropped.
If its dropped OS will perform first retransmission after 0.2 sec, then the delay increases exponentially.
Delay can help to make sure fake and original packets are properly ordered and processed on DPI.

7
docs/readme.txt

@ -170,7 +170,7 @@ nfqws
--dpi-desync[=<mode>] ; атака по десинхронизации DPI. mode : fake rst rstack disorder disorder2
--dpi-desync-fwmark=<int|0xHEX> ; бит fwmark для пометки десинхронизирующих пакетов, чтобы они повторно не падали в очередь. default = 0x40000000
--dpi-desync-ttl=<int> ; установить ttl для десинхронизирующих пакетов
--dpi-desync-fooling=none|md5sig|ts|badseq|badsum ; дополнительные методики как сделать, чтобы фейковый пакет не дошел до сервера
--dpi-desync-fooling=none|md5sig|badsum ; дополнительные методики как сделать, чтобы десинхронизирующий пакет не дошел до сервера
--dpi-desync-retrans=0|1 ; (только для fake,rst,rstack) 0(default)=отправлять оригинал следом за фейком 1=дропать оригинал, заставляя ОС выполнять ретрансмиссию через 0.2 сек
--dpi-desync-skip-nosni=0|1 ; 1(default)=не применять dpi desync для запросов без hostname в SNI, в частности для ESNI
--dpi-desync-split-pos=<1..1500> ; (только для disorder) разбивать пакет на указанной позиции
@ -194,7 +194,7 @@ nfqws
В литературе такие атаки еще называют TCB desynchronization и TCB teardown.
Надо, чтобы фейковые пакеты дошли до DPI, но не дошли до сервера.
На вооружении есть следующие возможности : установить низкий TTL, посылать пакет с инвалидной чексуммой,
добавлять tcp option "MD5 signature", испортить sequence numbers. Все они не лишены недостатков.
добавлять tcp option "MD5 signature". Все они не лишены недостатков.
* md5sig работает не на всех серверах. Пакеты с md5 обычно отбрасывают только linux.
* badsum не сработает, если ваше устройство за NAT, который не пропускает пакеты с инвалидной суммой.
@ -202,15 +202,12 @@ nfqws
В openwrt она сделана из коробки, в других роутерах как правило нет, и не всегда это можно изменить.
Если nfqws работает на роутере, то не обязательно выключать nf_conntrack_checksum. Фейковый пакет не проходит FORWARD, он идет через OUTPUT.
Но если роутер за другим NAT, например провайдерским, и он не пропускает invalid packets, вы ничего не сможете с этим сделать.
* пакеты с badseq будут наверняка отброшены принимающим узлом, но так же и DPI, если он ориентируется на sequence numbers
* TTL казалось бы - лучший вариант, но он требует индивидуальной настройки под каждого провайдера. Если DPI находится дальше локальных
сайтов провайдера, то вы можете отрезать себе доступ к ним. Необходим ip exclude list, заполняемый вручную.
Вместе с ttl можно применять md5sig. Это ничего не испортит, зато дает неплохой шанс работы сайтов, до которых "плохой" пакет дойдет по TTL.
Если не удается найти автоматическое решение, воспользуйтесь файлом zapret-hosts-user-exclude.txt.
КАКИМ СТОИТ ВЫБИРАТЬ TTL : найдите минимальное значение, при котором обход еще работает. Это и будет номер хопа вашего DPI.
Режимы дурения могут сочетаться в любых комбинациях. --dpi-desync-fooling берет множество значений через запятую.
Для режимов fake, rst, rstack после фейка отправляем оригинальный пакет. Можно его отправить сразу следом за фейком, а можно его просто дропнуть.
Если его дропнуть, ОС выполнит ретрансмиссию. Первая ретрансмиссия случается через 0.2 сек, потом задержка увеличивается экспоненциально.
Задержка может дать надежную гарантию, что пакеты пойдут именно в нужном порядке и будут именно в нем обработаны на DPI.

146
nfq/darkmagic.c

@ -10,138 +10,65 @@ uint32_t net32_add(uint32_t netorder_value, uint32_t cpuorder_increment)
return htonl(ntohl(netorder_value)+cpuorder_increment);
}
uint8_t *tcp_find_option(struct tcphdr *tcp, uint8_t kind)
{
char *t = (char*)(tcp+1);
char *end = (char*)tcp + (tcp->doff<<2);
while(t<end)
{
switch(*t)
{
case 0: // end
break;
case 1: // noop
t++;
break;
default: // kind,len,data
if ((t+1)>=end || (t+t[1])>end)
break;
if (*t==kind)
return t;
t+=t[1];
break;
}
}
return NULL;
}
uint32_t *tcp_find_timestamps(struct tcphdr *tcp)
{
uint8_t *t = tcp_find_option(tcp,8);
return (t && t[1]==10) ? (uint32_t*)(t+2) : NULL;
}
static void fill_tcphdr(struct tcphdr *tcp, uint8_t tcp_flags, uint32_t seq, uint32_t ack_seq, uint8_t fooling, uint16_t nsport, uint16_t ndport, uint16_t nwsize, uint32_t *timestamps)
static void fill_tcphdr(struct tcphdr *tcp, uint8_t tcp_flags, uint32_t seq, uint32_t ack_seq, enum tcp_fooling_mode fooling, uint16_t nsport, uint16_t ndport, uint16_t nwsize)
{
char *tcpopt = (char*)(tcp+1);
uint8_t t=0;
memset(tcp,0,sizeof(*tcp));
tcp->source = nsport;
tcp->dest = ndport;
if (fooling & TCP_FOOL_BADSEQ)
{
tcp->seq = net32_add(seq,0x80000000);
tcp->ack_seq = net32_add(ack_seq,0x80000000);
}
else
{
tcp->seq = seq;
tcp->ack_seq = ack_seq;
}
tcp->seq = seq;
tcp->ack_seq = ack_seq;
tcp->doff = 5;
*((uint8_t*)tcp+13)= tcp_flags;
tcp->window = nwsize;
if (fooling & TCP_FOOL_MD5SIG)
if (fooling==TCP_FOOL_MD5SIG)
{
tcp->doff += 5; // +20 bytes
tcpopt[0] = 19; // kind
tcpopt[1] = 18; // len
*(uint32_t*)(tcpopt+2)=random();
*(uint32_t*)(tcpopt+6)=random();
*(uint32_t*)(tcpopt+10)=random();
*(uint32_t*)(tcpopt+14)=random();
t=18;
}
if (timestamps || (fooling & TCP_FOOL_TS))
{
tcpopt[t] = 8; // kind
tcpopt[t+1] = 10; // len
// forge only TSecr if orig timestamp is present
*(uint32_t*)(tcpopt+t+2) = timestamps ? timestamps[0] : -1;
*(uint32_t*)(tcpopt+t+6) = (timestamps && !(fooling & TCP_FOOL_TS)) ? timestamps[1] : -1;
t+=10;
tcpopt[18] = 0; // end
tcpopt[19] = 0;
}
while (t&3) tcpopt[t++]=1; // noop
tcp->doff += t>>2;
}
static uint16_t tcpopt_len(uint8_t fooling, uint32_t *timestamps)
{
uint16_t t=0;
if (fooling & TCP_FOOL_MD5SIG) t=18;
if ((fooling & TCP_FOOL_TS) || timestamps) t+=10;
return (t+3)&~3;
}
static int rawsend_sock4=-1, rawsend_sock6=-1;
static void rawsend_clean_sock(int *sock)
{
if (sock && *sock!=-1)
{
close(*sock);
*sock=-1;
}
}
static int rawsend_sock=-1;
void rawsend_cleanup()
{
rawsend_clean_sock(&rawsend_sock4);
rawsend_clean_sock(&rawsend_sock6);
}
static int *rawsend_family_sock(int family)
{
switch(family)
if (rawsend_sock!=-1)
{
case AF_INET: return &rawsend_sock4;
case AF_INET6: return &rawsend_sock6;
default: return NULL;
close(rawsend_sock);
rawsend_sock=-1;
}
}
static int rawsend_socket(int family,uint32_t fwmark)
static void rawsend_socket(int family,uint32_t fwmark)
{
int *sock = rawsend_family_sock(family);
if (!sock) return -1;
if (*sock==-1)
if (rawsend_sock==-1)
{
int yes=1,pri=6;
*sock = socket(family, SOCK_RAW, IPPROTO_RAW);
if (*sock==-1)
rawsend_sock = socket(family, SOCK_RAW, IPPROTO_RAW);
if (rawsend_sock==-1)
perror("rawsend: socket()");
else if (setsockopt(*sock, SOL_SOCKET, SO_MARK, &fwmark, sizeof(fwmark)) == -1)
else if (setsockopt(rawsend_sock, SOL_SOCKET, SO_MARK, &fwmark, sizeof(fwmark)) == -1)
{
perror("rawsend: setsockopt(SO_MARK)");
rawsend_clean_sock(sock);
rawsend_cleanup();
}
else if (setsockopt(*sock, SOL_SOCKET, SO_PRIORITY, &pri, sizeof(pri)) == -1)
else if (setsockopt(rawsend_sock, SOL_SOCKET, SO_PRIORITY, &pri, sizeof(pri)) == -1)
{
perror("rawsend: setsockopt(SO_PRIORITY)");
rawsend_clean_sock(sock);
rawsend_cleanup();
}
}
return *sock;
}
bool rawsend(struct sockaddr* dst,uint32_t fwmark,const void *data,size_t len)
{
int sock=rawsend_socket(dst->sa_family,fwmark);
if (sock==-1) return false;
rawsend_socket(dst->sa_family,fwmark);
if (rawsend_sock==-1) return false;
int salen = dst->sa_family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
struct sockaddr_storage dst2;
@ -149,7 +76,7 @@ bool rawsend(struct sockaddr* dst,uint32_t fwmark,const void *data,size_t len)
if (dst->sa_family==AF_INET6)
((struct sockaddr_in6 *)&dst2)->sin6_port = 0; // or will be EINVAL
int bytes = sendto(sock, data, len, 0, (struct sockaddr*)&dst2, salen);
int bytes = sendto(rawsend_sock, data, len, 0, (struct sockaddr*)&dst2, salen);
if (bytes==-1)
{
perror("rawsend: sendto");
@ -162,14 +89,14 @@ bool prepare_tcp_segment4(
uint8_t tcp_flags,
uint32_t seq, uint32_t ack_seq,
uint16_t wsize,
uint32_t *timestamps,
uint8_t ttl,
uint8_t fooling,
enum tcp_fooling_mode fooling,
const void *data, uint16_t len,
char *buf, size_t *buflen)
{
uint16_t tcpoptlen = tcpopt_len(fooling,timestamps);
uint16_t pktlen = sizeof(struct iphdr) + sizeof(struct tcphdr) + tcpoptlen + len;
uint16_t tcpoptlen = 0;
if (fooling==TCP_FOOL_MD5SIG) tcpoptlen=20;
uint16_t pktlen = sizeof(struct iphdr) + sizeof(struct tcphdr) + tcpoptlen + len;
if (pktlen>*buflen)
{
fprintf(stderr,"prepare_tcp_segment : packet len cannot exceed %zu\n",*buflen);
@ -189,11 +116,11 @@ bool prepare_tcp_segment4(
ip->saddr = src->sin_addr.s_addr;
ip->daddr = dst->sin_addr.s_addr;
fill_tcphdr(tcp,tcp_flags,seq,ack_seq,fooling,src->sin_port,dst->sin_port,wsize,timestamps);
fill_tcphdr(tcp,tcp_flags,seq,ack_seq,fooling,src->sin_port,dst->sin_port,wsize);
memcpy((char*)tcp+sizeof(struct tcphdr)+tcpoptlen,data,len);
tcp_fix_checksum(tcp,sizeof(struct tcphdr)+tcpoptlen+len,ip->saddr,ip->daddr);
if (fooling & TCP_FOOL_BADSUM) tcp->check^=0xBEAF;
if (fooling==TCP_FOOL_BADSUM) tcp->check^=0xBEAF;
*buflen = pktlen;
return true;
@ -205,13 +132,13 @@ bool prepare_tcp_segment6(
uint8_t tcp_flags,
uint32_t seq, uint32_t ack_seq,
uint16_t wsize,
uint32_t *timestamps,
uint8_t ttl,
uint8_t fooling,
enum tcp_fooling_mode fooling,
const void *data, uint16_t len,
char *buf, size_t *buflen)
{
uint16_t tcpoptlen = tcpopt_len(fooling,timestamps);
uint16_t tcpoptlen = 0;
if (fooling==TCP_FOOL_MD5SIG) tcpoptlen=20;
uint16_t payloadlen = sizeof(struct tcphdr) + tcpoptlen + len;
uint16_t pktlen = sizeof(struct ip6_hdr) + payloadlen;
if (pktlen>*buflen)
@ -230,11 +157,11 @@ bool prepare_tcp_segment6(
ip6->ip6_src = src->sin6_addr;
ip6->ip6_dst = dst->sin6_addr;
fill_tcphdr(tcp,tcp_flags,seq,ack_seq,fooling,src->sin6_port,dst->sin6_port,wsize,timestamps);
fill_tcphdr(tcp,tcp_flags,seq,ack_seq,fooling,src->sin6_port,dst->sin6_port,wsize);
memcpy((char*)tcp+sizeof(struct tcphdr)+tcpoptlen,data,len);
tcp6_fix_checksum(tcp,sizeof(struct tcphdr)+tcpoptlen+len,&ip6->ip6_src,&ip6->ip6_dst);
if (fooling & TCP_FOOL_BADSUM) tcp->check^=0xBEAF;
if (fooling==TCP_FOOL_BADSUM) tcp->check^=0xBEAF;
*buflen = pktlen;
return true;
@ -245,16 +172,15 @@ bool prepare_tcp_segment(
uint8_t tcp_flags,
uint32_t seq, uint32_t ack_seq,
uint16_t wsize,
uint32_t *timestamps,
uint8_t ttl,
uint8_t fooling,
enum tcp_fooling_mode fooling,
const void *data, uint16_t len,
char *buf, size_t *buflen)
{
return (src->sa_family==AF_INET && dst->sa_family==AF_INET) ?
prepare_tcp_segment4((struct sockaddr_in *)src,(struct sockaddr_in *)dst,tcp_flags,seq,ack_seq,wsize,timestamps,ttl,fooling,data,len,buf,buflen) :
prepare_tcp_segment4((struct sockaddr_in *)src,(struct sockaddr_in *)dst,tcp_flags,seq,ack_seq,wsize,ttl,fooling,data,len,buf,buflen) :
(src->sa_family==AF_INET6 && dst->sa_family==AF_INET6) ?
prepare_tcp_segment6((struct sockaddr_in6 *)src,(struct sockaddr_in6 *)dst,tcp_flags,seq,ack_seq,wsize,timestamps,ttl,fooling,data,len,buf,buflen) :
prepare_tcp_segment6((struct sockaddr_in6 *)src,(struct sockaddr_in6 *)dst,tcp_flags,seq,ack_seq,wsize,ttl,fooling,data,len,buf,buflen) :
false;
}

22
nfq/darkmagic.h

@ -12,21 +12,19 @@
// returns netorder value
uint32_t net32_add(uint32_t netorder_value, uint32_t cpuorder_increment);
#define TCP_FOOL_NONE 0
#define TCP_FOOL_MD5SIG 1
#define TCP_FOOL_BADSUM 2
#define TCP_FOOL_TS 4
#define TCP_FOOL_BADSEQ 8
enum tcp_fooling_mode {
TCP_FOOL_NONE=0,
TCP_FOOL_MD5SIG=1,
TCP_FOOL_BADSUM=2
};
// seq and wsize have network byte order
bool prepare_tcp_segment4(
const struct sockaddr_in *src, const struct sockaddr_in *dst,
uint8_t tcp_flags,
uint32_t seq, uint32_t ack_seq,
uint16_t wsize,
uint32_t *timestamps,
uint8_t ttl,
uint8_t fooling,
enum tcp_fooling_mode fooling,
const void *data, uint16_t len,
char *buf, size_t *buflen);
bool prepare_tcp_segment6(
@ -34,9 +32,8 @@ bool prepare_tcp_segment6(
uint8_t tcp_flags,
uint32_t seq, uint32_t ack_seq,
uint16_t wsize,
uint32_t *timestamps,
uint8_t ttl,
uint8_t fooling,
enum tcp_fooling_mode fooling,
const void *data, uint16_t len,
char *buf, size_t *buflen);
bool prepare_tcp_segment(
@ -44,15 +41,12 @@ bool prepare_tcp_segment(
uint8_t tcp_flags,
uint32_t seq, uint32_t ack_seq,
uint16_t wsize,
uint32_t *timestamps,
uint8_t ttl,
uint8_t fooling,
enum tcp_fooling_mode fooling,
const void *data, uint16_t len,
char *buf, size_t *buflen);
void extract_endpoints(const struct iphdr *iphdr,const struct ip6_hdr *ip6hdr,const struct tcphdr *tcphdr, struct sockaddr_storage *src, struct sockaddr_storage *dst);
uint8_t *tcp_find_option(struct tcphdr *tcp, uint8_t kind);
uint32_t *tcp_find_timestamps(struct tcphdr *tcp);
// auto creates internal socket and uses it for subsequent calls
bool rawsend(struct sockaddr* dst,uint32_t fwmark,const void *data,size_t len);

46
nfq/nfqws.c

@ -91,7 +91,7 @@ struct params_s
bool desync_retrans,desync_skip_nosni,desync_any_proto;
int desync_split_pos;
uint8_t desync_ttl;
uint8_t desync_tcp_fooling_mode;
enum tcp_fooling_mode desync_tcp_fooling_mode;
uint32_t desync_fwmark;
char hostfile[256];
strpool *hostlist;
@ -467,7 +467,7 @@ static bool modify_tcp_packet(uint8_t *data, size_t len, struct tcphdr *tcphdr)
// result : true - drop original packet, false = dont drop
static bool dpi_desync_packet(const uint8_t *data_pkt, size_t len_pkt, struct iphdr *iphdr, struct ip6_hdr *ip6hdr, struct tcphdr *tcphdr, uint8_t *data_payload, size_t len_payload)
static bool dpi_desync_packet(const uint8_t *data_pkt, size_t len_pkt, const struct iphdr *iphdr, const struct ip6_hdr *ip6hdr, const struct tcphdr *tcphdr, const uint8_t *data_payload, size_t len_payload)
{
if (!!iphdr == !!ip6hdr) return false; // one and only one must be present
@ -535,12 +535,11 @@ static bool dpi_desync_packet(const uint8_t *data_pkt, size_t len_pkt, struct ip
uint8_t ttl_orig = iphdr ? iphdr->ttl : ip6hdr->ip6_ctlun.ip6_un1.ip6_un1_hlim;
uint8_t ttl_fake = params.desync_ttl ? params.desync_ttl : ttl_orig;
uint8_t flags_orig = *((uint8_t*)tcphdr+13);
uint32_t *timestamps = tcp_find_timestamps(tcphdr);
switch(params.desync_mode)
{
case DESYNC_FAKE:
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->seq, tcphdr->ack_seq, tcphdr->window, timestamps,
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->seq, tcphdr->ack_seq, tcphdr->window,
ttl_fake,params.desync_tcp_fooling_mode,
fake, fake_size, newdata, &newlen))
{
@ -549,7 +548,7 @@ static bool dpi_desync_packet(const uint8_t *data_pkt, size_t len_pkt, struct ip
break;
case DESYNC_RST:
case DESYNC_RSTACK:
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, TH_RST | (params.desync_mode==DESYNC_RSTACK ? TH_ACK:0), tcphdr->seq, tcphdr->ack_seq, tcphdr->window, timestamps,
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, TH_RST | (params.desync_mode==DESYNC_RSTACK ? TH_ACK:0), tcphdr->seq, tcphdr->ack_seq, tcphdr->window,
ttl_fake,params.desync_tcp_fooling_mode,
NULL, 0, newdata, &newlen))
{
@ -566,7 +565,7 @@ static bool dpi_desync_packet(const uint8_t *data_pkt, size_t len_pkt, struct ip
if (split_pos<len_payload)
{
DLOG("sending 2nd out-of-order tcp segment %zu-%zu len=%zu\n",split_pos,len_payload-1, len_payload-split_pos)
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, net32_add(tcphdr->seq,split_pos), tcphdr->ack_seq, tcphdr->window, timestamps,
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, net32_add(tcphdr->seq,split_pos), tcphdr->ack_seq, tcphdr->window,
ttl_orig,TCP_FOOL_NONE,
data_payload+split_pos, len_payload-split_pos, newdata, &newlen) ||
!rawsend((struct sockaddr *)&dst, params.desync_fwmark, newdata, newlen))
@ -580,7 +579,7 @@ static bool dpi_desync_packet(const uint8_t *data_pkt, size_t len_pkt, struct ip
{
DLOG("sending fake(1) 1st out-of-order tcp segment 0-%zu len=%zu\n",split_pos-1, split_pos)
fakeseg_len = sizeof(fakeseg);
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->seq, tcphdr->ack_seq, tcphdr->window, timestamps,
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->seq, tcphdr->ack_seq, tcphdr->window,
ttl_fake,params.desync_tcp_fooling_mode,
zeropkt, split_pos, fakeseg, &fakeseg_len) ||
!rawsend((struct sockaddr *)&dst, params.desync_fwmark, fakeseg, fakeseg_len))
@ -592,7 +591,7 @@ static bool dpi_desync_packet(const uint8_t *data_pkt, size_t len_pkt, struct ip
DLOG("sending 1st out-of-order tcp segment 0-%zu len=%zu\n",split_pos-1, split_pos)
newlen = sizeof(newdata);
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->seq, tcphdr->ack_seq, tcphdr->window, timestamps,
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->seq, tcphdr->ack_seq, tcphdr->window,
ttl_orig,TCP_FOOL_NONE,
data_payload, split_pos, newdata, &newlen) ||
!rawsend((struct sockaddr *)&dst, params.desync_fwmark, newdata, newlen))
@ -735,7 +734,7 @@ static void exithelp()
" --dpi-desync[=<mode>]\t\t\t; try to desync dpi state. modes : fake rst rstack disorder disorder2\n"
" --dpi-desync-fwmark=<int|0xHEX>\t; override fwmark for desync packet. default = 0x%08X\n"
" --dpi-desync-ttl=<int>\t\t\t; set ttl for desync packet\n"
" --dpi-desync-fooling=none|md5sig|ts|badseq|badsum\t; can use multiple comma separated values\n"
" --dpi-desync-fooling=none|md5sig|badsum\n"
" --dpi-desync-retrans=0|1\t\t; 0(default)=reinject original data packet after fake 1=drop original data packet to force its retransmission\n"
" --dpi-desync-skip-nosni=0|1\t\t; 1(default)=do not act on ClientHello without SNI (ESNI ?)\n"
" --dpi-desync-split-pos=<1..%zu>\t; (for disorder only) split TCP packet at specified position\n"
@ -912,27 +911,16 @@ int main(int argc, char **argv)
params.desync_ttl = (uint8_t)atoi(optarg);
break;
case 13: /* dpi-desync-fooling */
if (!strcmp(optarg,"none"))
params.desync_tcp_fooling_mode = TCP_FOOL_NONE;
else if (!strcmp(optarg,"md5sig"))
params.desync_tcp_fooling_mode = TCP_FOOL_MD5SIG;
else if (!strcmp(optarg,"badsum"))
params.desync_tcp_fooling_mode = TCP_FOOL_BADSUM;
else
{
char *e,*p = optarg;
while (p)
{
e = strchr(p,',');
if (e) *e++=0;
if (!strcmp(p,"md5sig"))
params.desync_tcp_fooling_mode |= TCP_FOOL_MD5SIG;
else if (!strcmp(p,"ts"))
params.desync_tcp_fooling_mode |= TCP_FOOL_TS;
else if (!strcmp(p,"badsum"))
params.desync_tcp_fooling_mode |= TCP_FOOL_BADSUM;
else if (!strcmp(p,"badseq"))
params.desync_tcp_fooling_mode |= TCP_FOOL_BADSEQ;
else if (strcmp(p,"none"))
{
fprintf(stderr, "dpi-desync-fooling allowed values : none,md5sig,ts,badseq,badsum\n");
exit_clean(1);
}
p = e;
}
fprintf(stderr, "dpi-desync-fooling allowed values : none,md5sig,badsum\n");
exit_clean(1);
}
break;
case 14: /* dpi-desync-retrans */

Loading…
Cancel
Save