mirror of
https://github.com/bol-van/zapret.git
synced 2024-11-30 05:50:53 +03:00
nfqws: hop-by-hop ipv6 fooling and desync
This commit is contained in:
parent
2c1871cc44
commit
427f16776c
@ -543,7 +543,7 @@ pktws_check_domain_bypass()
|
|||||||
# $2 - encrypted test : 1/0
|
# $2 - encrypted test : 1/0
|
||||||
# $3 - domain
|
# $3 - domain
|
||||||
|
|
||||||
local strategy tests='fake' ttls s e desync pos fooling frag sec="$2"
|
local strategy tests='fake' ttls s f e desync pos fooling frag sec="$2"
|
||||||
|
|
||||||
[ "$sec" = 0 ] && {
|
[ "$sec" = 0 ] && {
|
||||||
for s in '--hostcase' '--hostspell=hoSt' '--hostnospace' '--domcase'; do
|
for s in '--hostcase' '--hostspell=hoSt' '--hostnospace' '--domcase'; do
|
||||||
@ -575,12 +575,15 @@ pktws_check_domain_bypass()
|
|||||||
pktws_curl_test_update $1 $3 --dpi-desync=$desync $e
|
pktws_curl_test_update $1 $3 --dpi-desync=$desync $e
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
[ "$IPV" = 6 ] && pktws_curl_test_update $1 $3 $e --dpi-desync=hopbyhop
|
||||||
for desync in $tests; do
|
for desync in $tests; do
|
||||||
s="--dpi-desync=$desync"
|
s="--dpi-desync=$desync"
|
||||||
for ttl in $ttls; do
|
for ttl in $ttls; do
|
||||||
pktws_curl_test_update $1 $3 $s --dpi-desync-ttl=$ttl $e && break
|
pktws_curl_test_update $1 $3 $s --dpi-desync-ttl=$ttl $e && break
|
||||||
done
|
done
|
||||||
for fooling in badsum badseq md5sig; do
|
f="badsum badseq md5sig"
|
||||||
|
[ "$IPV" = 6 ] && f="$f hopbyhop hopbyhop2"
|
||||||
|
for fooling in $f; do
|
||||||
pktws_curl_test_update $1 $3 $s --dpi-desync-fooling=$fooling $e && [ "$fooling" = "md5sig" ] &&
|
pktws_curl_test_update $1 $3 $s --dpi-desync-fooling=$fooling $e && [ "$fooling" = "md5sig" ] &&
|
||||||
echo 'WARNING ! although md5sig fooling worked it will not work on all sites. it typically works only on linux servers.'
|
echo 'WARNING ! although md5sig fooling worked it will not work on all sites. it typically works only on linux servers.'
|
||||||
done
|
done
|
||||||
|
@ -214,3 +214,7 @@ nfqws: UDP desync with conntrack support (any-protocol only for now)
|
|||||||
v44
|
v44
|
||||||
|
|
||||||
nfqws: ipfrag
|
nfqws: ipfrag
|
||||||
|
|
||||||
|
v45
|
||||||
|
|
||||||
|
nfqws: hop-by-hop ipv6 desync and fooling
|
||||||
|
@ -139,11 +139,11 @@ nfqws takes the following parameters:
|
|||||||
--pidfile=<filename> ; write pid to file
|
--pidfile=<filename> ; write pid to file
|
||||||
--user=<username> ; drop root privs
|
--user=<username> ; drop root privs
|
||||||
--uid=uid[:gid] ; drop root privs
|
--uid=uid[:gid] ; drop root privs
|
||||||
--dpi-desync=[<mode0,]<mode>[,<mode2>] ; desync dpi state. modes : synack fake rst rstack disorder disorder2 split split2 ipfrag2
|
--dpi-desync=[<mode0,]<mode>[,<mode2>] ; desync dpi state. modes : synack fake rst rstack hopbyhop disorder disorder2 split split2 ipfrag2
|
||||||
--dpi-desync-fwmark=<int|0xHEX> ; override fwmark for desync packet. default = 0x40000000
|
--dpi-desync-fwmark=<int|0xHEX> ; override fwmark for desync packet. default = 0x40000000
|
||||||
--dpi-desync-ttl=<int> ; set ttl for desync packet
|
--dpi-desync-ttl=<int> ; set ttl for desync packet
|
||||||
--dpi-desync-ttl6=<int> ; set ipv6 hop limit for desync packet. by default ttl value is used
|
--dpi-desync-ttl6=<int> ; set ipv6 hop limit for desync packet. by default ttl value is used
|
||||||
--dpi-desync-fooling=none|md5sig|ts|badseq|badsum ; can take multiple comma separated values
|
--dpi-desync-fooling=<fooling> ; can take multiple comma separated values : none md5sig badseq badsum hopbyhop hopbyhop2
|
||||||
--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-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-repeats=<N> ; send every desync packet N times
|
--dpi-desync-repeats=<N> ; send every desync packet N times
|
||||||
--dpi-desync-skip-nosni=0|1 ; 1(default)=do not apply desync to requests without hostname in the SNI
|
--dpi-desync-skip-nosni=0|1 ; 1(default)=do not apply desync to requests without hostname in the SNI
|
||||||
@ -201,7 +201,12 @@ add tcp option **MD5 signature**. All of them have their own disadvantages :
|
|||||||
This way you cant hurt anything, but good chances it will help to open local ISP websites.
|
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`.
|
If automatic solution cannot be found then use `zapret-hosts-user-exclude.txt`.
|
||||||
Some router stock firmwares fix outgoing TTL. Without switching this option off TTL fooling will not work.
|
Some router stock firmwares fix outgoing TTL. Without switching this option off TTL fooling will not work.
|
||||||
|
* `hopbyhop` is ipv6 only. This fooling adds empty extension header `hop-by-hop options` or two headers in case of `hopbyhop2`.
|
||||||
|
Packets with two hop-by-hop headers violate RFC and discarded by all operating systems.
|
||||||
|
All OS accept packets with one hop-by-hop header.
|
||||||
|
Some ISPs/operators drop ipv6 packets with hop-by-hop options. Fakes will not be processed by the server either because
|
||||||
|
ISP drops them or because there are two same headers.
|
||||||
|
DPIs may still anaylize packets with one or two hop-by-hop headers.
|
||||||
|
|
||||||
`--dpi-desync-fooling` takes multiple comma separated values.
|
`--dpi-desync-fooling` takes multiple comma separated values.
|
||||||
|
|
||||||
@ -234,6 +239,14 @@ Mode `split2` disables sending of fake segments. It can be used as a faster alte
|
|||||||
|
|
||||||
In `disorder2` and 'split2` modes no fake packets are sent, so ttl and fooling options are not required.
|
In `disorder2` and 'split2` modes no fake packets are sent, so ttl and fooling options are not required.
|
||||||
|
|
||||||
|
`hopbyhop` desync mode (it's not the same as `hopbyhop` fooling !) is ipv6 only. One hop-by-hop header
|
||||||
|
is added to all desynced packets.
|
||||||
|
Extra header increases packet size and can't be applied to the maximum size packets.
|
||||||
|
If it's not possible to send modified packet original one will be sent.
|
||||||
|
The idea here is that DPI sees 0 in the next header field of the main ipv6 header and does not
|
||||||
|
walk through the extension header chain until transport header is found.
|
||||||
|
`hopbyhop` mode cannot be used with second phase modes.
|
||||||
|
|
||||||
There are DPIs that analyze responses from the server, particularly the certificate from the ServerHello
|
There are DPIs that analyze responses from the server, particularly the certificate from the ServerHello
|
||||||
that contain domain name(s). The ClientHello delivery confirmation is an ACK packet from the server
|
that contain domain name(s). The ClientHello delivery confirmation is an ACK packet from the server
|
||||||
with ACK sequence number corresponding to the length of the ClientHello+1.
|
with ACK sequence number corresponding to the length of the ClientHello+1.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
zapret v.44
|
zapret v.45
|
||||||
|
|
||||||
English
|
English
|
||||||
-------
|
-------
|
||||||
@ -187,11 +187,11 @@ nfqws
|
|||||||
--hostnospace ; убрать пробел после "Host:" и переместить его в конец значения "User-Agent:" для сохранения длины пакета
|
--hostnospace ; убрать пробел после "Host:" и переместить его в конец значения "User-Agent:" для сохранения длины пакета
|
||||||
--hostspell=HoST ; точное написание заголовка Host (можно "HOST" или "HoSt"). автоматом включает --hostcase
|
--hostspell=HoST ; точное написание заголовка Host (можно "HOST" или "HoSt"). автоматом включает --hostcase
|
||||||
--domcase ; домен после Host: сделать таким : TeSt.cOm
|
--domcase ; домен после Host: сделать таким : TeSt.cOm
|
||||||
--dpi-desync=[<mode0>,]<mode>[,<mode2] ; атака по десинхронизации DPI. mode : synack fake rst rstack disorder disorder2 split split2 ipfrag2
|
--dpi-desync=[<mode0>,]<mode>[,<mode2] ; атака по десинхронизации DPI. mode : synack fake rst rstack hopbyhop disorder disorder2 split split2 ipfrag2
|
||||||
--dpi-desync-fwmark=<int|0xHEX> ; бит fwmark для пометки десинхронизирующих пакетов, чтобы они повторно не падали в очередь. default = 0x40000000
|
--dpi-desync-fwmark=<int|0xHEX> ; бит fwmark для пометки десинхронизирующих пакетов, чтобы они повторно не падали в очередь. default = 0x40000000
|
||||||
--dpi-desync-ttl=<int> ; установить ttl для десинхронизирующих пакетов
|
--dpi-desync-ttl=<int> ; установить ttl для десинхронизирующих пакетов
|
||||||
--dpi-desync-ttl6=<int> ; установить ipv6 hop limit для десинхронизирующих пакетов. если не указано, используется значение ttl
|
--dpi-desync-ttl6=<int> ; установить ipv6 hop limit для десинхронизирующих пакетов. если не указано, используется значение ttl
|
||||||
--dpi-desync-fooling=none|md5sig|ts|badseq|badsum ; дополнительные методики как сделать, чтобы фейковый пакет не дошел до сервера
|
--dpi-desync-fooling=<fooling> ; дополнительные методики как сделать, чтобы фейковый пакет не дошел до сервера. none md5sig badseq badsum hopbyhop hopbyhop2
|
||||||
--dpi-desync-retrans=0|1 ; (только для fake,rst,rstack) 0(default)=отправлять оригинал следом за фейком 1=дропать оригинал, заставляя ОС выполнять ретрансмиссию через 0.2 сек
|
--dpi-desync-retrans=0|1 ; (только для fake,rst,rstack) 0(default)=отправлять оригинал следом за фейком 1=дропать оригинал, заставляя ОС выполнять ретрансмиссию через 0.2 сек
|
||||||
--dpi-desync-repeats=<N> ; посылать каждый генерируемый в nfqws пакет N раз (не влияет на остальные пакеты)
|
--dpi-desync-repeats=<N> ; посылать каждый генерируемый в nfqws пакет N раз (не влияет на остальные пакеты)
|
||||||
--dpi-desync-skip-nosni=0|1 ; 1(default)=не применять dpi desync для запросов без hostname в SNI, в частности для ESNI
|
--dpi-desync-skip-nosni=0|1 ; 1(default)=не применять dpi desync для запросов без hostname в SNI, в частности для ESNI
|
||||||
@ -257,6 +257,11 @@ nfqws
|
|||||||
Некоторые стоковые прошивки роутеров фиксируют исходящий TTL, без отключения этой опции через них работать не будет.
|
Некоторые стоковые прошивки роутеров фиксируют исходящий TTL, без отключения этой опции через них работать не будет.
|
||||||
КАКИМ СТОИТ ВЫБИРАТЬ TTL : найдите минимальное значение, при котором обход еще работает.
|
КАКИМ СТОИТ ВЫБИРАТЬ TTL : найдите минимальное значение, при котором обход еще работает.
|
||||||
Это и будет номер хопа вашего DPI.
|
Это и будет номер хопа вашего DPI.
|
||||||
|
* hopbyhop относится только к ipv6. Добавляется ipv6 extenstion header "hop-by-hop options".
|
||||||
|
В варианте hopbyhop2 добавляются 2 хедера, что является нарушением стандарта и гарантированно отбрасывается
|
||||||
|
стеком протоколов во всех ОС. Один хедер hop-by-hop принимается всеми ОС, однако на некоторых каналах/провайдерах
|
||||||
|
такие пакеты могут фильтроваться и не доходить. Расчет идет на то, что DPI проанализирует пакет с hop-by-hop,
|
||||||
|
но он либо не дойдет до адресата всилу фильтров провайдера, либо будет отброшен сервером, потому что хедера два.
|
||||||
|
|
||||||
Режимы дурения могут сочетаться в любых комбинациях. --dpi-desync-fooling берет множество значений через запятую.
|
Режимы дурения могут сочетаться в любых комбинациях. --dpi-desync-fooling берет множество значений через запятую.
|
||||||
|
|
||||||
@ -288,6 +293,16 @@ nfqws
|
|||||||
|
|
||||||
disorder2 и split2 не предполагают отсылку фейк пакетов, поэтому опции ttl и fooling неактуальны.
|
disorder2 и split2 не предполагают отсылку фейк пакетов, поэтому опции ttl и fooling неактуальны.
|
||||||
|
|
||||||
|
Режим десинхронизации hopbyhop (не путать с fooling !) относится только к ipv6 и заключается в добавлении
|
||||||
|
хедера "hop-by-hop options" во все пакеты, попадающие под десинхронизацию.
|
||||||
|
Здесь надо обязательно понимать, что добавление хедера увеличивает размер пакета, потому не может быть применен
|
||||||
|
к пакетам максимального размера. Это имеет место при передачи больших сообщений.
|
||||||
|
В случае невозможности отослать пакет дурение будет отменено, пакет будет выслан в оригинале.
|
||||||
|
Расчет идет на то, что DPI увидит 0 в поле next header основного заголовка ipv6 и не будет скакать по
|
||||||
|
extension хедерам в поисках транспортного хедера. Таким образом не поймет, что это tcp или udp, и пропустит пакет
|
||||||
|
без анализа. Возможно, какие-то DPI на это купятся.
|
||||||
|
hopbyhop исключает применение режимов 2-й фазы.
|
||||||
|
|
||||||
Есть DPI, которые анализируют ответы от сервера, в частности сертификат из ServerHello, где прописаны домены.
|
Есть DPI, которые анализируют ответы от сервера, в частности сертификат из ServerHello, где прописаны домены.
|
||||||
Подтверждением доставки ClientHello является ACK пакет от сервера с номером ACK sequence, соответствующим длине ClientHello+1.
|
Подтверждением доставки ClientHello является ACK пакет от сервера с номером ACK sequence, соответствующим длине ClientHello+1.
|
||||||
В варианте disorder обычно приходит сперва частичное подтверждение (SACK), потом полный ACK.
|
В варианте disorder обычно приходит сперва частичное подтверждение (SACK), потом полный ACK.
|
||||||
|
@ -200,19 +200,40 @@ bool prepare_tcp_segment6(
|
|||||||
uint8_t *buf, size_t *buflen)
|
uint8_t *buf, size_t *buflen)
|
||||||
{
|
{
|
||||||
uint16_t tcpoptlen = tcpopt_len(fooling,timestamps,scale_factor);
|
uint16_t tcpoptlen = tcpopt_len(fooling,timestamps,scale_factor);
|
||||||
uint16_t ip_payload_len = sizeof(struct tcphdr) + tcpoptlen + len;
|
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);
|
||||||
uint16_t pktlen = sizeof(struct ip6_hdr) + ip_payload_len;
|
uint16_t pktlen = sizeof(struct ip6_hdr) + ip_payload_len;
|
||||||
if (pktlen>*buflen) return false;
|
if (pktlen>*buflen) return false;
|
||||||
|
|
||||||
struct ip6_hdr *ip6 = (struct ip6_hdr*)buf;
|
struct ip6_hdr *ip6 = (struct ip6_hdr*)buf;
|
||||||
struct tcphdr *tcp = (struct tcphdr*)(ip6+1);
|
struct tcphdr *tcp = (struct tcphdr*)(ip6+1);
|
||||||
|
uint8_t proto;
|
||||||
|
|
||||||
|
if (fooling & (FOOL_HOPBYHOP|FOOL_HOPBYHOP2))
|
||||||
|
{
|
||||||
|
struct ip6_hbh *hbh = (struct ip6_hbh*)tcp;
|
||||||
|
tcp = (struct tcphdr*)((uint8_t*)tcp+8);
|
||||||
|
memset(hbh,0,8);
|
||||||
|
// extra HOPBYHOP header. standard violation
|
||||||
|
if (fooling & FOOL_HOPBYHOP2)
|
||||||
|
{
|
||||||
|
hbh = (struct ip6_hbh*)tcp;
|
||||||
|
tcp = (struct tcphdr*)((uint8_t*)tcp+8);
|
||||||
|
memset(hbh,0,8);
|
||||||
|
}
|
||||||
|
hbh->ip6h_nxt = IPPROTO_TCP;
|
||||||
|
proto = 0; // hop by hop options
|
||||||
|
}
|
||||||
|
else
|
||||||
|
proto = IPPROTO_TCP;
|
||||||
|
|
||||||
uint8_t *payload = (uint8_t*)(tcp+1)+tcpoptlen;
|
uint8_t *payload = (uint8_t*)(tcp+1)+tcpoptlen;
|
||||||
|
|
||||||
fill_ip6hdr(ip6, &src->sin6_addr, &dst->sin6_addr, ip_payload_len, IPPROTO_TCP, ttl);
|
fill_ip6hdr(ip6, &src->sin6_addr, &dst->sin6_addr, ip_payload_len, proto, ttl);
|
||||||
fill_tcphdr(tcp,fooling,tcp_flags,nseq,nack_seq,src->sin6_port,dst->sin6_port,nwsize,scale_factor,timestamps,badseq_increment,badseq_ack_increment);
|
fill_tcphdr(tcp,fooling,tcp_flags,nseq,nack_seq,src->sin6_port,dst->sin6_port,nwsize,scale_factor,timestamps,badseq_increment,badseq_ack_increment);
|
||||||
|
|
||||||
memcpy(payload,data,len);
|
memcpy(payload,data,len);
|
||||||
tcp6_fix_checksum(tcp,ip_payload_len,&ip6->ip6_src,&ip6->ip6_dst);
|
tcp6_fix_checksum(tcp,transport_payload_len,&ip6->ip6_src,&ip6->ip6_dst);
|
||||||
if (fooling & FOOL_BADSUM) tcp->th_sum^=htons(0xBEAF);
|
if (fooling & FOOL_BADSUM) tcp->th_sum^=htons(0xBEAF);
|
||||||
|
|
||||||
*buflen = pktlen;
|
*buflen = pktlen;
|
||||||
@ -273,19 +294,39 @@ bool prepare_udp_segment6(
|
|||||||
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 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);
|
||||||
uint16_t pktlen = sizeof(struct ip6_hdr) + ip_payload_len;
|
uint16_t pktlen = sizeof(struct ip6_hdr) + ip_payload_len;
|
||||||
if (pktlen>*buflen) return false;
|
if (pktlen>*buflen) return false;
|
||||||
|
|
||||||
struct ip6_hdr *ip6 = (struct ip6_hdr*)buf;
|
struct ip6_hdr *ip6 = (struct ip6_hdr*)buf;
|
||||||
struct udphdr *udp = (struct udphdr*)(ip6+1);
|
struct udphdr *udp = (struct udphdr*)(ip6+1);
|
||||||
|
uint8_t proto;
|
||||||
|
|
||||||
|
if (fooling & (FOOL_HOPBYHOP|FOOL_HOPBYHOP2))
|
||||||
|
{
|
||||||
|
struct ip6_hbh *hbh = (struct ip6_hbh*)udp;
|
||||||
|
udp = (struct udphdr*)((uint8_t*)udp+8);
|
||||||
|
memset(hbh,0,8);
|
||||||
|
// extra HOPBYHOP header. standard violation
|
||||||
|
if (fooling & FOOL_HOPBYHOP2)
|
||||||
|
{
|
||||||
|
hbh = (struct ip6_hbh*)udp;
|
||||||
|
udp = (struct udphdr*)((uint8_t*)udp+8);
|
||||||
|
memset(hbh,0,8);
|
||||||
|
}
|
||||||
|
hbh->ip6h_nxt = IPPROTO_UDP;
|
||||||
|
proto = 0; // hop by hop options
|
||||||
|
}
|
||||||
|
else
|
||||||
|
proto = IPPROTO_UDP;
|
||||||
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, IPPROTO_UDP, 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, len);
|
||||||
|
|
||||||
memcpy(payload,data,len);
|
memcpy(payload,data,len);
|
||||||
udp6_fix_checksum(udp,ip_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);
|
||||||
|
|
||||||
*buflen = pktlen;
|
*buflen = pktlen;
|
||||||
|
@ -14,11 +14,13 @@
|
|||||||
// returns netorder value
|
// returns netorder value
|
||||||
uint32_t net32_add(uint32_t netorder_value, uint32_t cpuorder_increment);
|
uint32_t net32_add(uint32_t netorder_value, uint32_t cpuorder_increment);
|
||||||
|
|
||||||
#define FOOL_NONE 0
|
#define FOOL_NONE 0x00
|
||||||
#define FOOL_MD5SIG 1
|
#define FOOL_MD5SIG 0x01
|
||||||
#define FOOL_BADSUM 2
|
#define FOOL_BADSUM 0x02
|
||||||
#define FOOL_TS 4
|
#define FOOL_TS 0x04
|
||||||
#define FOOL_BADSEQ 8
|
#define FOOL_BADSEQ 0x08
|
||||||
|
#define FOOL_HOPBYHOP 0x10
|
||||||
|
#define FOOL_HOPBYHOP2 0x20
|
||||||
|
|
||||||
#define SCALE_NONE ((uint8_t)-1)
|
#define SCALE_NONE ((uint8_t)-1)
|
||||||
|
|
||||||
|
38
nfq/desync.c
38
nfq/desync.c
@ -67,7 +67,11 @@ 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;
|
return mode==DESYNC_FAKE || mode==DESYNC_RST || mode==DESYNC_RSTACK || mode==DESYNC_HOPBYHOP;
|
||||||
|
}
|
||||||
|
bool desync_only_first_stage(enum dpi_desync_mode mode)
|
||||||
|
{
|
||||||
|
return mode==DESYNC_HOPBYHOP;
|
||||||
}
|
}
|
||||||
bool desync_valid_second_stage(enum dpi_desync_mode mode)
|
bool desync_valid_second_stage(enum dpi_desync_mode mode)
|
||||||
{
|
{
|
||||||
@ -95,6 +99,8 @@ enum dpi_desync_mode desync_mode_from_string(const char *s)
|
|||||||
return DESYNC_SPLIT2;
|
return DESYNC_SPLIT2;
|
||||||
else if (!strcmp(s,"ipfrag2"))
|
else if (!strcmp(s,"ipfrag2"))
|
||||||
return DESYNC_IPFRAG2;
|
return DESYNC_IPFRAG2;
|
||||||
|
else if (!strcmp(s,"hopbyhop"))
|
||||||
|
return DESYNC_HOPBYHOP;
|
||||||
return DESYNC_INVALID;
|
return DESYNC_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -378,6 +384,21 @@ packet_process_result dpi_desync_tcp_packet(uint8_t *data_pkt, size_t len_pkt, s
|
|||||||
DLOG("sending fake RST/RSTACK\n");
|
DLOG("sending fake RST/RSTACK\n");
|
||||||
b = true;
|
b = true;
|
||||||
break;
|
break;
|
||||||
|
case DESYNC_HOPBYHOP:
|
||||||
|
if (ip6hdr)
|
||||||
|
{
|
||||||
|
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,FOOL_HOPBYHOP,0,0,
|
||||||
|
data_payload, len_payload, pkt1, &pkt1_len))
|
||||||
|
{
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
DLOG("resending original packet with hop-by-hop options\n");
|
||||||
|
if (!rawsend((struct sockaddr *)&dst, params.desync_fwmark, pkt1, pkt1_len))
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
// this mode is final, no other options available
|
||||||
|
return drop;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (b)
|
if (b)
|
||||||
@ -640,6 +661,21 @@ packet_process_result dpi_desync_udp_packet(uint8_t *data_pkt, size_t len_pkt, s
|
|||||||
hexdump_limited_dlog(fake,fake_size,PKTDATA_MAXDUMP); DLOG("\n")
|
hexdump_limited_dlog(fake,fake_size,PKTDATA_MAXDUMP); DLOG("\n")
|
||||||
b = true;
|
b = true;
|
||||||
break;
|
break;
|
||||||
|
case DESYNC_HOPBYHOP:
|
||||||
|
if (ip6hdr)
|
||||||
|
{
|
||||||
|
if (!prepare_udp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst,
|
||||||
|
ttl_orig,FOOL_HOPBYHOP,
|
||||||
|
data_payload, len_payload, pkt1, &pkt1_len))
|
||||||
|
{
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
DLOG("resending original packet with hop-by-hop options\n");
|
||||||
|
if (!rawsend((struct sockaddr *)&dst, params.desync_fwmark, pkt1, pkt1_len))
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
// this mode is final, no other options available
|
||||||
|
return drop;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (b)
|
if (b)
|
||||||
|
@ -29,7 +29,8 @@ enum dpi_desync_mode {
|
|||||||
DESYNC_DISORDER2,
|
DESYNC_DISORDER2,
|
||||||
DESYNC_SPLIT,
|
DESYNC_SPLIT,
|
||||||
DESYNC_SPLIT2,
|
DESYNC_SPLIT2,
|
||||||
DESYNC_IPFRAG2
|
DESYNC_IPFRAG2,
|
||||||
|
DESYNC_HOPBYHOP
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const char *fake_http_request_default;
|
extern const char *fake_http_request_default;
|
||||||
@ -38,6 +39,7 @@ extern const uint8_t fake_tls_clienthello_default[517];
|
|||||||
enum dpi_desync_mode desync_mode_from_string(const char *s);
|
enum dpi_desync_mode desync_mode_from_string(const char *s);
|
||||||
bool desync_valid_zero_stage(enum dpi_desync_mode mode);
|
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_valid_second_stage(enum dpi_desync_mode mode);
|
bool desync_valid_second_stage(enum dpi_desync_mode mode);
|
||||||
|
|
||||||
void desync_init();
|
void desync_init();
|
||||||
|
10
nfq/nfqws.c
10
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 disorder disorder2 split split2 ipfrag2\n"
|
" --dpi-desync=[<mode0>,]<mode>[,<mode2>] ; try to desync dpi state. modes : synack fake rst rstack hopbyhop disorder disorder2 split split2 ipfrag2\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)
|
||||||
@ -513,7 +513,7 @@ static void exithelp()
|
|||||||
#endif
|
#endif
|
||||||
" --dpi-desync-ttl=<int>\t\t\t; set ttl for desync packet\n"
|
" --dpi-desync-ttl=<int>\t\t\t; set ttl for desync packet\n"
|
||||||
" --dpi-desync-ttl6=<int>\t\t; set ipv6 hop limit for desync packet. by default ttl value is used.\n"
|
" --dpi-desync-ttl6=<int>\t\t; set ipv6 hop limit for desync packet. by default ttl value is used.\n"
|
||||||
" --dpi-desync-fooling=<mode>[,<mode>]\t; can use multiple comma separated values. modes : none md5sig ts badseq badsum\n"
|
" --dpi-desync-fooling=<mode>[,<mode>]\t; can use multiple comma separated values. modes : none md5sig ts badseq badsum hopbyhop hopbyhop2\n"
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
" --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-retrans=0|1\t\t; 0(default)=reinject original data packet after fake 1=drop original data packet to force its retransmission\n"
|
||||||
#endif
|
#endif
|
||||||
@ -810,7 +810,7 @@ int main(int argc, char **argv)
|
|||||||
fprintf(stderr, "invalid desync combo : %s+%s+%s\n",mode,mode2,mode3);
|
fprintf(stderr, "invalid desync combo : %s+%s+%s\n",mode,mode2,mode3);
|
||||||
exit_clean(1);
|
exit_clean(1);
|
||||||
}
|
}
|
||||||
if (params.desync_mode2 && !(desync_valid_first_stage(params.desync_mode) && desync_valid_second_stage(params.desync_mode2)))
|
if (params.desync_mode2 && (desync_only_first_stage(params.desync_mode) || !(desync_valid_first_stage(params.desync_mode) && desync_valid_second_stage(params.desync_mode2))))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "invalid desync combo : %s+%s\n", mode,mode2);
|
fprintf(stderr, "invalid desync combo : %s+%s\n", mode,mode2);
|
||||||
exit_clean(1);
|
exit_clean(1);
|
||||||
@ -864,6 +864,10 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
else if (!strcmp(p,"badseq"))
|
else if (!strcmp(p,"badseq"))
|
||||||
params.desync_fooling_mode |= FOOL_BADSEQ;
|
params.desync_fooling_mode |= FOOL_BADSEQ;
|
||||||
|
else if (!strcmp(p,"hopbyhop"))
|
||||||
|
params.desync_fooling_mode |= FOOL_HOPBYHOP;
|
||||||
|
else if (!strcmp(p,"hopbyhop2"))
|
||||||
|
params.desync_fooling_mode |= FOOL_HOPBYHOP2;
|
||||||
else if (strcmp(p,"none"))
|
else if (strcmp(p,"none"))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "dpi-desync-fooling allowed values : none,md5sig,ts,badseq,badsum\n");
|
fprintf(stderr, "dpi-desync-fooling allowed values : none,md5sig,ts,badseq,badsum\n");
|
||||||
|
Loading…
Reference in New Issue
Block a user