mirror of
https://github.com/bol-van/zapret.git
synced 2024-11-11 17:29:16 +05:00
nfqws: tunable badseq/badack increment, changed defaults
This commit is contained in:
parent
1d69f741ad
commit
d1618faf40
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.
@ -54,7 +54,14 @@ uint8_t tcp_find_scale_factor(const struct tcphdr *tcp)
|
||||
}
|
||||
|
||||
// n prefix (nsport, nwsize) means network byte order
|
||||
static void fill_tcphdr(struct tcphdr *tcp, uint8_t fooling, uint8_t tcp_flags, uint32_t nseq, uint32_t nack_seq, uint16_t nsport, uint16_t ndport, uint16_t nwsize, uint8_t scale_factor, uint32_t *timestamps)
|
||||
static void fill_tcphdr(
|
||||
struct tcphdr *tcp, uint8_t fooling, uint8_t tcp_flags,
|
||||
uint32_t nseq, uint32_t nack_seq,
|
||||
uint16_t nsport, uint16_t ndport,
|
||||
uint16_t nwsize, uint8_t scale_factor,
|
||||
uint32_t *timestamps,
|
||||
uint32_t badseq_increment,
|
||||
uint32_t badseq_ack_increment)
|
||||
{
|
||||
char *tcpopt = (char*)(tcp+1);
|
||||
uint8_t t=0;
|
||||
@ -64,13 +71,13 @@ static void fill_tcphdr(struct tcphdr *tcp, uint8_t fooling, uint8_t tcp_flags,
|
||||
tcp->th_dport = ndport;
|
||||
if (fooling & TCP_FOOL_BADSEQ)
|
||||
{
|
||||
tcp->th_seq = net32_add(nseq,0x80000000);
|
||||
tcp->th_ack = net32_add(nack_seq,0x80000000);
|
||||
tcp->th_seq = net32_add(nseq,badseq_increment);
|
||||
tcp->th_ack = net32_add(nack_seq,badseq_ack_increment);
|
||||
}
|
||||
else
|
||||
{
|
||||
tcp->th_seq = nseq;
|
||||
tcp->th_ack = nack_seq;
|
||||
tcp->th_seq = nseq;
|
||||
tcp->th_ack = nack_seq;
|
||||
}
|
||||
tcp->th_off = 5;
|
||||
*((uint8_t*)tcp+13)= tcp_flags;
|
||||
@ -285,7 +292,7 @@ bool rawsend(const struct sockaddr* dst,uint32_t fwmark,const void *data,size_t
|
||||
v = ((struct ip6_hdr *)data)->ip6_ctlun.ip6_un1.ip6_un1_hlim;
|
||||
if (setsockopt(sock, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &v, sizeof(v)) == -1)
|
||||
perror("rawsend: setsockopt(IPV6_HOPLIMIT)");
|
||||
// the only way to control source address is bind. make it equal to ip6_hdr
|
||||
[5~ // the only way to control source address is bind. make it equal to ip6_hdr
|
||||
if (bind(sock, (struct sockaddr*)&sa_src, salen) < 0)
|
||||
perror("rawsend bind: ");
|
||||
//printf("BSD v6 RAWSEND "); print_sockaddr((struct sockaddr*)&sa_src); printf(" -> "); print_sockaddr((struct sockaddr*)&dst2); printf("\n");
|
||||
@ -342,6 +349,8 @@ bool prepare_tcp_segment4(
|
||||
uint32_t *timestamps,
|
||||
uint8_t ttl,
|
||||
uint8_t fooling,
|
||||
uint32_t badseq_increment,
|
||||
uint32_t badseq_ack_increment,
|
||||
const void *data, uint16_t len,
|
||||
uint8_t *buf, size_t *buflen)
|
||||
{
|
||||
@ -366,7 +375,7 @@ bool prepare_tcp_segment4(
|
||||
ip->ip_src = src->sin_addr;
|
||||
ip->ip_dst = dst->sin_addr;
|
||||
|
||||
fill_tcphdr(tcp,fooling,tcp_flags,nseq,nack_seq,src->sin_port,dst->sin_port,nwsize,scale_factor,timestamps);
|
||||
fill_tcphdr(tcp,fooling,tcp_flags,nseq,nack_seq,src->sin_port,dst->sin_port,nwsize,scale_factor,timestamps,badseq_increment,badseq_ack_increment);
|
||||
|
||||
memcpy((char*)tcp+sizeof(struct tcphdr)+tcpoptlen,data,len);
|
||||
tcp4_fix_checksum(tcp,sizeof(struct tcphdr)+tcpoptlen+len,&ip->ip_src,&ip->ip_dst);
|
||||
@ -386,6 +395,8 @@ bool prepare_tcp_segment6(
|
||||
uint32_t *timestamps,
|
||||
uint8_t ttl,
|
||||
uint8_t fooling,
|
||||
uint32_t badseq_increment,
|
||||
uint32_t badseq_ack_increment,
|
||||
const void *data, uint16_t len,
|
||||
uint8_t *buf, size_t *buflen)
|
||||
{
|
||||
@ -408,7 +419,7 @@ bool prepare_tcp_segment6(
|
||||
ip6->ip6_src = src->sin6_addr;
|
||||
ip6->ip6_dst = dst->sin6_addr;
|
||||
|
||||
fill_tcphdr(tcp,fooling,tcp_flags,nseq,nack_seq,src->sin6_port,dst->sin6_port,nwsize,scale_factor,timestamps);
|
||||
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((char*)tcp+sizeof(struct tcphdr)+tcpoptlen,data,len);
|
||||
tcp6_fix_checksum(tcp,sizeof(struct tcphdr)+tcpoptlen+len,&ip6->ip6_src,&ip6->ip6_dst);
|
||||
@ -427,13 +438,15 @@ bool prepare_tcp_segment(
|
||||
uint32_t *timestamps,
|
||||
uint8_t ttl,
|
||||
uint8_t fooling,
|
||||
uint32_t badseq_increment,
|
||||
uint32_t badseq_ack_increment,
|
||||
const void *data, uint16_t len,
|
||||
uint8_t *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,nseq,nack_seq,nwsize,scale_factor,timestamps,ttl,fooling,data,len,buf,buflen) :
|
||||
prepare_tcp_segment4((struct sockaddr_in *)src,(struct sockaddr_in *)dst,tcp_flags,nseq,nack_seq,nwsize,scale_factor,timestamps,ttl,fooling,badseq_increment,badseq_ack_increment,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,nseq,nack_seq,nwsize,scale_factor,timestamps,ttl,fooling,data,len,buf,buflen) :
|
||||
prepare_tcp_segment6((struct sockaddr_in6 *)src,(struct sockaddr_in6 *)dst,tcp_flags,nseq,nack_seq,nwsize,scale_factor,timestamps,ttl,fooling,badseq_increment,badseq_ack_increment,data,len,buf,buflen) :
|
||||
false;
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,8 @@ bool prepare_tcp_segment4(
|
||||
uint32_t *timestamps,
|
||||
uint8_t ttl,
|
||||
uint8_t fooling,
|
||||
uint32_t badseq_increment,
|
||||
uint32_t badseq_ack_increment,
|
||||
const void *data, uint16_t len,
|
||||
uint8_t *buf, size_t *buflen);
|
||||
bool prepare_tcp_segment6(
|
||||
@ -42,6 +44,8 @@ bool prepare_tcp_segment6(
|
||||
uint32_t *timestamps,
|
||||
uint8_t ttl,
|
||||
uint8_t fooling,
|
||||
uint32_t badseq_increment,
|
||||
uint32_t badseq_ack_increment,
|
||||
const void *data, uint16_t len,
|
||||
uint8_t *buf, size_t *buflen);
|
||||
bool prepare_tcp_segment(
|
||||
@ -53,6 +57,8 @@ bool prepare_tcp_segment(
|
||||
uint32_t *timestamps,
|
||||
uint8_t ttl,
|
||||
uint8_t fooling,
|
||||
uint32_t badseq_increment,
|
||||
uint32_t badseq_ack_increment,
|
||||
const void *data, uint16_t len,
|
||||
uint8_t *buf, size_t *buflen);
|
||||
|
||||
|
18
nfq/desync.c
18
nfq/desync.c
@ -176,7 +176,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
{
|
||||
newlen = sizeof(newdata);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, TH_SYN|TH_ACK, tcphdr->th_seq, tcphdr->th_ack, tcphdr->th_win, scale_factor, timestamps,
|
||||
ttl_fake,params.desync_tcp_fooling_mode,
|
||||
ttl_fake,params.desync_tcp_fooling_mode,params.desync_badseq_increment,params.desync_badseq_ack_increment,
|
||||
NULL, 0, newdata, &newlen))
|
||||
{
|
||||
return res;
|
||||
@ -309,7 +309,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
{
|
||||
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,
|
||||
ttl_fake,params.desync_tcp_fooling_mode,
|
||||
ttl_fake,params.desync_tcp_fooling_mode,params.desync_badseq_increment,params.desync_badseq_ack_increment,
|
||||
fake, fake_size, newdata, &newlen))
|
||||
{
|
||||
return res;
|
||||
@ -321,7 +321,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
case DESYNC_RST:
|
||||
case DESYNC_RSTACK:
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, TH_RST | (desync_mode==DESYNC_RSTACK ? TH_ACK:0), tcphdr->th_seq, tcphdr->th_ack, tcphdr->th_win, scale_factor, timestamps,
|
||||
ttl_fake,params.desync_tcp_fooling_mode,
|
||||
ttl_fake,params.desync_tcp_fooling_mode,params.desync_badseq_increment,params.desync_badseq_ack_increment,
|
||||
NULL, 0, newdata, &newlen))
|
||||
{
|
||||
return res;
|
||||
@ -373,7 +373,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
if (split_pos<len_payload)
|
||||
{
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, net32_add(tcphdr->th_seq,split_pos), tcphdr->th_ack, tcphdr->th_win, scale_factor, timestamps,
|
||||
ttl_orig,TCP_FOOL_NONE,
|
||||
ttl_orig,TCP_FOOL_NONE,params.desync_badseq_increment,params.desync_badseq_ack_increment,
|
||||
data_payload+split_pos, len_payload-split_pos, newdata, &newlen))
|
||||
return res;
|
||||
DLOG("sending 2nd out-of-order tcp segment %zu-%zu len=%zu : ",split_pos,len_payload-1, len_payload-split_pos)
|
||||
@ -387,7 +387,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
{
|
||||
fakeseg_len = sizeof(fakeseg);
|
||||
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_tcp_fooling_mode,
|
||||
ttl_fake,params.desync_tcp_fooling_mode,params.desync_badseq_increment,params.desync_badseq_ack_increment,
|
||||
zeropkt, split_pos, fakeseg, &fakeseg_len))
|
||||
return res;
|
||||
DLOG("sending fake(1) 1st out-of-order tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos)
|
||||
@ -399,7 +399,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
|
||||
newlen = sizeof(newdata);
|
||||
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,TCP_FOOL_NONE,
|
||||
ttl_orig,TCP_FOOL_NONE,params.desync_badseq_increment,params.desync_badseq_ack_increment,
|
||||
data_payload, split_pos, newdata, &newlen))
|
||||
return res;
|
||||
DLOG("sending 1st out-of-order tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos)
|
||||
@ -429,7 +429,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
{
|
||||
fakeseg_len = sizeof(fakeseg);
|
||||
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_tcp_fooling_mode,
|
||||
ttl_fake,params.desync_tcp_fooling_mode,params.desync_badseq_increment,params.desync_badseq_ack_increment,
|
||||
zeropkt, split_pos, fakeseg, &fakeseg_len))
|
||||
return res;
|
||||
DLOG("sending fake(1) 1st tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos)
|
||||
@ -440,7 +440,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
|
||||
newlen = sizeof(newdata);
|
||||
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,TCP_FOOL_NONE,
|
||||
ttl_orig,TCP_FOOL_NONE,params.desync_badseq_increment,params.desync_badseq_ack_increment,
|
||||
data_payload, split_pos, newdata, &newlen))
|
||||
return res;
|
||||
DLOG("sending 1st tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos)
|
||||
@ -460,7 +460,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
{
|
||||
newlen = sizeof(newdata);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, net32_add(tcphdr->th_seq,split_pos), tcphdr->th_ack, tcphdr->th_win, scale_factor, timestamps,
|
||||
ttl_orig,TCP_FOOL_NONE,
|
||||
ttl_orig,TCP_FOOL_NONE,params.desync_badseq_increment,params.desync_badseq_ack_increment,
|
||||
data_payload+split_pos, len_payload-split_pos, newdata, &newlen))
|
||||
return res;
|
||||
DLOG("sending 2nd tcp segment %zu-%zu len=%zu : ",split_pos,len_payload-1, len_payload-split_pos)
|
||||
|
49
nfq/nfqws.c
49
nfq/nfqws.c
@ -494,6 +494,8 @@ static void exithelp()
|
||||
" --dpi-desync-repeats=<N>\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-split-pos=<1..%u>\t; TCP packet split position\n"
|
||||
" --dpi-desync-badseq-increment=<int|0xHEX> ; badseq fooling seq signed increment. default %d\n"
|
||||
" --dpi-desync-badack-increment=<int|0xHEX> ; 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-fake-http=<filename>\t; file containing fake http request\n"
|
||||
" --dpi-desync-fake-tls=<filename>\t; file containing fake TLS ClientHello (for https)\n"
|
||||
@ -503,7 +505,8 @@ static void exithelp()
|
||||
#if defined(__linux__) || defined(SO_USER_COOKIE)
|
||||
DPI_DESYNC_FWMARK_DEFAULT,DPI_DESYNC_FWMARK_DEFAULT,
|
||||
#endif
|
||||
DPI_DESYNC_MAX_FAKE_LEN
|
||||
DPI_DESYNC_MAX_FAKE_LEN,
|
||||
BADSEQ_INCREMENT_DEFAULT, BADSEQ_ACK_INCREMENT_DEFAULT
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
@ -554,6 +557,8 @@ int main(int argc, char **argv)
|
||||
params.ctrack_t_est = CTRACK_T_EST;
|
||||
params.ctrack_t_fin = CTRACK_T_FIN;
|
||||
params.desync_ttl6 = 0xFF; // unused
|
||||
params.desync_badseq_increment = BADSEQ_INCREMENT_DEFAULT;
|
||||
params.desync_badseq_ack_increment = BADSEQ_ACK_INCREMENT_DEFAULT;
|
||||
|
||||
if (can_drop_root()) // are we root ?
|
||||
{
|
||||
@ -597,11 +602,13 @@ int main(int argc, char **argv)
|
||||
{"dpi-desync-repeats",required_argument,0,0}, // optidx=20
|
||||
{"dpi-desync-skip-nosni",optional_argument,0,0},// optidx=21
|
||||
{"dpi-desync-split-pos",required_argument,0,0},// optidx=22
|
||||
{"dpi-desync-any-protocol",optional_argument,0,0},// optidx=23
|
||||
{"dpi-desync-fake-http",required_argument,0,0},// optidx=24
|
||||
{"dpi-desync-fake-tls",required_argument,0,0},// optidx=25
|
||||
{"dpi-desync-cutoff",required_argument,0,0},// optidx=26
|
||||
{"hostlist",required_argument,0,0}, // optidx=27
|
||||
{"dpi-desync-badseq-increment",required_argument,0,0},// optidx=23
|
||||
{"dpi-desync-badack-increment",required_argument,0,0},// optidx=24
|
||||
{"dpi-desync-any-protocol",optional_argument,0,0},// optidx=25
|
||||
{"dpi-desync-fake-http",required_argument,0,0},// optidx=26
|
||||
{"dpi-desync-fake-tls",required_argument,0,0},// optidx=27
|
||||
{"dpi-desync-cutoff",required_argument,0,0},// optidx=28
|
||||
{"hostlist",required_argument,0,0}, // optidx=29
|
||||
{NULL,0,NULL,0}
|
||||
};
|
||||
if (argc < 2) exithelp();
|
||||
@ -816,10 +823,30 @@ int main(int argc, char **argv)
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 23: /* dpi-desync-any-protocol */
|
||||
case 23: /* dpi-desync-badseq-increments */
|
||||
if ((optarg[0]=='0' && optarg[1]=='x' || optarg[0]=='-' && optarg[1]=='0' && optarg[2]=='x') && sscanf(optarg+2+(optarg[0]=='-'), "%X", (int32_t*)¶ms.desync_badseq_increment))
|
||||
{
|
||||
if (optarg[0]=='-') params.desync_badseq_increment = -params.desync_badseq_increment;
|
||||
} else if (!sscanf(optarg, "%d", (int32_t*)¶ms.desync_badseq_increment))
|
||||
{
|
||||
fprintf(stderr, "dpi-desync-badseq-increment should be signed decimal or signed 0xHEX\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 24: /* dpi-desync-badack-increment */
|
||||
if ((optarg[0]=='0' && optarg[1]=='x' || optarg[0]=='-' && optarg[1]=='0' && optarg[2]=='x') && sscanf(optarg+2+(optarg[0]=='-'), "%X", (int32_t*)¶ms.desync_badseq_ack_increment))
|
||||
{
|
||||
if (optarg[0]=='-') params.desync_badseq_ack_increment = -params.desync_badseq_ack_increment;
|
||||
} else if (!sscanf(optarg, "%d", (int32_t*)¶ms.desync_badseq_ack_increment))
|
||||
{
|
||||
fprintf(stderr, "dpi-desync-badack-increment should be signed decimal or signed 0xHEX\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 25: /* dpi-desync-any-protocol */
|
||||
params.desync_any_proto = !optarg || atoi(optarg);
|
||||
break;
|
||||
case 24: /* dpi-desync-fake-http */
|
||||
case 26: /* dpi-desync-fake-http */
|
||||
params.fake_http_size = sizeof(params.fake_http);
|
||||
if (!load_file_nonempty(optarg,params.fake_http,¶ms.fake_http_size))
|
||||
{
|
||||
@ -827,7 +854,7 @@ int main(int argc, char **argv)
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 25: /* dpi-desync-fake-tls */
|
||||
case 27: /* dpi-desync-fake-tls */
|
||||
params.fake_tls_size = sizeof(params.fake_tls);
|
||||
if (!load_file_nonempty(optarg,params.fake_tls,¶ms.fake_tls_size))
|
||||
{
|
||||
@ -835,14 +862,14 @@ int main(int argc, char **argv)
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 26: /* desync-cutoff */
|
||||
case 28: /* desync-cutoff */
|
||||
if (!sscanf(optarg, "%u", ¶ms.desync_cutoff))
|
||||
{
|
||||
fprintf(stderr, "invalid desync-cutoff value\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 27: /* hostlist */
|
||||
case 29: /* hostlist */
|
||||
if (!LoadHostList(¶ms.hostlist, optarg))
|
||||
exit_clean(1);
|
||||
strncpy(params.hostfile,optarg,sizeof(params.hostfile));
|
||||
|
@ -17,6 +17,9 @@
|
||||
|
||||
#define Q_MAXLEN 1024 // in packets
|
||||
|
||||
#define BADSEQ_INCREMENT_DEFAULT -10000
|
||||
#define BADSEQ_ACK_INCREMENT_DEFAULT -65000
|
||||
|
||||
struct params_s
|
||||
{
|
||||
bool debug;
|
||||
@ -37,6 +40,7 @@ struct params_s
|
||||
uint8_t desync_ttl, desync_ttl6;
|
||||
uint8_t desync_tcp_fooling_mode;
|
||||
uint32_t desync_fwmark; // unused in BSD
|
||||
uint32_t desync_badseq_increment, desync_badseq_ack_increment;
|
||||
char hostfile[256];
|
||||
strpool *hostlist;
|
||||
uint8_t fake_http[1460],fake_tls[1460];
|
||||
|
Loading…
Reference in New Issue
Block a user