mirror of
https://github.com/bol-van/zapret.git
synced 2025-04-19 21:42:59 +03:00
nfqws: dpi-desync-repeats
This commit is contained in:
parent
35ec175b54
commit
b7a9442723
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.
@ -132,6 +132,7 @@ It takes the following parameters:
|
||||
--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-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-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
|
||||
--dpi-desync-any-protocol=0|1 ; 0(default)=desync only http and tls 1=desync any nonempty data packet
|
||||
|
@ -173,6 +173,7 @@ nfqws
|
||||
--dpi-desync-ttl=<int> ; установить ttl для десинхронизирующих пакетов
|
||||
--dpi-desync-fooling=none|md5sig|ts|badseq|badsum ; дополнительные методики как сделать, чтобы фейковый пакет не дошел до сервера
|
||||
--dpi-desync-retrans=0|1 ; (только для fake,rst,rstack) 0(default)=отправлять оригинал следом за фейком 1=дропать оригинал, заставляя ОС выполнять ретрансмиссию через 0.2 сек
|
||||
--dpi-desync-repeats=<N> ; посылать каждый генерируемый в nfqws пакет N раз (не влияет на остальные пакеты)
|
||||
--dpi-desync-skip-nosni=0|1 ; 1(default)=не применять dpi desync для запросов без hostname в SNI, в частности для ESNI
|
||||
--dpi-desync-split-pos=<1..1500> ; (только для disorder) разбивать пакет на указанной позиции
|
||||
--dpi-desync-any-protocol=0|1 ; 0(default)=работать только по http request и tls clienthello 1=по всем непустым пакетам данных
|
||||
|
30
nfq/desync.c
30
nfq/desync.c
@ -57,6 +57,16 @@ void desync_init()
|
||||
}
|
||||
|
||||
|
||||
// auto creates internal socket and uses it for subsequent calls
|
||||
static bool rawsend_rep(struct sockaddr* dst,uint32_t fwmark,const void *data,size_t len)
|
||||
{
|
||||
for (int i=0;i<params.desync_repeats;i++)
|
||||
if (!rawsend(dst,fwmark,data,len))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// result : true - drop original packet, false = dont drop
|
||||
packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struct iphdr *iphdr, struct ip6_hdr *ip6hdr, struct tcphdr *tcphdr, size_t len_tcp, uint8_t *data_payload, size_t len_payload)
|
||||
{
|
||||
@ -182,7 +192,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, net32_add(tcphdr->seq,split_pos), tcphdr->ack_seq, tcphdr->window, timestamps,
|
||||
ttl_orig,TCP_FOOL_NONE,
|
||||
data_payload+split_pos, len_payload-split_pos, newdata, &newlen) ||
|
||||
!rawsend((struct sockaddr *)&dst, params.desync_fwmark, newdata, newlen))
|
||||
!rawsend_rep((struct sockaddr *)&dst, params.desync_fwmark, newdata, newlen))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
@ -196,7 +206,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->seq, tcphdr->ack_seq, tcphdr->window, timestamps,
|
||||
ttl_fake,params.desync_tcp_fooling_mode,
|
||||
zeropkt, split_pos, fakeseg, &fakeseg_len) ||
|
||||
!rawsend((struct sockaddr *)&dst, params.desync_fwmark, fakeseg, fakeseg_len))
|
||||
!rawsend_rep((struct sockaddr *)&dst, params.desync_fwmark, fakeseg, fakeseg_len))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
@ -208,7 +218,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->seq, tcphdr->ack_seq, tcphdr->window, timestamps,
|
||||
ttl_orig,TCP_FOOL_NONE,
|
||||
data_payload, split_pos, newdata, &newlen) ||
|
||||
!rawsend((struct sockaddr *)&dst, params.desync_fwmark, newdata, newlen))
|
||||
!rawsend_rep((struct sockaddr *)&dst, params.desync_fwmark, newdata, newlen))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
@ -216,7 +226,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
if (params.desync_mode==DESYNC_DISORDER)
|
||||
{
|
||||
DLOG("sending fake(2) 1st out-of-order tcp segment 0-%zu len=%zu\n",split_pos-1, split_pos)
|
||||
if (!rawsend((struct sockaddr *)&dst, params.desync_fwmark, fakeseg, fakeseg_len))
|
||||
if (!rawsend_rep((struct sockaddr *)&dst, params.desync_fwmark, fakeseg, fakeseg_len))
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -237,7 +247,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->seq, tcphdr->ack_seq, tcphdr->window, timestamps,
|
||||
ttl_fake,params.desync_tcp_fooling_mode,
|
||||
zeropkt, split_pos, fakeseg, &fakeseg_len) ||
|
||||
!rawsend((struct sockaddr *)&dst, params.desync_fwmark, fakeseg, fakeseg_len))
|
||||
!rawsend_rep((struct sockaddr *)&dst, params.desync_fwmark, fakeseg, fakeseg_len))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
@ -248,7 +258,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->seq, tcphdr->ack_seq, tcphdr->window, timestamps,
|
||||
ttl_orig,TCP_FOOL_NONE,
|
||||
data_payload, split_pos, newdata, &newlen) ||
|
||||
!rawsend((struct sockaddr *)&dst, params.desync_fwmark, newdata, newlen))
|
||||
!rawsend_rep((struct sockaddr *)&dst, params.desync_fwmark, newdata, newlen))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
@ -256,7 +266,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
if (params.desync_mode==DESYNC_SPLIT)
|
||||
{
|
||||
DLOG("sending fake(2) 1st tcp segment 0-%zu len=%zu\n",split_pos-1, split_pos)
|
||||
if (!rawsend((struct sockaddr *)&dst, params.desync_fwmark, fakeseg, fakeseg_len))
|
||||
if (!rawsend_rep((struct sockaddr *)&dst, params.desync_fwmark, fakeseg, fakeseg_len))
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -267,7 +277,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, net32_add(tcphdr->seq,split_pos), tcphdr->ack_seq, tcphdr->window, timestamps,
|
||||
ttl_orig,TCP_FOOL_NONE,
|
||||
data_payload+split_pos, len_payload-split_pos, newdata, &newlen) ||
|
||||
!rawsend((struct sockaddr *)&dst, params.desync_fwmark, newdata, newlen))
|
||||
!rawsend_rep((struct sockaddr *)&dst, params.desync_fwmark, newdata, newlen))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
@ -299,7 +309,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
return res;
|
||||
}
|
||||
|
||||
if (!rawsend((struct sockaddr *)&dst, params.desync_fwmark, newdata, newlen))
|
||||
if (!rawsend_rep((struct sockaddr *)&dst, params.desync_fwmark, newdata, newlen))
|
||||
return res;
|
||||
|
||||
if (params.desync_retrans)
|
||||
@ -309,7 +319,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
DLOG("reinjecting original packet. len=%zu len_payload=%zu\n", len_pkt, len_payload)
|
||||
// if original packet was tampered earlier it needs checksum fixed
|
||||
if (res==modify) tcp_fix_checksum(tcphdr,len_tcp,iphdr,ip6hdr);
|
||||
if (!rawsend((struct sockaddr *)&dst, params.desync_fwmark, data_pkt, len_pkt))
|
||||
if (!rawsend_rep((struct sockaddr *)&dst, params.desync_fwmark, data_pkt, len_pkt))
|
||||
return res;
|
||||
}
|
||||
return drop;
|
||||
|
27
nfq/nfqws.c
27
nfq/nfqws.c
@ -257,6 +257,7 @@ static void exithelp()
|
||||
" --dpi-desync-ttl=<int>\t\t\t; set ttl for desync packet\n"
|
||||
" --dpi-desync-fooling=<mode>[,<mode>]\t; can use multiple comma separated values. modes : none md5sig ts badseq 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-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; (for disorder only) split TCP packet at specified position\n"
|
||||
" --dpi-desync-any-protocol=0|1\t\t; 0(default)=desync only http and tls 1=desync any nonempty data packet\n"
|
||||
@ -310,6 +311,7 @@ int main(int argc, char **argv)
|
||||
params.desync_fwmark = DPI_DESYNC_FWMARK_DEFAULT;
|
||||
params.desync_skip_nosni = true;
|
||||
params.desync_split_pos = 3;
|
||||
params.desync_repeats = 1;
|
||||
|
||||
const struct option long_options[] = {
|
||||
{"debug",optional_argument,0,0}, // optidx=0
|
||||
@ -327,10 +329,11 @@ int main(int argc, char **argv)
|
||||
{"dpi-desync-ttl",required_argument,0,0}, // optidx=12
|
||||
{"dpi-desync-fooling",required_argument,0,0}, // optidx=13
|
||||
{"dpi-desync-retrans",optional_argument,0,0}, // optidx=14
|
||||
{"dpi-desync-skip-nosni",optional_argument,0,0},// optidx=15
|
||||
{"dpi-desync-split-pos",required_argument,0,0},// optidx=16
|
||||
{"dpi-desync-any-protocol",optional_argument,0,0},// optidx=17
|
||||
{"hostlist",required_argument,0,0}, // optidx=18
|
||||
{"dpi-desync-repeats",required_argument,0,0}, // optidx=15
|
||||
{"dpi-desync-skip-nosni",optional_argument,0,0},// optidx=16
|
||||
{"dpi-desync-split-pos",required_argument,0,0},// optidx=17
|
||||
{"dpi-desync-any-protocol",optional_argument,0,0},// optidx=18
|
||||
{"hostlist",required_argument,0,0}, // optidx=19
|
||||
{NULL,0,NULL,0}
|
||||
};
|
||||
if (argc < 2) exithelp();
|
||||
@ -460,10 +463,18 @@ int main(int argc, char **argv)
|
||||
case 14: /* dpi-desync-retrans */
|
||||
params.desync_retrans = !optarg || atoi(optarg);
|
||||
break;
|
||||
case 15: /* dpi-desync-skip-nosni */
|
||||
case 15: /* dpi-desync-repeats */
|
||||
params.desync_repeats = atoi(optarg);
|
||||
if (params.desync_repeats<=0 || params.desync_repeats>20)
|
||||
{
|
||||
fprintf(stderr, "dpi-desync-repeats must be within 1..20\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 16: /* dpi-desync-skip-nosni */
|
||||
params.desync_skip_nosni = !optarg || atoi(optarg);
|
||||
break;
|
||||
case 16: /* dpi-desync-split-pos */
|
||||
case 17: /* dpi-desync-split-pos */
|
||||
params.desync_split_pos = atoi(optarg);
|
||||
if (params.desync_split_pos<1 || params.desync_split_pos>DPI_DESYNC_MAX_FAKE_LEN)
|
||||
{
|
||||
@ -471,10 +482,10 @@ int main(int argc, char **argv)
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 17: /* dpi-desync-any-protocol */
|
||||
case 18: /* dpi-desync-any-protocol */
|
||||
params.desync_any_proto = !optarg || atoi(optarg);
|
||||
break;
|
||||
case 18: /* hostlist */
|
||||
case 19: /* hostlist */
|
||||
if (!LoadHostList(¶ms.hostlist, optarg))
|
||||
exit_clean(1);
|
||||
strncpy(params.hostfile,optarg,sizeof(params.hostfile));
|
||||
|
@ -19,7 +19,7 @@ struct params_s
|
||||
char hostspell[4];
|
||||
enum dpi_desync_mode desync_mode;
|
||||
bool desync_retrans,desync_skip_nosni,desync_any_proto;
|
||||
int desync_split_pos;
|
||||
int desync_repeats,desync_split_pos;
|
||||
uint8_t desync_ttl;
|
||||
uint8_t desync_tcp_fooling_mode;
|
||||
uint32_t desync_fwmark;
|
||||
|
102
nfq/strpool.c
102
nfq/strpool.c
@ -6,71 +6,71 @@
|
||||
#undef uthash_nonfatal_oom
|
||||
#define uthash_nonfatal_oom(elt) ut_oom_recover(elt)
|
||||
|
||||
static bool oom=false;
|
||||
static bool oom = false;
|
||||
static void ut_oom_recover(strpool *elem)
|
||||
{
|
||||
oom=true;
|
||||
oom = true;
|
||||
}
|
||||
|
||||
// for zero terminated strings
|
||||
bool StrPoolAddStr(strpool **pp,const char *s)
|
||||
bool StrPoolAddStr(strpool **pp, const char *s)
|
||||
{
|
||||
strpool *elem;
|
||||
if (!(elem = (strpool*)malloc(sizeof(strpool))))
|
||||
return false;
|
||||
if (!(elem->str = strdup(s)))
|
||||
{
|
||||
free(elem);
|
||||
return false;
|
||||
}
|
||||
oom = false;
|
||||
HASH_ADD_KEYPTR( hh, *pp, elem->str, strlen(elem->str), elem );
|
||||
if (oom)
|
||||
{
|
||||
free(elem->str);
|
||||
free(elem);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
strpool *elem;
|
||||
if (!(elem = (strpool*)malloc(sizeof(strpool))))
|
||||
return false;
|
||||
if (!(elem->str = strdup(s)))
|
||||
{
|
||||
free(elem);
|
||||
return false;
|
||||
}
|
||||
oom = false;
|
||||
HASH_ADD_KEYPTR(hh, *pp, elem->str, strlen(elem->str), elem);
|
||||
if (oom)
|
||||
{
|
||||
free(elem->str);
|
||||
free(elem);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// for not zero terminated strings
|
||||
bool StrPoolAddStrLen(strpool **pp,const char *s,size_t slen)
|
||||
bool StrPoolAddStrLen(strpool **pp, const char *s, size_t slen)
|
||||
{
|
||||
strpool *elem;
|
||||
if (!(elem = (strpool*)malloc(sizeof(strpool))))
|
||||
return false;
|
||||
if (!(elem->str = malloc(slen+1)))
|
||||
{
|
||||
free(elem);
|
||||
return false;
|
||||
}
|
||||
memcpy(elem->str,s,slen);
|
||||
elem->str[slen]=0;
|
||||
oom = false;
|
||||
HASH_ADD_KEYPTR( hh, *pp, elem->str, strlen(elem->str), elem );
|
||||
if (oom)
|
||||
{
|
||||
free(elem->str);
|
||||
free(elem);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
strpool *elem;
|
||||
if (!(elem = (strpool*)malloc(sizeof(strpool))))
|
||||
return false;
|
||||
if (!(elem->str = malloc(slen + 1)))
|
||||
{
|
||||
free(elem);
|
||||
return false;
|
||||
}
|
||||
memcpy(elem->str, s, slen);
|
||||
elem->str[slen] = 0;
|
||||
oom = false;
|
||||
HASH_ADD_KEYPTR(hh, *pp, elem->str, strlen(elem->str), elem);
|
||||
if (oom)
|
||||
{
|
||||
free(elem->str);
|
||||
free(elem);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StrPoolCheckStr(strpool *p,const char *s)
|
||||
bool StrPoolCheckStr(strpool *p, const char *s)
|
||||
{
|
||||
strpool *elem;
|
||||
HASH_FIND_STR( p, s, elem);
|
||||
return elem!=NULL;
|
||||
strpool *elem;
|
||||
HASH_FIND_STR(p, s, elem);
|
||||
return elem != NULL;
|
||||
}
|
||||
|
||||
void StrPoolDestroy(strpool **p)
|
||||
{
|
||||
strpool *elem,*tmp;
|
||||
HASH_ITER(hh, *p, elem, tmp) {
|
||||
free(elem->str);
|
||||
HASH_DEL(*p, elem);
|
||||
free(elem);
|
||||
}
|
||||
*p = NULL;
|
||||
strpool *elem, *tmp;
|
||||
HASH_ITER(hh, *p, elem, tmp) {
|
||||
free(elem->str);
|
||||
HASH_DEL(*p, elem);
|
||||
free(elem);
|
||||
}
|
||||
*p = NULL;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user