nfqws: seqovl

This commit is contained in:
bol-van 2024-06-24 16:51:06 +03:00
parent 7edccea909
commit ff0d59faf4
22 changed files with 206 additions and 94 deletions

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.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1009,7 +1009,7 @@ pktws_check_domain_http_bypass_()
ok=1
}
[ "$ret" != 0 -o "$SCANLEVEL" = force ] && {
[ "$sec" = 0 ] && {
if [ "$sec" = 0 ]; then
pktws_curl_test_update $1 $3 $s --hostcase && {
[ "$SCANLEVEL" = quick ] && return
ok=1
@ -1022,15 +1022,14 @@ pktws_check_domain_http_bypass_()
}
done
done
}
[ "$sec" = 1 ] && {
else
for pos in sni sniext; do
pktws_curl_test_update $1 $3 $s --dpi-desync-split-tls=$pos && {
[ "$SCANLEVEL" = quick ] && return
ok=1
}
done
}
fi
for pos in 1 3 4 5 10 50; do
s="--dpi-desync=split2 --dpi-desync-split-pos=$pos"
if pktws_curl_test_update $1 $3 $s; then
@ -1100,6 +1099,22 @@ pktws_check_domain_http_bypass_()
}
done
for desync in split2 disorder2; do
s="--dpi-desync=$desync"
if [ "$sec" = 0 ]; then
for pos in method host; do
pktws_curl_test_update $1 $3 $s --dpi-desync-split-seqovl=1 --dpi-desync-split-http-req=$pos $e && [ "$SCANLEVEL" = quick ] && return
done
else
for pos in sni sniext; do
pktws_curl_test_update $1 $3 $s --dpi-desync-split-seqovl=1 --dpi-desync-split-tls=$pos $e && [ "$SCANLEVEL" = quick ] && return
done
fi
for pos in 2 3 4 5 10 50; do
pktws_curl_test_update $1 $3 $s --dpi-desync-split-seqovl=$(($pos - 1)) --dpi-desync-split-pos=$pos $e && [ "$SCANLEVEL" = quick ] && return
done
done
s="http_iana_org.bin"
[ "$sec" = 0 ] || s="tls_clienthello_iana_org.bin"
for desync in syndata syndata,split2 syndata,disorder2 syndata,split2 syndata,disorder2 ; do

View File

@ -294,3 +294,8 @@ tpws: --split-tls
tpws: --tlsrec=sniext
nfqws: --dpi-desync-split-http-req, --dpi-desync-split-tls. multi segment TLS support for split.
blockcheck: mdig dns cache
v60
blockcheck: port block test, partial ip block test
nfqws: seqovl split/disorder modes

View File

@ -180,6 +180,8 @@ nfqws takes the following parameters:
--dpi-desync-split-pos=<1..9216> ; data payload split position
--dpi-desync-split-http-req=method|host ; split at specified logical part of plain http request
--dpi-desync-split-tls=sni|sniext ; split at specified logical part of TLS ClientHello
--dpi-desync-split-seqovl=<int> ; use sequence overlap before first sent original split segment
--dpi-desync-split-seqovl-pattern=<filename>|0xHEX ; pattern for the fake part of overlap
--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-badseq-increment=<int|0xHEX> ; badseq fooling seq signed increment. default -10000
@ -292,6 +294,16 @@ 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.
`seqovl` adds to the first sent original segment (1st for split, 2nd for disorder) seqovl bytes to the beginning and decreases
sequence number.
In `split2` mode this creates partially in-window packet. OS receives only in-window part.
In `disorder2` mode OS receives fake and real part of the second segment but does not pass received data to the socket until first
segment is received. First segment overwrites fake part of the second segment. Then OS passes original data to the socket.
All unix OS preserve last received data. This may not be the case for Windows servers and may not work.
Disorder requires `seqovl` to be less than `split_pos`. Either statically defined or automatically calculated.
Otherwise desync is not possible and will not happen.
Method allows to avoid separate fakes. Fakes and real data are mixed.
`hopbyhop`, `destopt` and `ipfrag1` desync modes (they're not the same as `hopbyhop` fooling !) are ipv6 only. One `hop-by-hop`,
`destination options` or `fragment` header is added to all desynced packets.
Extra header increases packet size and can't be applied to the maximum size packets.

View File

@ -1,4 +1,4 @@
zapret v.59
zapret v.60
English
-------
@ -253,6 +253,8 @@ nfqws
--dpi-desync-split-pos=<1..1500> ; (только для split*, disorder*) разбивать пакет на указанной позиции
--dpi-desync-split-http-req=method|host ; разбивка http request на указанном логическом месте
--dpi-desync-split-tls=sni|sniext ; разбивка tls client hello на указанном логическом месте
--dpi-desync-split-seqovl=<int> ; использовать sequence overlap перед первым отсылаемым оригинальным tcp сегментом
--dpi-desync-split-seqovl-pattern=<filename>|0xHEX ; чем заполнять фейковую часть overlap
--dpi-desync-badseq-increment=<int|0xHEX> ; инкремент sequence number для badseq. по умолчанию -10000
--dpi-desync-badack-increment=<int|0xHEX> ; инкремент ack sequence number для badseq. по умолчанию -66000
--dpi-desync-any-protocol=0|1 ; 0(default)=работать только по http request и tls clienthello 1=по всем непустым пакетам данных
@ -379,6 +381,26 @@ fakeknown отличается от fake тем, что применяется
disorder2 и split2 не предполагают отсылку фейк пакетов, поэтому опции ttl и fooling неактуальны.
seqovl добавляет в начало первой отсылаемой части оригинального пакета (1 часть для split и 2 часть для disorder)
seqovl байт со смещенным в минус sequence number на величину seqovl.
В случае split2 расчет идет на то, что предыдущий отсыл, если он был, уже попал в сокет серверного приложения,
поэтому новая пришедшая часть лишь частично находится в пределах текущего окна (in-window).
Спереди фейковая часть отбрасывается, а оставшаяся часть содержит оригинал и начинается с начала window,
поэтому попадает в сокет.
Серверное приложение получает все, что реально отсылает клиент, отбрасывая фейковую out-of-window часть.
Но DPI не может этого понять, поэтому у него происходит sequence десинхронизация.
Для disorder2 overlap идет на 2-ю часть пакета. Обязательно, чтобы seqovl был меньше split_pos, иначе
все отосланное будет передано в сокет сразу же, включая фейк, ломая протокол прикладного уровня.
При соблюдении этого условия 2-я часть пакета является полностью in-window,
поэтому серверная ОС принимает ее целиком, включая фейк. Но поскольку начальная часть данных из 1 пакета еще не принята,
то фейк и реальные данные остаются в памяти ядра, не отправляясь в серверное приложение. Как только приходит 1-я часть пакета,
она переписывает фейковую часть в памяти ядра. Ядро получает данные из 1 и 2 части, поэтому далее
идет отправка в сокет приложения. Таково поведение всех unix ОС - оставлять последние принятые данные.
Для windows серверов может быть наоборот, поэтому не факт, что такой вариант будет на них работать.
Метод позволяет обойтись без fooling и TTL. Фейки перемешаны с реальным данными.
split/disorder вместо split2/disorder2 по-прежнему добавляют дополнительные отдельные фейки.
Режимы десинхронизации hopbyhop, destopt и ipfrag1 (не путать с fooling !) относятся только к ipv6 и заключается
в добавлении хедера "hop-by-hop options" , "destination options" или "fragment" во все пакеты, попадающие под десинхронизацию.
Здесь надо обязательно понимать, что добавление хедера увеличивает размер пакета, потому не может быть применено

View File

@ -959,17 +959,41 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
case DESYNC_DISORDER2:
if (split_pos)
{
uint8_t fakeseg[DPI_DESYNC_MAX_FAKE_LEN+100];
size_t fakeseg_len;
uint8_t fakeseg[DPI_DESYNC_MAX_FAKE_LEN+100], *seg;
size_t seg_len;
if (params.desync_seqovl>=split_pos)
{
DLOG("seqovl>=split_pos. desync is not possible.\n")
return verdict;
}
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,
if (params.desync_seqovl)
{
seg_len = len_payload-split_pos+params.desync_seqovl;
if (seg_len>sizeof(fakeseg))
{
DLOG("seqovl is too large\n")
return verdict;
}
fill_pattern(fakeseg,params.desync_seqovl,params.seqovl_pattern,sizeof(params.seqovl_pattern));
memcpy(fakeseg+params.desync_seqovl,data_payload+split_pos,len_payload-split_pos);
seg = fakeseg;
}
else
{
seg = data_payload+split_pos;
seg_len = len_payload-split_pos;
}
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, net32_add(net32_add(tcphdr->th_seq,split_pos),-params.desync_seqovl), tcphdr->th_ack, tcphdr->th_win, scale_factor, timestamps,
ttl_orig,fooling_orig,params.desync_badseq_increment,params.desync_badseq_ack_increment,
data_payload+split_pos, len_payload-split_pos, pkt1, &pkt1_len))
seg, seg_len, pkt1, &pkt1_len))
return verdict;
DLOG("sending 2nd out-of-order tcp segment %zu-%zu len=%zu : ",split_pos,len_payload-1, len_payload-split_pos)
hexdump_limited_dlog(data_payload+split_pos,len_payload-split_pos,PKTDATA_MAXDUMP); DLOG("\n")
DLOG("sending 2nd out-of-order tcp segment %zu-%zu len=%zu seqovl=%u : ",split_pos,len_payload-1, len_payload-split_pos, params.desync_seqovl)
hexdump_limited_dlog(seg,seg_len,PKTDATA_MAXDUMP); DLOG("\n")
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
return verdict;
}
@ -977,18 +1001,17 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
if (desync_mode==DESYNC_DISORDER)
{
fakeseg_len = sizeof(fakeseg);
seg_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_fooling_mode,params.desync_badseq_increment,params.desync_badseq_ack_increment,
zeropkt, split_pos, fakeseg, &fakeseg_len))
zeropkt, split_pos, fakeseg, &seg_len))
return verdict;
DLOG("sending fake(1) 1st out-of-order tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos)
hexdump_limited_dlog(zeropkt,split_pos,PKTDATA_MAXDUMP); DLOG("\n")
if (!rawsend_rep((struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, fakeseg_len))
if (!rawsend_rep((struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, seg_len))
return verdict;
}
pkt1_len = sizeof(pkt1);
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,fooling_orig,params.desync_badseq_increment,params.desync_badseq_ack_increment,
@ -1003,7 +1026,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
{
DLOG("sending fake(2) 1st out-of-order tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos)
hexdump_limited_dlog(zeropkt,split_pos,PKTDATA_MAXDUMP); DLOG("\n")
if (!rawsend_rep((struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, fakeseg_len))
if (!rawsend_rep((struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, seg_len))
return verdict;
}
@ -1014,8 +1037,8 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
case DESYNC_SPLIT2:
if (split_pos)
{
uint8_t fakeseg[DPI_DESYNC_MAX_FAKE_LEN+100];
size_t fakeseg_len;
uint8_t fakeseg[DPI_DESYNC_MAX_FAKE_LEN+100],ovlseg[DPI_DESYNC_MAX_FAKE_LEN+100], *seg;
size_t fakeseg_len,seg_len;
if (desync_mode==DESYNC_SPLIT)
{
@ -1030,13 +1053,30 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
return verdict;
}
pkt1_len = sizeof(pkt1);
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->th_seq, tcphdr->th_ack, tcphdr->th_win, scale_factor, timestamps,
if (params.desync_seqovl)
{
seg_len = split_pos+params.desync_seqovl;
if (seg_len>sizeof(ovlseg))
{
DLOG("seqovl is too large")
return verdict;
}
fill_pattern(ovlseg,params.desync_seqovl,params.seqovl_pattern,sizeof(params.seqovl_pattern));
memcpy(ovlseg+params.desync_seqovl,data_payload,split_pos);
seg = ovlseg;
}
else
{
seg = data_payload;
seg_len = split_pos;
}
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, net32_add(tcphdr->th_seq,-params.desync_seqovl), tcphdr->th_ack, tcphdr->th_win, scale_factor, timestamps,
ttl_orig,fooling_orig,params.desync_badseq_increment,params.desync_badseq_ack_increment,
data_payload, split_pos, pkt1, &pkt1_len))
seg, seg_len, pkt1, &pkt1_len))
return verdict;
DLOG("sending 1st tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos)
hexdump_limited_dlog(data_payload,split_pos,PKTDATA_MAXDUMP); DLOG("\n")
DLOG("sending 1st tcp segment 0-%zu len=%zu seqovl=%u : ",split_pos-1, split_pos, params.desync_seqovl)
hexdump_limited_dlog(seg,seg_len,PKTDATA_MAXDUMP); DLOG("\n")
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
return verdict;
@ -1047,7 +1087,6 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
if (!rawsend_rep((struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, fakeseg_len))
return verdict;
}
if (split_pos<len_payload)
{
pkt1_len = sizeof(pkt1);

View File

@ -832,11 +832,13 @@ static void exithelp(void)
" --dpi-desync-split-pos=<1..%u>\t\t; data payload split position\n"
" --dpi-desync-split-http-req=method|host\t; split at specified logical part of plain http request\n"
" --dpi-desync-split-tls=sni|sniext\t\t; split at specified logical part of TLS ClientHello\n"
" --dpi-desync-split-seqovl=<int>\t\t; use sequence overlap before first sent original split segment\n"
" --dpi-desync-split-seqovl-pattern=<filename>|0xHEX ; pattern for the fake part of overlap\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\t; ip frag position starting from the transport header. multiple of 8, default %u.\n"
" --dpi-desync-badseq-increment=<int|0xHEX>\t; badseq fooling seq 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\t; 0(default)=desync only known protocols 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>|0xHEX\t; file containing fake http request\n"
" --dpi-desync-fake-tls=<filename>|0xHEX\t\t; file containing fake TLS ClientHello (for https)\n"
" --dpi-desync-fake-unknown=<filename>|0xHEX\t; file containing unknown protocol fake payload\n"
@ -1009,42 +1011,44 @@ int main(int argc, char **argv)
{"dpi-desync-split-pos",required_argument,0,0},// optidx=23
{"dpi-desync-split-http-req",required_argument,0,0 },// optidx=24
{"dpi-desync-split-tls",required_argument,0,0 },// optidx=25
{"dpi-desync-ipfrag-pos-tcp",required_argument,0,0},// optidx=26
{"dpi-desync-ipfrag-pos-udp",required_argument,0,0},// optidx=27
{"dpi-desync-badseq-increment",required_argument,0,0},// optidx=28
{"dpi-desync-badack-increment",required_argument,0,0},// optidx=29
{"dpi-desync-any-protocol",optional_argument,0,0},// optidx=30
{"dpi-desync-fake-http",required_argument,0,0},// optidx=31
{"dpi-desync-fake-tls",required_argument,0,0},// optidx=32
{"dpi-desync-fake-unknown",required_argument,0,0},// optidx=33
{"dpi-desync-fake-syndata",required_argument,0,0},// optidx=34
{"dpi-desync-fake-quic",required_argument,0,0},// optidx=35
{"dpi-desync-fake-wireguard",required_argument,0,0},// optidx=36
{"dpi-desync-fake-dht",required_argument,0,0},// optidx=37
{"dpi-desync-fake-unknown-udp",required_argument,0,0},// optidx=38
{"dpi-desync-udplen-increment",required_argument,0,0},// optidx=39
{"dpi-desync-udplen-pattern",required_argument,0,0},// optidx=40
{"dpi-desync-cutoff",required_argument,0,0},// optidx=41
{"dpi-desync-start",required_argument,0,0},// optidx=42
{"hostlist",required_argument,0,0}, // optidx=43
{"hostlist-exclude",required_argument,0,0}, // optidx=44
{"hostlist-auto",required_argument,0,0}, // optidx=45
{"hostlist-auto-fail-threshold",required_argument,0,0}, // optidx=46
{"hostlist-auto-fail-time",required_argument,0,0}, // optidx=47
{"hostlist-auto-retrans-threshold",required_argument,0,0}, // optidx=48
{"hostlist-auto-debug",required_argument,0,0}, // optidx=49
{"dpi-desync-split-seqovl",required_argument,0,0 },// optidx=26
{"dpi-desync-split-seqovl-pattern",required_argument,0,0 },// optidx=27
{"dpi-desync-ipfrag-pos-tcp",required_argument,0,0},// optidx=28
{"dpi-desync-ipfrag-pos-udp",required_argument,0,0},// optidx=29
{"dpi-desync-badseq-increment",required_argument,0,0},// optidx=30
{"dpi-desync-badack-increment",required_argument,0,0},// optidx=31
{"dpi-desync-any-protocol",optional_argument,0,0},// optidx=32
{"dpi-desync-fake-http",required_argument,0,0},// optidx=33
{"dpi-desync-fake-tls",required_argument,0,0},// optidx=34
{"dpi-desync-fake-unknown",required_argument,0,0},// optidx=35
{"dpi-desync-fake-syndata",required_argument,0,0},// optidx=36
{"dpi-desync-fake-quic",required_argument,0,0},// optidx=37
{"dpi-desync-fake-wireguard",required_argument,0,0},// optidx=38
{"dpi-desync-fake-dht",required_argument,0,0},// optidx=39
{"dpi-desync-fake-unknown-udp",required_argument,0,0},// optidx=40
{"dpi-desync-udplen-increment",required_argument,0,0},// optidx=41
{"dpi-desync-udplen-pattern",required_argument,0,0},// optidx=42
{"dpi-desync-cutoff",required_argument,0,0},// optidx=43
{"dpi-desync-start",required_argument,0,0},// optidx=43
{"hostlist",required_argument,0,0}, // optidx=44
{"hostlist-exclude",required_argument,0,0}, // optidx=45
{"hostlist-auto",required_argument,0,0}, // optidx=46
{"hostlist-auto-fail-threshold",required_argument,0,0}, // optidx=48
{"hostlist-auto-fail-time",required_argument,0,0}, // optidx=49
{"hostlist-auto-retrans-threshold",required_argument,0,0}, // optidx=50
{"hostlist-auto-debug",required_argument,0,0}, // optidx=51
#ifdef __linux__
{"bind-fix4",no_argument,0,0}, // optidx=50
{"bind-fix6",no_argument,0,0}, // optidx=51
{"bind-fix4",no_argument,0,0}, // optidx=52
{"bind-fix6",no_argument,0,0}, // optidx=53
#elif defined(__CYGWIN__)
{"wf-iface",required_argument,0,0}, // optidx=50
{"wf-l3",required_argument,0,0}, // optidx=51
{"wf-tcp",required_argument,0,0}, // optidx=52
{"wf-udp",required_argument,0,0}, // optidx=53
{"wf-raw",required_argument,0,0}, // optidx=54
{"wf-save",required_argument,0,0}, // optidx=55
{"ssid-filter",required_argument,0,0}, // optidx=56
{"wf-iface",required_argument,0,0}, // optidx=52
{"wf-l3",required_argument,0,0}, // optidx=53
{"wf-tcp",required_argument,0,0}, // optidx=54
{"wf-udp",required_argument,0,0}, // optidx=55
{"wf-raw",required_argument,0,0}, // optidx=56
{"wf-save",required_argument,0,0}, // optidx=57
{"ssid-filter",required_argument,0,0}, // optidx=58
#endif
{NULL,0,NULL,0}
};
@ -1297,7 +1301,22 @@ int main(int argc, char **argv)
exit_clean(1);
}
break;
case 26: /* dpi-desync-ipfrag-pos-tcp */
case 26: /* dpi-desync-split-seqovl */
if (sscanf(optarg,"%u",&params.desync_seqovl)<1)
{
fprintf(stderr, "dpi-desync-split-seqovl is not valid\n");
exit_clean(1);
}
break;
case 27: /* dpi-desync-split-seqovl-pattern */
{
char buf[sizeof(params.seqovl_pattern)];
size_t sz=sizeof(buf);
load_file_or_exit(optarg,buf,&sz);
fill_pattern(params.seqovl_pattern,sizeof(params.seqovl_pattern),buf,sz);
}
break;
case 28: /* dpi-desync-ipfrag-pos-tcp */
if (sscanf(optarg,"%u",&params.desync_ipfrag_pos_tcp)<1 || params.desync_ipfrag_pos_tcp<1 || params.desync_ipfrag_pos_tcp>DPI_DESYNC_MAX_FAKE_LEN)
{
fprintf(stderr, "dpi-desync-ipfrag-pos-tcp must be within 1..%u range\n",DPI_DESYNC_MAX_FAKE_LEN);
@ -1309,7 +1328,7 @@ int main(int argc, char **argv)
exit_clean(1);
}
break;
case 27: /* dpi-desync-ipfrag-pos-udp */
case 29: /* dpi-desync-ipfrag-pos-udp */
if (sscanf(optarg,"%u",&params.desync_ipfrag_pos_udp)<1 || params.desync_ipfrag_pos_udp<1 || params.desync_ipfrag_pos_udp>DPI_DESYNC_MAX_FAKE_LEN)
{
fprintf(stderr, "dpi-desync-ipfrag-pos-udp must be within 1..%u range\n",DPI_DESYNC_MAX_FAKE_LEN);
@ -1321,63 +1340,63 @@ int main(int argc, char **argv)
exit_clean(1);
}
break;
case 28: /* dpi-desync-badseq-increments */
case 30: /* dpi-desync-badseq-increments */
if (!parse_badseq_increment(optarg,&params.desync_badseq_increment))
{
fprintf(stderr, "dpi-desync-badseq-increment should be signed decimal or signed 0xHEX\n");
exit_clean(1);
}
break;
case 29: /* dpi-desync-badack-increment */
case 31: /* dpi-desync-badack-increment */
if (!parse_badseq_increment(optarg,&params.desync_badseq_ack_increment))
{
fprintf(stderr, "dpi-desync-badack-increment should be signed decimal or signed 0xHEX\n");
exit_clean(1);
}
break;
case 30: /* dpi-desync-any-protocol */
case 32: /* dpi-desync-any-protocol */
params.desync_any_proto = !optarg || atoi(optarg);
break;
case 31: /* dpi-desync-fake-http */
case 33: /* dpi-desync-fake-http */
params.fake_http_size = sizeof(params.fake_http);
load_file_or_exit(optarg,params.fake_http,&params.fake_http_size);
break;
case 32: /* dpi-desync-fake-tls */
case 34: /* dpi-desync-fake-tls */
params.fake_tls_size = sizeof(params.fake_tls);
load_file_or_exit(optarg,params.fake_tls,&params.fake_tls_size);
break;
case 33: /* dpi-desync-fake-unknown */
case 35: /* dpi-desync-fake-unknown */
params.fake_unknown_size = sizeof(params.fake_unknown);
load_file_or_exit(optarg,params.fake_unknown,&params.fake_unknown_size);
break;
case 34: /* dpi-desync-fake-syndata */
case 36: /* dpi-desync-fake-syndata */
params.fake_syndata_size = sizeof(params.fake_syndata);
load_file_or_exit(optarg,params.fake_syndata,&params.fake_syndata_size);
break;
case 35: /* dpi-desync-fake-quic */
case 37: /* dpi-desync-fake-quic */
params.fake_quic_size = sizeof(params.fake_quic);
load_file_or_exit(optarg,params.fake_quic,&params.fake_quic_size);
break;
case 36: /* dpi-desync-fake-wireguard */
case 38: /* dpi-desync-fake-wireguard */
params.fake_wg_size = sizeof(params.fake_wg);
load_file_or_exit(optarg,params.fake_wg,&params.fake_wg_size);
break;
case 37: /* dpi-desync-fake-dht */
case 39: /* dpi-desync-fake-dht */
params.fake_dht_size = sizeof(params.fake_dht);
load_file_or_exit(optarg,params.fake_dht,&params.fake_dht_size);
break;
case 38: /* dpi-desync-fake-unknown-udp */
case 40: /* dpi-desync-fake-unknown-udp */
params.fake_unknown_udp_size = sizeof(params.fake_unknown_udp);
load_file_or_exit(optarg,params.fake_unknown_udp,&params.fake_unknown_udp_size);
break;
case 39: /* dpi-desync-udplen-increment */
case 41: /* dpi-desync-udplen-increment */
if (sscanf(optarg,"%d",&params.udplen_increment)<1 || params.udplen_increment>0x7FFF || params.udplen_increment<-0x8000)
{
fprintf(stderr, "dpi-desync-udplen-increment must be integer within -32768..32767 range\n");
exit_clean(1);
}
break;
case 40: /* dpi-desync-udplen-pattern */
case 42: /* dpi-desync-udplen-pattern */
{
char buf[sizeof(params.udplen_pattern)];
size_t sz=sizeof(buf);
@ -1385,35 +1404,35 @@ int main(int argc, char **argv)
fill_pattern(params.udplen_pattern,sizeof(params.udplen_pattern),buf,sz);
}
break;
case 41: /* desync-cutoff */
case 43: /* desync-cutoff */
if (!parse_cutoff(optarg, &params.desync_cutoff, &params.desync_cutoff_mode))
{
fprintf(stderr, "invalid desync-cutoff value\n");
exit_clean(1);
}
break;
case 42: /* desync-start */
case 44: /* desync-start */
if (!parse_cutoff(optarg, &params.desync_start, &params.desync_start_mode))
{
fprintf(stderr, "invalid desync-start value\n");
exit_clean(1);
}
break;
case 43: /* hostlist */
case 45: /* hostlist */
if (!strlist_add(&params.hostlist_files, optarg))
{
fprintf(stderr, "strlist_add failed\n");
exit_clean(1);
}
break;
case 44: /* hostlist-exclude */
case 46: /* hostlist-exclude */
if (!strlist_add(&params.hostlist_exclude_files, optarg))
{
fprintf(stderr, "strlist_add failed\n");
exit_clean(1);
}
break;
case 45: /* hostlist-auto */
case 47: /* hostlist-auto */
if (*params.hostlist_auto_filename)
{
fprintf(stderr, "only one auto hostlist is supported\n");
@ -1446,7 +1465,7 @@ int main(int argc, char **argv)
strncpy(params.hostlist_auto_filename, optarg, sizeof(params.hostlist_auto_filename));
params.hostlist_auto_filename[sizeof(params.hostlist_auto_filename) - 1] = '\0';
break;
case 46: /* hostlist-auto-fail-threshold */
case 48: /* hostlist-auto-fail-threshold */
params.hostlist_auto_fail_threshold = (uint8_t)atoi(optarg);
if (params.hostlist_auto_fail_threshold<1 || params.hostlist_auto_fail_threshold>20)
{
@ -1454,7 +1473,7 @@ int main(int argc, char **argv)
exit_clean(1);
}
break;
case 47: /* hostlist-auto-fail-time */
case 49: /* hostlist-auto-fail-time */
params.hostlist_auto_fail_time = (uint8_t)atoi(optarg);
if (params.hostlist_auto_fail_time<1)
{
@ -1462,7 +1481,7 @@ int main(int argc, char **argv)
exit_clean(1);
}
break;
case 48: /* hostlist-auto-retrans-threshold */
case 50: /* hostlist-auto-retrans-threshold */
params.hostlist_auto_retrans_threshold = (uint8_t)atoi(optarg);
if (params.hostlist_auto_retrans_threshold<2 || params.hostlist_auto_retrans_threshold>10)
{
@ -1470,7 +1489,7 @@ int main(int argc, char **argv)
exit_clean(1);
}
break;
case 49: /* hostlist-auto-debug */
case 51: /* hostlist-auto-debug */
{
FILE *F = fopen(optarg,"a+t");
if (!F)
@ -1488,28 +1507,28 @@ int main(int argc, char **argv)
}
break;
#ifdef __linux__
case 50: /* bind-fix4 */
case 52: /* bind-fix4 */
params.bind_fix4 = true;
break;
case 51: /* bind-fix6 */
case 53: /* bind-fix6 */
params.bind_fix6 = true;
break;
#elif defined(__CYGWIN__)
case 50: /* wf-iface */
case 52: /* wf-iface */
if (!sscanf(optarg,"%u.%u",&IfIdx,&SubIfIdx))
{
fprintf(stderr, "bad value for --wf-iface\n");
exit_clean(1);
}
break;
case 51: /* wf-l3 */
case 53: /* wf-l3 */
if (!wf_make_l3(optarg,&wf_ipv4,&wf_ipv6))
{
fprintf(stderr, "bad value for --wf-l3\n");
exit_clean(1);
}
break;
case 52: /* wf-tcp */
case 54: /* wf-tcp */
hash_wf_tcp=hash_jen(optarg,strlen(optarg));
if (!wf_make_pf(optarg,"tcp","SrcPort",wf_pf_tcp_src,sizeof(wf_pf_tcp_src)) ||
!wf_make_pf(optarg,"tcp","DstPort",wf_pf_tcp_dst,sizeof(wf_pf_tcp_dst)))
@ -1518,7 +1537,7 @@ int main(int argc, char **argv)
exit_clean(1);
}
break;
case 53: /* wf-udp */
case 55: /* wf-udp */
hash_wf_udp=hash_jen(optarg,strlen(optarg));
if (!wf_make_pf(optarg,"udp","SrcPort",wf_pf_udp_src,sizeof(wf_pf_udp_src)) ||
!wf_make_pf(optarg,"udp","DstPort",wf_pf_udp_dst,sizeof(wf_pf_udp_dst)))
@ -1527,7 +1546,7 @@ int main(int argc, char **argv)
exit_clean(1);
}
break;
case 54: /* wf-raw */
case 56: /* wf-raw */
hash_wf_raw=hash_jen(optarg,strlen(optarg));
if (optarg[0]=='@')
{
@ -1541,11 +1560,11 @@ int main(int argc, char **argv)
windivert_filter[sizeof(windivert_filter) - 1] = '\0';
}
break;
case 55: /* wf-save */
case 57: /* wf-save */
strncpy(wf_save_file, optarg, sizeof(wf_save_file));
wf_save_file[sizeof(wf_save_file) - 1] = '\0';
break;
case 56: /* ssid-filter */
case 58: /* ssid-filter */
hash_ssid_filter=hash_jen(optarg,strlen(optarg));
{
char *e,*p = optarg;
@ -1617,7 +1636,7 @@ int main(int argc, char **argv)
if (hMutexArg && GetLastError()==ERROR_ALREADY_EXISTS)
{
CloseHandle(hMutexArg); hMutexArg = NULL;
printf("A copy of winws is already running with the same filter\n");
fprintf(stderr, "A copy of winws is already running with the same filter\n");
goto exiterr;
}

View File

@ -50,7 +50,7 @@ struct params_s
char hostspell[4];
enum dpi_desync_mode desync_mode0,desync_mode,desync_mode2;
bool desync_retrans,desync_skip_nosni,desync_any_proto;
unsigned int desync_repeats,desync_split_pos,desync_ipfrag_pos_tcp,desync_ipfrag_pos_udp;
unsigned int desync_repeats,desync_split_pos,desync_seqovl,desync_ipfrag_pos_tcp,desync_ipfrag_pos_udp;
enum httpreqpos desync_split_http_req;
enum tlspos desync_split_tls;
char desync_start_mode, desync_cutoff_mode; // n - packets, d - data packets, s - relative sequence
@ -60,7 +60,7 @@ struct params_s
uint32_t desync_fooling_mode;
uint32_t desync_fwmark; // unused in BSD
uint32_t desync_badseq_increment, desync_badseq_ack_increment;
uint8_t fake_http[1460],fake_tls[1460],fake_unknown[1460],fake_syndata[1460];
uint8_t fake_http[1460],fake_tls[1460],fake_unknown[1460],fake_syndata[1460],seqovl_pattern[1460];
uint8_t fake_unknown_udp[1472],udplen_pattern[1472],fake_quic[1472],fake_wg[1472],fake_dht[1472];
size_t fake_http_size,fake_tls_size,fake_quic_size,fake_wg_size,fake_dht_size,fake_unknown_size,fake_syndata_size,fake_unknown_udp_size;
int udplen_increment;