nfqws: dpi-desync-repeats

This commit is contained in:
bol-van
2020-03-18 15:38:15 +03:00
parent 35ec175b54
commit b7a9442723
14 changed files with 93 additions and 70 deletions

View File

@@ -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;

View File

@@ -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(&params.hostlist, optarg))
exit_clean(1);
strncpy(params.hostfile,optarg,sizeof(params.hostfile));

View File

@@ -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;

View File

@@ -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;
}