mirror of
https://github.com/bol-van/zapret.git
synced 2024-11-30 05:50:53 +03:00
nfqws: udplen-pattern, hex string support
This commit is contained in:
parent
9b112d9a28
commit
91ac09a8bd
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -138,44 +138,47 @@ For BSD systems there is dvtws. Its built from the same source and has almost th
|
|||||||
nfqws takes the following parameters:
|
nfqws takes the following parameters:
|
||||||
|
|
||||||
```
|
```
|
||||||
--debug=0|1 ; 1=print debug info
|
--debug=0|1
|
||||||
--qnum=<nfqueue_number>
|
--qnum=<nfqueue_number>
|
||||||
--bind-fix4 ; apply outgoing interface selection fix for generated ipv4 packets
|
|
||||||
--bind-fix6 ; apply outgoing interface selection fix for generated ipv6 packets
|
|
||||||
--wsize=<winsize>[:<scale_factor>] ; change window size in SYN,ACK packets. default is not to change scale factor (OBSOLETE !)
|
|
||||||
--wssize=<winsize>[:<scale_factor>] ; change window size in outgoing packets. default scale factor is 0. (see CONNTRACK)
|
|
||||||
--wssize-cutoff=[n|d|s]N ; apply server wsize only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N
|
|
||||||
--ctrack-timeouts=S:E:F ; internal conntrack timeouts for SYN, ESTABLISHED and FIN stages. default 60:300:60
|
|
||||||
--hostcase ; change Host: => host:
|
|
||||||
--hostspell=HoSt ; exact spelling of the "Host" header. must be 4 chars. default is "host"
|
|
||||||
--hostnospace ; remove space after Host: and add it to User-Agent: to preserve packet size
|
|
||||||
--domcase ; mix domain case after Host: like this : TeSt.cOm
|
|
||||||
--daemon ; daemonize
|
--daemon ; daemonize
|
||||||
--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 fakeknown rst rstack hopbyhop destopt ipfrag1 disorder disorder2 split split2 ipfrag2 udplen
|
--bind-fix4 ; apply outgoing interface selection fix for generated ipv4 packets
|
||||||
--dpi-desync-fwmark=<int|0xHEX> ; override fwmark for desync packet. default = 0x40000000
|
--bind-fix6 ; apply outgoing interface selection fix for generated ipv6 packets
|
||||||
|
--wsize=<window_size>[:<scale_factor>] ; set window size. 0 = do not modify. OBSOLETE !
|
||||||
|
--wssize=<window_size>[:<scale_factor>] ; set window size for server. 0 = do not modify. default scale_factor = 0.
|
||||||
|
--wssize-cutoff=[n|d|s]N ; apply server wsize only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N
|
||||||
|
--ctrack-timeouts=S:E:F[:U] ; internal conntrack timeouts for TCP SYN, ESTABLISHED, FIN stages, UDP timeout. default 60:300:60:60
|
||||||
|
--hostcase ; change Host: => host:
|
||||||
|
--hostspell ; exact spelling of "Host" header. must be 4 chars. default is "host"
|
||||||
|
--hostnospace ; remove space after Host: and add it to User-Agent: to preserve packet size
|
||||||
|
--domcase ; mix domain case : Host: TeSt.cOm
|
||||||
|
--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
|
||||||
|
--dpi-desync-fwmark=<int|0xHEX> ; override fwmark for desync packet. default = 0x40000000 (1073741824)
|
||||||
--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=<fooling> ; can take multiple comma separated values : none md5sig badseq badsum hopbyhop hopbyhop2
|
--dpi-desync-fooling=<mode>[,<mode>] ; can use multiple comma separated values. modes : none md5sig ts 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 ; 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 act on ClientHello without SNI (ESNI ?)
|
||||||
--dpi-desync-split-pos=<1..1500> ; (for split* and disorder* only) split TCP packet at specified position
|
--dpi-desync-split-pos=<1..9216> ; data payload split position
|
||||||
--dpi-desync-ipfrag-pos-tcp=<8..9216> ; ip frag position starting from the transport header. multiple of 8, default 8.
|
--dpi-desync-ipfrag-pos-tcp=<8..9216> ; ip frag position starting from the transport header. multiple of 8, default 8.
|
||||||
--dpi-desync-ipfrag-pos-udp=<8..9216> ; ip frag position starting from the transport header. multiple of 8, default 32.
|
--dpi-desync-ipfrag-pos-udp=<8..9216> ; ip frag position starting from the transport header. multiple of 8, default 32.
|
||||||
--dpi-desync-badseq-increment=<int|0xHEX> ; badseq fooling seq signed increment. default -10000
|
--dpi-desync-badseq-increment=<int|0xHEX> ; badseq fooling seq signed increment. default -10000
|
||||||
--dpi-desync-badack-increment=<int|0xHEX> ; badseq fooling ackseq signed increment. default -66000
|
--dpi-desync-badack-increment=<int|0xHEX> ; badseq fooling ackseq signed increment. default -66000
|
||||||
--dpi-desync-any-protocol=0|1 ; 0(default)=desync only http and tls 1=desync any nonempty data packet
|
--dpi-desync-any-protocol=0|1 ; 0(default)=desync only http and tls 1=desync any nonempty data packet
|
||||||
--dpi-desync-fake-http=<filename> ; file containing fake http request. replacement for built-in
|
--dpi-desync-fake-http=<filename>|0xHEX ; file containing fake http request
|
||||||
--dpi-desync-fake-tls=<filename> ; file containing fake TLS ClientHello (for https). replacement for built-in
|
--dpi-desync-fake-tls=<filename>|0xHEX ; file containing fake TLS ClientHello (for https)
|
||||||
--dpi-desync-fake-unknown=<filename> ; file containing unknown protocol fake payload. default is 256 zeroes
|
--dpi-desync-fake-unknown=<filename>|0xHEX ; file containing unknown protocol fake payload
|
||||||
--dpi-desync-fake-quic=<filename> ; file containing fake QUIC Initial
|
--dpi-desync-fake-quic=<filename>|0xHEX ; file containing fake QUIC Initial
|
||||||
--dpi-desync-fake-unknown-udp=<filename> ; file containing unknown udp protocol fake payload
|
--dpi-desync-fake-wireguard=<filename>|0xHEX ; file containing fake wireguard handshake initiation
|
||||||
|
--dpi-desync-fake-unknown-udp=<filename>|0xHEX ; file containing unknown udp protocol fake payload
|
||||||
|
--dpi-desync-udplen-increment=<int> ; increase or decrease udp packet length by N bytes (default 2). negative values decrease length.
|
||||||
|
--dpi-desync-udplen-pattern=<filename>|0xHEX ; udp tail fill pattern
|
||||||
--dpi-desync-cutoff=[n|d|s]N ; apply dpi desync only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N
|
--dpi-desync-cutoff=[n|d|s]N ; apply dpi desync only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N
|
||||||
--hostlist=<filename> ; only act on hosts in the list (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)
|
--hostlist=<filename> ; apply dpi desync only to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)
|
||||||
--hostlist-exclude=<filename> ; do not act on hosts in the list (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)
|
--hostlist-exclude=<filename> ; do not apply dpi desync to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)
|
||||||
```
|
```
|
||||||
|
|
||||||
The manipulation parameters can be combined in any way.
|
The manipulation parameters can be combined in any way.
|
||||||
|
@ -219,12 +219,13 @@ nfqws
|
|||||||
--dpi-desync-badseq-increment=<int|0xHEX> ; инкремент sequence number для badseq. по умолчанию -10000
|
--dpi-desync-badseq-increment=<int|0xHEX> ; инкремент sequence number для badseq. по умолчанию -10000
|
||||||
--dpi-desync-badack-increment=<int|0xHEX> ; инкремент ack sequence number для badseq. по умолчанию -66000
|
--dpi-desync-badack-increment=<int|0xHEX> ; инкремент ack sequence number для badseq. по умолчанию -66000
|
||||||
--dpi-desync-any-protocol=0|1 ; 0(default)=работать только по http request и tls clienthello 1=по всем непустым пакетам данных
|
--dpi-desync-any-protocol=0|1 ; 0(default)=работать только по http request и tls clienthello 1=по всем непустым пакетам данных
|
||||||
--dpi-desync-fake-http=<filename> ; файл, содержащий фейковый http запрос для dpi-desync=fake, на замену стандартному w3.org
|
--dpi-desync-fake-http=<filename>|0xHEX ; файл, содержащий фейковый http запрос для dpi-desync=fake, на замену стандартному w3.org
|
||||||
--dpi-desync-fake-tls=<filename> ; файл, содержащий фейковый tls clienthello для dpi-desync=fake, на замену стандартному w3.org
|
--dpi-desync-fake-tls=<filename>|0xHEX ; файл, содержащий фейковый tls clienthello для dpi-desync=fake, на замену стандартному w3.org
|
||||||
--dpi-desync-fake-unknown=<filename> ; файл, содержащий фейковый пейлоад неизвестного протокола для dpi-desync=fake, на замену стандартным нулям 256 байт
|
--dpi-desync-fake-unknown=<filename>|0xHEX ; файл, содержащий фейковый пейлоад неизвестного протокола для dpi-desync=fake, на замену стандартным нулям 256 байт
|
||||||
--dpi-desync-fake-quic=<filename> ; файл, содержащий фейковый QUIC Initial
|
--dpi-desync-fake-quic=<filename>|0xHEX ; файл, содержащий фейковый QUIC Initial
|
||||||
--dpi-desync-fake-unknown-udp=<filename> ; файл, содержащий фейковый пейлоад неизвестного udp протокола для dpi-desync=fake, на замену стандартным нулям 64 байт
|
--dpi-desync-fake-unknown-udp=<filename>|0xHEX ; файл, содержащий фейковый пейлоад неизвестного udp протокола для dpi-desync=fake, на замену стандартным нулям 64 байт
|
||||||
--dpi-desync-udplen-increment=<int> ; насколько увеличивать длину udp пейлоада в режиме udplen
|
--dpi-desync-udplen-increment=<int> ; насколько увеличивать длину udp пейлоада в режиме udplen
|
||||||
|
--dpi-desync-udplen-pattern=<filename>|0xHEX ; чем добивать udp пакет в режиме udplen. по умолчанию - нули
|
||||||
--dpi-desync-cutoff=[n|d|s]N ; применять dpi desync только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N
|
--dpi-desync-cutoff=[n|d|s]N ; применять dpi desync только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N
|
||||||
--hostlist=<filename> ; применять дурение только к хостам из листа. может быть множество листов, они обьединяются. пустой обший лист = его отсутствие
|
--hostlist=<filename> ; применять дурение только к хостам из листа. может быть множество листов, они обьединяются. пустой обший лист = его отсутствие
|
||||||
--hostlist-exclude=<filename> ; не применять дурение к хостам из листа. может быть множество листов, они обьединяются
|
--hostlist-exclude=<filename> ; не применять дурение к хостам из листа. может быть множество листов, они обьединяются
|
||||||
|
@ -299,6 +299,7 @@ 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,
|
||||||
|
const uint8_t *padding, size_t padding_size,
|
||||||
int padlen,
|
int 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)
|
||||||
@ -324,6 +325,9 @@ bool prepare_udp_segment4(
|
|||||||
fill_udphdr(udp, src->sin_port, dst->sin_port, datalen);
|
fill_udphdr(udp, src->sin_port, dst->sin_port, datalen);
|
||||||
|
|
||||||
memcpy(payload,data,len);
|
memcpy(payload,data,len);
|
||||||
|
if (padding)
|
||||||
|
fill_pattern(payload+len,padlen,padding,padding_size);
|
||||||
|
else
|
||||||
memset(payload+len,0,padlen);
|
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);
|
||||||
@ -335,6 +339,7 @@ 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,
|
||||||
|
const uint8_t *padding, size_t padding_size,
|
||||||
int padlen,
|
int 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)
|
||||||
@ -408,6 +413,9 @@ bool prepare_udp_segment6(
|
|||||||
fill_udphdr(udp, src->sin6_port, dst->sin6_port, datalen);
|
fill_udphdr(udp, src->sin6_port, dst->sin6_port, datalen);
|
||||||
|
|
||||||
memcpy(payload,data,len);
|
memcpy(payload,data,len);
|
||||||
|
if (padding)
|
||||||
|
fill_pattern(payload+len,padlen,padding,padding_size);
|
||||||
|
else
|
||||||
memset(payload+len,0,padlen);
|
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);
|
||||||
@ -419,14 +427,15 @@ 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,
|
||||||
|
const uint8_t *padding, size_t padding_size,
|
||||||
int padlen,
|
int 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,padlen,data,len,buf,buflen) :
|
prepare_udp_segment4((struct sockaddr_in *)src,(struct sockaddr_in *)dst,ttl,fooling,padding,padding_size,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,padlen,data,len,buf,buflen) :
|
prepare_udp_segment6((struct sockaddr_in6 *)src,(struct sockaddr_in6 *)dst,ttl,fooling,padding,padding_size,padlen,data,len,buf,buflen) :
|
||||||
false;
|
false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +73,7 @@ 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,
|
||||||
|
const uint8_t *padding, size_t padding_size,
|
||||||
int padlen,
|
int 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);
|
||||||
@ -80,6 +81,7 @@ 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,
|
||||||
|
const uint8_t *padding, size_t padding_size,
|
||||||
int padlen,
|
int 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);
|
||||||
@ -87,6 +89,7 @@ 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,
|
||||||
|
const uint8_t *padding, size_t padding_size,
|
||||||
int padlen,
|
int 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);
|
||||||
|
@ -783,7 +783,7 @@ packet_process_result dpi_desync_udp_packet(uint32_t fwmark, const char *ifout,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DESYNC_FAKE:
|
case DESYNC_FAKE:
|
||||||
if (!prepare_udp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, ttl_fake, params.desync_fooling_mode, 0, fake, fake_size, pkt1, &pkt1_len))
|
if (!prepare_udp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, ttl_fake, params.desync_fooling_mode, NULL, 0, 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")
|
||||||
@ -798,7 +798,7 @@ packet_process_result dpi_desync_udp_packet(uint32_t fwmark, const char *ifout,
|
|||||||
if (ip6hdr && (params.desync_mode2==DESYNC_NONE || !desync_valid_second_stage_udp(params.desync_mode2)))
|
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,0,
|
ttl_orig,fooling_orig,NULL,0,0,
|
||||||
data_payload, len_payload, pkt1, &pkt1_len))
|
data_payload, len_payload, pkt1, &pkt1_len))
|
||||||
{
|
{
|
||||||
return res;
|
return res;
|
||||||
@ -837,7 +837,7 @@ packet_process_result dpi_desync_udp_packet(uint32_t fwmark, const char *ifout,
|
|||||||
{
|
{
|
||||||
case DESYNC_UDPLEN:
|
case DESYNC_UDPLEN:
|
||||||
pkt1_len = sizeof(pkt1);
|
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))
|
if (!prepare_udp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, ttl_orig,fooling_orig, params.udplen_pattern, sizeof(params.udplen_pattern), params.udplen_increment, data_payload, len_payload, pkt1, &pkt1_len))
|
||||||
{
|
{
|
||||||
DLOG("could not construct packet with modified length. too large ?\n");
|
DLOG("could not construct packet with modified length. too large ?\n");
|
||||||
return res;
|
return res;
|
||||||
|
@ -179,3 +179,50 @@ void phton64(uint8_t *p, uint64_t v)
|
|||||||
p[6] = (uint8_t)(v >> 8);
|
p[6] = (uint8_t)(v >> 8);
|
||||||
p[7] = (uint8_t)(v >> 0);
|
p[7] = (uint8_t)(v >> 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define INVALID_HEX_DIGIT ((uint8_t)-1)
|
||||||
|
static inline uint8_t parse_hex_digit(char c)
|
||||||
|
{
|
||||||
|
return (c>='0' && c<='9') ? c-'0' : (c>='a' && c<='f') ? c-'a'+0xA : (c>='A' && c<='F') ? c-'A'+0xA : INVALID_HEX_DIGIT;
|
||||||
|
}
|
||||||
|
static inline bool parse_hex_byte(const char *s, uint8_t *pbyte)
|
||||||
|
{
|
||||||
|
uint8_t u,l;
|
||||||
|
u = parse_hex_digit(s[0]);
|
||||||
|
l = parse_hex_digit(s[1]);
|
||||||
|
if (u==INVALID_HEX_DIGIT || l==INVALID_HEX_DIGIT)
|
||||||
|
{
|
||||||
|
*pbyte=0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*pbyte=(u<<4) | l;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool parse_hex_str(const char *s, uint8_t *pbuf, size_t *size)
|
||||||
|
{
|
||||||
|
uint8_t *pe = pbuf+*size;
|
||||||
|
*size=0;
|
||||||
|
while(pbuf<pe && *s)
|
||||||
|
{
|
||||||
|
if (!parse_hex_byte(s,pbuf))
|
||||||
|
return false;
|
||||||
|
pbuf++; s+=2; (*size)++;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fill_pattern(uint8_t *buf,size_t bufsize,const void *pattern,size_t patsize)
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
while (bufsize)
|
||||||
|
{
|
||||||
|
size = bufsize>patsize ? patsize : bufsize;
|
||||||
|
memcpy(buf,pattern,size);
|
||||||
|
buf += size;
|
||||||
|
bufsize -= size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -34,3 +34,6 @@ static inline void phton16(uint8_t *p, uint16_t v) {
|
|||||||
static inline uint32_t pntoh32(const uint8_t *p) {
|
static inline uint32_t pntoh32(const uint8_t *p) {
|
||||||
return ((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16) | ((uint32_t)p[2] << 8) | (uint32_t)p[3];
|
return ((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16) | ((uint32_t)p[2] << 8) | (uint32_t)p[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool parse_hex_str(const char *s, uint8_t *pbuf, size_t *size);
|
||||||
|
void fill_pattern(uint8_t *buf,size_t bufsize,const void *pattern,size_t patsize);
|
||||||
|
122
nfq/nfqws.c
122
nfq/nfqws.c
@ -504,54 +504,55 @@ static void exithelp()
|
|||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
" --qnum=<nfqueue_number>\n"
|
" --qnum=<nfqueue_number>\n"
|
||||||
#elif defined(BSD)
|
#elif defined(BSD)
|
||||||
" --port=<port>\t\t\t\t; divert port\n"
|
" --port=<port>\t\t\t\t\t; divert port\n"
|
||||||
#endif
|
#endif
|
||||||
" --daemon\t\t\t\t; daemonize\n"
|
" --daemon\t\t\t\t\t; daemonize\n"
|
||||||
" --pidfile=<filename>\t\t\t; write pid to file\n"
|
" --pidfile=<filename>\t\t\t\t; write pid to file\n"
|
||||||
" --user=<username>\t\t\t; drop root privs\n"
|
" --user=<username>\t\t\t\t; drop root privs\n"
|
||||||
" --uid=uid[:gid]\t\t\t; drop root privs\n"
|
" --uid=uid[:gid]\t\t\t\t; drop root privs\n"
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
" --bind-fix4\t\t\t\t; apply outgoing interface selection fix for generated ipv4 packets\n"
|
" --bind-fix4\t\t\t\t\t; apply outgoing interface selection fix for generated ipv4 packets\n"
|
||||||
" --bind-fix6\t\t\t\t; apply outgoing interface selection fix for generated ipv6 packets\n"
|
" --bind-fix6\t\t\t\t\t; apply outgoing interface selection fix for generated ipv6 packets\n"
|
||||||
#endif
|
#endif
|
||||||
" --wsize=<window_size>[:<scale_factor>]\t; set window size. 0 = do not modify. OBSOLETE !\n"
|
" --wsize=<window_size>[:<scale_factor>]\t\t; set window size. 0 = do not modify. OBSOLETE !\n"
|
||||||
" --wssize=<window_size>[:<scale_factor>]; set window size for server. 0 = do not modify. default scale_factor = 0.\n"
|
" --wssize=<window_size>[:<scale_factor>]\t; set window size for server. 0 = do not modify. default scale_factor = 0.\n"
|
||||||
" --wssize-cutoff=[n|d|s]N\t\t; apply server wsize only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N\n"
|
" --wssize-cutoff=[n|d|s]N\t\t\t; apply server wsize only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N\n"
|
||||||
" --ctrack-timeouts=S:E:F[:U]\t\t; internal conntrack timeouts for TCP SYN, ESTABLISHED, FIN stages, UDP timeout. default %u:%u:%u:%u\n"
|
" --ctrack-timeouts=S:E:F[:U]\t\t\t; internal conntrack timeouts for TCP SYN, ESTABLISHED, FIN stages, UDP timeout. default %u:%u:%u:%u\n"
|
||||||
" --hostcase\t\t\t\t; change Host: => host:\n"
|
" --hostcase\t\t\t\t\t; change Host: => host:\n"
|
||||||
" --hostspell\t\t\t\t; exact spelling of \"Host\" header. must be 4 chars. default is \"host\"\n"
|
" --hostspell\t\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\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\t; mix domain case : Host: TeSt.cOm\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"
|
" --dpi-desync=[<mode0>,]<mode>[,<mode2>]\t; 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\t; override fwmark for desync packet. default = 0x%08X (%u)\n"
|
||||||
#elif defined(SO_USER_COOKIE)
|
#elif defined(SO_USER_COOKIE)
|
||||||
" --dpi-desync-sockarg=<int|0xHEX>\t; override sockarg (SO_USER_COOKIE) for desync packet. default = 0x%08X (%u)\n"
|
" --dpi-desync-sockarg=<int|0xHEX>\t\t; override sockarg (SO_USER_COOKIE) for desync packet. default = 0x%08X (%u)\n"
|
||||||
#endif
|
#endif
|
||||||
" --dpi-desync-ttl=<int>\t\t\t; set ttl for desync packet\n"
|
" --dpi-desync-ttl=<int>\t\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\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 hopbyhop hopbyhop2\n"
|
" --dpi-desync-fooling=<mode>[,<mode>]\t\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\t; 0(default)=reinject original data packet after fake 1=drop original data packet to force its retransmission\n"
|
||||||
#endif
|
#endif
|
||||||
" --dpi-desync-repeats=<N>\t\t; send every desync packet N times\n"
|
" --dpi-desync-repeats=<N>\t\t\t; send every desync packet N times\n"
|
||||||
" --dpi-desync-skip-nosni=0|1\t\t; 1(default)=do not act on ClientHello without SNI (ESNI ?)\n"
|
" --dpi-desync-skip-nosni=0|1\t\t\t; 1(default)=do not act on ClientHello without SNI (ESNI ?)\n"
|
||||||
" --dpi-desync-split-pos=<1..%u>\t; data payload split position\n"
|
" --dpi-desync-split-pos=<1..%u>\t\t; data payload split position\n"
|
||||||
" --dpi-desync-ipfrag-pos-tcp=<8..%u>\t; ip frag position starting from the transport header. multiple of 8, default %u.\n"
|
" --dpi-desync-ipfrag-pos-tcp=<8..%u>\t\t; ip frag position starting from the transport header. multiple of 8, default %u.\n"
|
||||||
" --dpi-desync-ipfrag-pos-udp=<8..%u>\t; ip frag position starting from the transport header. multiple of 8, default %u.\n"
|
" --dpi-desync-ipfrag-pos-udp=<8..%u>\t\t; ip frag position starting from the transport header. multiple of 8, default %u.\n"
|
||||||
" --dpi-desync-badseq-increment=<int|0xHEX> ; badseq fooling seq signed increment. default %d\n"
|
" --dpi-desync-badseq-increment=<int|0xHEX>\t; badseq fooling seq signed increment. default %d\n"
|
||||||
" --dpi-desync-badack-increment=<int|0xHEX> ; badseq fooling ackseq signed increment. default %d\n"
|
" --dpi-desync-badack-increment=<int|0xHEX>\t; badseq fooling ackseq signed increment. default %d\n"
|
||||||
" --dpi-desync-any-protocol=0|1\t\t; 0(default)=desync only http and tls 1=desync any nonempty data packet\n"
|
" --dpi-desync-any-protocol=0|1\t\t\t; 0(default)=desync only http and tls 1=desync any nonempty data packet\n"
|
||||||
" --dpi-desync-fake-http=<filename>\t; file containing fake http request\n"
|
" --dpi-desync-fake-http=<filename>|0xHEX\t; file containing fake http request\n"
|
||||||
" --dpi-desync-fake-tls=<filename>\t; file containing fake TLS ClientHello (for https)\n"
|
" --dpi-desync-fake-tls=<filename>|0xHEX\t\t; file containing fake TLS ClientHello (for https)\n"
|
||||||
" --dpi-desync-fake-unknown=<filename>\t; file containing unknown protocol fake payload\n"
|
" --dpi-desync-fake-unknown=<filename>|0xHEX\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>|0xHEX\t; file containing fake QUIC Initial\n"
|
||||||
" --dpi-desync-fake-wireguard=<filename>\t; file containing fake wireguard handshake initiation\n"
|
" --dpi-desync-fake-wireguard=<filename>|0xHEX\t; file containing fake wireguard handshake initiation\n"
|
||||||
" --dpi-desync-fake-unknown-udp=<filename> ; file containing unknown udp protocol fake payload\n"
|
" --dpi-desync-fake-unknown-udp=<filename>|0xHEX\t; file containing unknown udp protocol fake payload\n"
|
||||||
" --dpi-desync-udplen-increment=<int>\t; increase or decrease udp packet length by N bytes (default %u). negative values decrease length.\n"
|
" --dpi-desync-udplen-increment=<int>\t\t; increase or decrease udp packet length by N bytes (default %u). negative values decrease length.\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-udplen-pattern=<filename>|0xHEX\t; udp tail fill pattern\n"
|
||||||
" --hostlist=<filename>\t\t\t; apply dpi desync only to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)\n"
|
" --dpi-desync-cutoff=[n|d|s]N\t\t\t; apply dpi desync only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N\n"
|
||||||
" --hostlist-exclude=<filename>\t\t; do not apply dpi desync to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)\n",
|
" --hostlist=<filename>\t\t\t\t; apply dpi desync only to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)\n"
|
||||||
|
" --hostlist-exclude=<filename>\t\t\t; do not apply dpi desync to the listed hosts (one host per line, subdomains auto apply, gzip supported, multiple hostlists allowed)\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,
|
||||||
#if defined(__linux__) || defined(SO_USER_COOKIE)
|
#if defined(__linux__) || defined(SO_USER_COOKIE)
|
||||||
DPI_DESYNC_FWMARK_DEFAULT,DPI_DESYNC_FWMARK_DEFAULT,
|
DPI_DESYNC_FWMARK_DEFAULT,DPI_DESYNC_FWMARK_DEFAULT,
|
||||||
@ -611,6 +612,17 @@ static bool parse_badseq_increment(const char *opt, uint32_t *value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void load_file_or_exit(const char *filename, void *buf, size_t *size)
|
static void load_file_or_exit(const char *filename, void *buf, size_t *size)
|
||||||
|
{
|
||||||
|
if (filename[0]=='0' && filename[1]=='x')
|
||||||
|
{
|
||||||
|
if (!parse_hex_str(filename+2,buf,size) || !*size)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "invalid hex string: %s\n",filename+2);
|
||||||
|
exit_clean(1);
|
||||||
|
}
|
||||||
|
DLOG("read %zu bytes from hex string\n",*size)
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (!load_file_nonempty(filename,buf,size))
|
if (!load_file_nonempty(filename,buf,size))
|
||||||
{
|
{
|
||||||
@ -619,6 +631,7 @@ static void load_file_or_exit(const char *filename, void *buf, size_t *size)
|
|||||||
}
|
}
|
||||||
DLOG("read %zu bytes from %s\n",*size,filename)
|
DLOG("read %zu bytes from %s\n",*size,filename)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
@ -717,12 +730,13 @@ int main(int argc, char **argv)
|
|||||||
{"dpi-desync-fake-wireguard",required_argument,0,0},// optidx=32
|
{"dpi-desync-fake-wireguard",required_argument,0,0},// optidx=32
|
||||||
{"dpi-desync-fake-unknown-udp",required_argument,0,0},// optidx=33
|
{"dpi-desync-fake-unknown-udp",required_argument,0,0},// optidx=33
|
||||||
{"dpi-desync-udplen-increment",required_argument,0,0},// optidx=34
|
{"dpi-desync-udplen-increment",required_argument,0,0},// optidx=34
|
||||||
{"dpi-desync-cutoff",required_argument,0,0},// optidx=35
|
{"dpi-desync-udplen-pattern",required_argument,0,0},// optidx=35
|
||||||
{"hostlist",required_argument,0,0}, // optidx=36
|
{"dpi-desync-cutoff",required_argument,0,0},// optidx=36
|
||||||
{"hostlist-exclude",required_argument,0,0}, // optidx=37
|
{"hostlist",required_argument,0,0}, // optidx=37
|
||||||
|
{"hostlist-exclude",required_argument,0,0}, // optidx=38
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
{"bind-fix4",no_argument,0,0}, // optidx=38
|
{"bind-fix4",no_argument,0,0}, // optidx=39
|
||||||
{"bind-fix6",no_argument,0,0}, // optidx=39
|
{"bind-fix6",no_argument,0,0}, // optidx=40
|
||||||
#endif
|
#endif
|
||||||
{NULL,0,NULL,0}
|
{NULL,0,NULL,0}
|
||||||
};
|
};
|
||||||
@ -1019,21 +1033,29 @@ int main(int argc, char **argv)
|
|||||||
exit_clean(1);
|
exit_clean(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 35: /* desync-cutoff */
|
case 35: /* dpi-desync-udplen-pattern */
|
||||||
|
{
|
||||||
|
char buf[sizeof(params.udplen_pattern)];
|
||||||
|
size_t sz=sizeof(buf);
|
||||||
|
load_file_or_exit(optarg,buf,&sz);
|
||||||
|
fill_pattern(params.udplen_pattern,sizeof(params.udplen_pattern),buf,sz);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 36: /* desync-cutoff */
|
||||||
if (!parse_cutoff(optarg, ¶ms.desync_cutoff, ¶ms.desync_cutoff_mode))
|
if (!parse_cutoff(optarg, ¶ms.desync_cutoff, ¶ms.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 36: /* hostlist */
|
case 37: /* hostlist */
|
||||||
if (!strlist_add(¶ms.hostlist_files, optarg))
|
if (!strlist_add(¶ms.hostlist_files, optarg))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "strlist_add failed\n");
|
fprintf(stderr, "strlist_add failed\n");
|
||||||
exit_clean(1);
|
exit_clean(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 37: /* hostlist-exclude */
|
case 38: /* hostlist-exclude */
|
||||||
if (!strlist_add(¶ms.hostlist_exclude_files, optarg))
|
if (!strlist_add(¶ms.hostlist_exclude_files, optarg))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "strlist_add failed\n");
|
fprintf(stderr, "strlist_add failed\n");
|
||||||
@ -1041,10 +1063,10 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
case 38: /* bind-fix4 */
|
case 39: /* bind-fix4 */
|
||||||
params.bind_fix4 = true;
|
params.bind_fix4 = true;
|
||||||
break;
|
break;
|
||||||
case 39: /* bind-fix6 */
|
case 40: /* bind-fix6 */
|
||||||
params.bind_fix6 = true;
|
params.bind_fix6 = true;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
@ -50,7 +50,7 @@ struct params_s
|
|||||||
uint8_t desync_fooling_mode;
|
uint8_t desync_fooling_mode;
|
||||||
uint32_t desync_fwmark; // unused in BSD
|
uint32_t desync_fwmark; // unused in BSD
|
||||||
uint32_t desync_badseq_increment, desync_badseq_ack_increment;
|
uint32_t desync_badseq_increment, desync_badseq_ack_increment;
|
||||||
uint8_t fake_http[1432],fake_tls[1432],fake_quic[1472],fake_wg[1472],fake_unknown[1432],fake_unknown_udp[1472];
|
uint8_t fake_http[1432],fake_tls[1432],fake_quic[1472],fake_wg[1472],fake_unknown[1432],fake_unknown_udp[1472], udplen_pattern[1472];
|
||||||
size_t fake_http_size,fake_tls_size,fake_quic_size,fake_wg_size,fake_unknown_size,fake_unknown_udp_size;
|
size_t fake_http_size,fake_tls_size,fake_quic_size,fake_wg_size,fake_unknown_size,fake_unknown_udp_size;
|
||||||
int udplen_increment;
|
int udplen_increment;
|
||||||
bool droproot;
|
bool droproot;
|
||||||
|
Loading…
Reference in New Issue
Block a user