mirror of
https://github.com/bol-van/zapret.git
synced 2024-11-26 12:10:53 +03:00
Compare commits
6 Commits
fd4dc89360
...
dcae31fae8
Author | SHA1 | Date | |
---|---|---|---|
|
dcae31fae8 | ||
|
223895fffb | ||
|
4189becb02 | ||
|
a39a6226bd | ||
|
dcf6bf8cc7 | ||
|
d43d88b9d0 |
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.
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.
@ -882,7 +882,28 @@ pktws_check_domain_http_bypass_()
|
||||
ok=1
|
||||
}
|
||||
[ "$ret" != 0 -o "$SCANLEVEL" = force ] && {
|
||||
[ "$sec" = 0 ] && pktws_curl_test_update $1 $3 $s --hostcase && [ "$SCANLEVEL" = quick ] && return
|
||||
[ "$sec" = 0 ] && {
|
||||
pktws_curl_test_update $1 $3 $s --hostcase && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
ok=1
|
||||
}
|
||||
for pos in method host; do
|
||||
for hostcase in '' '--hostcase'; do
|
||||
pktws_curl_test_update $1 $3 $s --dpi-desync-split-http-req=$pos $hostcase && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
ok=1
|
||||
}
|
||||
done
|
||||
done
|
||||
}
|
||||
[ "$sec" = 1 ] && {
|
||||
for pos in sni sniext; do
|
||||
pktws_curl_test_update $1 $3 $s --dpi-desync-split-tls=$pos && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
ok=1
|
||||
}
|
||||
done
|
||||
}
|
||||
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
|
||||
@ -1047,6 +1068,13 @@ tpws_check_domain_http_bypass_()
|
||||
for mss in '' 88; do
|
||||
s3=${mss:+--mss=$mss --mss-pf=$HTTPS_PORT}
|
||||
for s2 in '' '--oob' '--disorder' '--oob --disorder'; do
|
||||
for pos in sni sniext; do
|
||||
s="--split-tls=$pos"
|
||||
tpws_curl_test_update $1 $3 $s $s2 $s3 && warn_mss $s3 && [ "$SCANLEVEL" != force ] && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
break
|
||||
}
|
||||
done
|
||||
for pos in 1 2 3 4 5 10 50; do
|
||||
s="--split-pos=$pos"
|
||||
tpws_curl_test_update $1 $3 $s $s2 $s3 && warn_mss $s3 && [ "$SCANLEVEL" != force ] && {
|
||||
@ -1055,8 +1083,8 @@ tpws_check_domain_http_bypass_()
|
||||
}
|
||||
done
|
||||
done
|
||||
for s2 in '--tlsrec=sni' '--tlsrec=sni --split-pos=10' '--tlsrec=sni --split-pos=10 --oob' \
|
||||
'--tlsrec=sni --split-pos=10 --disorder' '--tlsrec=sni --split-pos=10 --oob --disorder' \
|
||||
for s2 in '--tlsrec=sni' '--tlsrec=sni --split-tls=sni' '--tlsrec=sni --split-tls=sni --oob' \
|
||||
'--tlsrec=sni --split-tls=sni --disorder' '--tlsrec=sni --split-tls=sni --oob --disorder' \
|
||||
'--tlsrec=sni --split-pos=1' '--tlsrec=sni --split-pos=1 --oob' '--tlsrec=sni --split-pos=1 --disorder' \
|
||||
'--tlsrec=sni --split-pos=1 --oob --disorder'; do
|
||||
tpws_curl_test_update $1 $3 $s2 $s3 && warn_mss $s3 && [ "$SCANLEVEL" != force ] && {
|
||||
|
@ -287,3 +287,10 @@ nfqws: --qnum is mandatory, no more default queue 0
|
||||
v58
|
||||
|
||||
winws
|
||||
|
||||
v59
|
||||
|
||||
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
|
||||
|
@ -178,6 +178,8 @@ nfqws takes the following parameters:
|
||||
--dpi-desync-repeats=<N> ; send every desync packet N times
|
||||
--dpi-desync-skip-nosni=0|1 ; 1(default)=do not act on ClientHello without SNI (ESNI ?)
|
||||
--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-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
|
||||
@ -467,6 +469,12 @@ If nfqws receives a partial ClientHello it begins reassemble session. Packets ar
|
||||
Then the first packet goes through desync using fully reassembled message. Other packets are sent
|
||||
without desync. On any error reassemble is cancelled and all delayed packets are sent immediately without desync.
|
||||
|
||||
There is special support for all tcp split options for multi segment TLS. Split position is treated
|
||||
as message-oriented, not packet oriented. For example, if your client sends TLS ClientHello with size 2000
|
||||
and SNI is at 1700, desync mode is fake,split2, then fake is sent first, then original first segment
|
||||
and the last splitted segment. 3 segments total.
|
||||
|
||||
|
||||
### UDP support
|
||||
|
||||
UDP attacks are limited. Its not possible to fragment UDP on transport level, only on network (ip) level.
|
||||
@ -587,6 +595,7 @@ tpws is transparent proxy.
|
||||
--hostlist-auto-debug=<logfile> ; debug auto hostlist positives
|
||||
|
||||
--split-http-req=method|host ; split http request at specified logical position.
|
||||
--split-tls=sni|sniext ; split at specified logical part of TLS ClientHello
|
||||
--split-pos=<numeric_offset> ; split at specified pos. split-http-req takes precedence over split-pos for http reqs.
|
||||
--split-any-protocol ; split not only http and https
|
||||
--disorder[=http|tls] ; when splitting simulate sending second fragment first
|
||||
@ -602,7 +611,7 @@ tpws is transparent proxy.
|
||||
--methodspace ; add extra space after method
|
||||
--methodeol ; add end-of-line before method
|
||||
--unixeol ; replace 0D0A to 0A
|
||||
--tlsrec=sni ; make 2 TLS records. split at SNI. don't split if SNI is not present.
|
||||
--tlsrec=sni|sniext ; make 2 TLS records. split at specified logical part. don't split if SNI is not present.
|
||||
--tlsrec-pos=<pos> ; make 2 TLS records. split at specified pos
|
||||
--mss=<int> ; set client MSS. forces server to split messages but significantly decreases speed !
|
||||
--mss-pf=[~]port1[-port2] ; MSS port filter. ~ means negation
|
||||
|
@ -1,4 +1,4 @@
|
||||
zapret v.58
|
||||
zapret v.59
|
||||
|
||||
English
|
||||
-------
|
||||
@ -251,6 +251,8 @@ nfqws
|
||||
--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> ; (только для split*, disorder*) разбивать пакет на указанной позиции
|
||||
--dpi-desync-split-http-req=method|host ; разбивка http request на указанном логическом месте
|
||||
--dpi-desync-split-tls=sni|sniext ; разбивка tls client hello на указанном логическом месте
|
||||
--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=по всем непустым пакетам данных
|
||||
@ -538,6 +540,13 @@ chrome рандомизирует фингерпринт TLS. SNI может о
|
||||
на основании полностью собранного ClientHello. Остальные пакеты отсылаются без десинхронизации.
|
||||
При любой ошибке в процессе сборки задержанные пакеты немедленно отсылаются в сеть, а десинхронизация отменяется.
|
||||
|
||||
Есть специальная поддержка всех вариантов tcp сплита для многосегментного TLS.
|
||||
Если указать позицию сплита больше длины первого пакета или использовать --dpi-desync-split-tls,
|
||||
то разбивка происходит не обязательно первого пакета, а того, на который пришлась итоговая позиция.
|
||||
Если, допустим, клиент послал TLS ClientHello длиной 2000, а SNI начинается с 1700,
|
||||
и заданы опции fake,split2, то перед первым пакетом идет fake, затем первый пакет в оригинале,
|
||||
а последний пакет разбивается на 2 сегмента. В итоге имеем фейк в начале и 3 реальных сегмента.
|
||||
|
||||
ПОДДЕРЖКА UDP
|
||||
Атаки на udp более ограничены в возможностях. udp нельзя фрагментировать иначе, чем на уровне ip.
|
||||
Для UDP действуют только режимы десинхронизации fake,hopbyhop,destopt,ipfrag1,ipfrag2,udplen,tamper.
|
||||
@ -676,7 +685,7 @@ tpws - это transparent proxy.
|
||||
--methodspace ; добавить пробел после метода : "GET /" => "GET /"
|
||||
--methodeol ; добавить перевод строки перед методом : "GET /" => "\r\nGET /"
|
||||
--unixeol ; конвертировать 0D0A в 0A и использовать везде 0A
|
||||
--tlsrec=sni ; разбивка TLS ClientHello на 2 TLS records. режем между 1 и 2 символами hostname в SNI. Если SNI нет - отмена.
|
||||
--tlsrec=sni|sniext ; разбивка TLS ClientHello на 2 TLS records. режем между 1 и 2 символами hostname в SNI или между байтами длины SNI extension. Если SNI нет - отмена.
|
||||
--tlsrec-pos=<pos> ; разбивка TLS ClientHello на 2 TLS records. режем на указанной позиции, если длина слишком мелкая - на позиции 1.
|
||||
--mss=<int> ; установить MSS для клиента. может заставить сервер разбивать ответы, но существенно снижает скорость
|
||||
--mss-pf=[~]port1[-port2] ; применять MSS только к портам назначения, подпадающим под фильтр. ~ означает инверсию
|
||||
|
95
nfq/desync.c
95
nfq/desync.c
@ -437,7 +437,27 @@ static bool process_desync_interval(t_ctrack *ctrack)
|
||||
|
||||
static bool replay_queue(struct rawpacket_tailhead *q);
|
||||
|
||||
static uint8_t dpi_desync_tcp_packet_play(bool replay, uint32_t fwmark, const char *ifout, uint8_t *data_pkt, size_t *len_pkt, struct ip *ip, struct ip6_hdr *ip6hdr, struct tcphdr *tcphdr, size_t transport_len, uint8_t *data_payload, size_t len_payload)
|
||||
static size_t pos_normalize(size_t split_pos, size_t reasm_offset, size_t len_payload)
|
||||
{
|
||||
size_t rsplit_pos = split_pos;
|
||||
// normalize split pos to current packet
|
||||
split_pos=(split_pos>reasm_offset && (split_pos-reasm_offset)<len_payload) ? split_pos-reasm_offset : 0;
|
||||
if (rsplit_pos)
|
||||
{
|
||||
if (split_pos==rsplit_pos)
|
||||
DLOG("split pos %zu\n",split_pos)
|
||||
else
|
||||
{
|
||||
if (split_pos)
|
||||
DLOG("split pos was normalized to packet data offset : %zu -> %zu\n",rsplit_pos,split_pos)
|
||||
else
|
||||
DLOG("split pos %zu is outside of this packet %zu-%zu\n",rsplit_pos,reasm_offset,reasm_offset+len_payload)
|
||||
}
|
||||
}
|
||||
return split_pos;
|
||||
}
|
||||
|
||||
static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint32_t fwmark, const char *ifout, uint8_t *data_pkt, size_t *len_pkt, struct ip *ip, struct ip6_hdr *ip6hdr, struct tcphdr *tcphdr, size_t transport_len, uint8_t *data_payload, size_t len_payload)
|
||||
{
|
||||
uint8_t verdict=VERDICT_PASS;
|
||||
|
||||
@ -634,7 +654,8 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, uint32_t fwmark, const ch
|
||||
uint8_t *p, *phost;
|
||||
const uint8_t *rdata_payload = data_payload;
|
||||
size_t rlen_payload = len_payload;
|
||||
|
||||
size_t split_pos;
|
||||
|
||||
if (replay)
|
||||
{
|
||||
rdata_payload = ctrack_replay->reasm_orig.packet;
|
||||
@ -655,7 +676,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, uint32_t fwmark, const ch
|
||||
|
||||
// we do not reassemble http
|
||||
reasm_orig_cancel(ctrack);
|
||||
|
||||
|
||||
forced_wssize_cutoff(ctrack);
|
||||
fake = params.fake_http;
|
||||
fake_size = params.fake_http_size;
|
||||
@ -679,6 +700,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, uint32_t fwmark, const ch
|
||||
DLOG("req retrans : tcp seq interval %u-%u\n",ctrack->req_seq_start,ctrack->req_seq_end);
|
||||
}
|
||||
}
|
||||
split_pos = HttpPos(params.desync_split_http_req, params.desync_split_pos, rdata_payload, rlen_payload);
|
||||
bKnownProtocol = true;
|
||||
}
|
||||
else if (IsTLSClientHello(rdata_payload,rlen_payload,TLS_PARTIALS_ENABLE))
|
||||
@ -722,9 +744,9 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, uint32_t fwmark, const ch
|
||||
if (!ReasmIsEmpty(&ctrack->reasm_orig))
|
||||
{
|
||||
verdict_tcp_csum_fix(verdict, tcphdr, transport_len, ip, ip6hdr);
|
||||
if (rawpacket_queue(&ctrack->delayed, &dst, desync_fwmark, ifout, data_pkt, *len_pkt))
|
||||
if (rawpacket_queue(&ctrack->delayed, &dst, desync_fwmark, ifout, data_pkt, *len_pkt, len_payload))
|
||||
{
|
||||
DLOG("DELAY desync until reasm is complete (%u)\n", rawpacket_queue_count(&ctrack->delayed));
|
||||
DLOG("DELAY desync until reasm is complete (#%u)\n", rawpacket_queue_count(&ctrack->delayed));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -750,8 +772,11 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, uint32_t fwmark, const ch
|
||||
|
||||
fake = params.fake_tls;
|
||||
fake_size = params.fake_tls_size;
|
||||
split_pos = TLSPos(params.desync_split_tls, params.desync_split_pos, rdata_payload, rlen_payload, 0);
|
||||
bKnownProtocol = true;
|
||||
}
|
||||
else
|
||||
split_pos=params.desync_split_pos;
|
||||
|
||||
reasm_orig_cancel(ctrack);
|
||||
rdata_payload=NULL;
|
||||
@ -842,6 +867,9 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, uint32_t fwmark, const ch
|
||||
print_sockaddr((struct sockaddr *)&dst);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (!split_pos || split_pos>rlen_payload) split_pos=1;
|
||||
split_pos=pos_normalize(split_pos,reasm_offset,len_payload);
|
||||
|
||||
enum dpi_desync_mode desync_mode = params.desync_mode;
|
||||
uint32_t fooling_orig = FOOL_NONE;
|
||||
@ -852,6 +880,11 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, uint32_t fwmark, const ch
|
||||
switch(desync_mode)
|
||||
{
|
||||
case DESYNC_FAKE_KNOWN:
|
||||
if (reasm_offset)
|
||||
{
|
||||
desync_mode = params.desync_mode2;
|
||||
break;
|
||||
}
|
||||
if (!bKnownProtocol)
|
||||
{
|
||||
DLOG("not applying fake because of unknown protocol\n");
|
||||
@ -859,6 +892,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, uint32_t fwmark, const ch
|
||||
break;
|
||||
}
|
||||
case DESYNC_FAKE:
|
||||
if (reasm_offset) break;
|
||||
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,
|
||||
fake, fake_size, pkt1, &pkt1_len))
|
||||
@ -871,6 +905,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, uint32_t fwmark, const ch
|
||||
break;
|
||||
case DESYNC_RST:
|
||||
case DESYNC_RSTACK:
|
||||
if (reasm_offset) break;
|
||||
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_fooling_mode,params.desync_badseq_increment,params.desync_badseq_ack_increment,
|
||||
NULL, 0, pkt1, &pkt1_len))
|
||||
@ -884,7 +919,9 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, uint32_t fwmark, const ch
|
||||
case DESYNC_DESTOPT:
|
||||
case DESYNC_IPFRAG1:
|
||||
fooling_orig = (desync_mode==DESYNC_HOPBYHOP) ? FOOL_HOPBYHOP : (desync_mode==DESYNC_DESTOPT) ? FOOL_DESTOPT : FOOL_IPFRAG1;
|
||||
if (ip6hdr && (params.desync_mode2==DESYNC_NONE || !desync_valid_second_stage_tcp(params.desync_mode2)))
|
||||
desync_mode = params.desync_mode2;
|
||||
if (ip6hdr && (desync_mode==DESYNC_NONE || !desync_valid_second_stage_tcp(desync_mode) ||
|
||||
(!split_pos && (desync_mode==DESYNC_SPLIT || desync_mode==DESYNC_SPLIT2 || desync_mode==DESYNC_DISORDER || desync_mode==DESYNC_DISORDER2))))
|
||||
{
|
||||
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,0,0,
|
||||
@ -898,7 +935,6 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, uint32_t fwmark, const ch
|
||||
// this mode is final, no other options available
|
||||
return VERDICT_DROP;
|
||||
}
|
||||
desync_mode = params.desync_mode2;
|
||||
}
|
||||
|
||||
if (b)
|
||||
@ -916,12 +952,12 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, uint32_t fwmark, const ch
|
||||
desync_mode = params.desync_mode2;
|
||||
}
|
||||
|
||||
size_t split_pos=len_payload>params.desync_split_pos ? params.desync_split_pos : 1;
|
||||
pkt1_len = sizeof(pkt1);
|
||||
switch(desync_mode)
|
||||
{
|
||||
case DESYNC_DISORDER:
|
||||
case DESYNC_DISORDER2:
|
||||
if (split_pos)
|
||||
{
|
||||
uint8_t fakeseg[DPI_DESYNC_MAX_FAKE_LEN+100];
|
||||
size_t fakeseg_len;
|
||||
@ -976,6 +1012,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, uint32_t fwmark, const ch
|
||||
break;
|
||||
case DESYNC_SPLIT:
|
||||
case DESYNC_SPLIT2:
|
||||
if (split_pos)
|
||||
{
|
||||
uint8_t fakeseg[DPI_DESYNC_MAX_FAKE_LEN+100];
|
||||
size_t fakeseg_len;
|
||||
@ -1028,6 +1065,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, uint32_t fwmark, const ch
|
||||
}
|
||||
break;
|
||||
case DESYNC_IPFRAG2:
|
||||
if (!reasm_offset)
|
||||
{
|
||||
verdict_tcp_csum_fix(verdict, tcphdr, transport_len, ip, ip6hdr);
|
||||
|
||||
@ -1091,10 +1129,13 @@ static bool quic_reasm_cancel(t_ctrack *ctrack, const char *reason)
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t dpi_desync_udp_packet_play(bool replay, uint32_t fwmark, const char *ifout, uint8_t *data_pkt, size_t *len_pkt, struct ip *ip, struct ip6_hdr *ip6hdr, struct udphdr *udphdr, size_t transport_len, uint8_t *data_payload, size_t len_payload)
|
||||
static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint32_t fwmark, const char *ifout, uint8_t *data_pkt, size_t *len_pkt, struct ip *ip, struct ip6_hdr *ip6hdr, struct udphdr *udphdr, size_t transport_len, uint8_t *data_payload, size_t len_payload)
|
||||
{
|
||||
uint8_t verdict=VERDICT_PASS;
|
||||
|
||||
// no need to desync middle packets in reasm session
|
||||
if (reasm_offset) return verdict;
|
||||
|
||||
t_ctrack *ctrack=NULL, *ctrack_replay=NULL;
|
||||
bool bReverse=false;
|
||||
|
||||
@ -1207,9 +1248,9 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, uint32_t fwmark, const ch
|
||||
if (!ReasmIsEmpty(&ctrack->reasm_orig))
|
||||
{
|
||||
verdict_udp_csum_fix(verdict, udphdr, transport_len, ip, ip6hdr);
|
||||
if (rawpacket_queue(&ctrack->delayed, &dst, desync_fwmark, ifout, data_pkt, *len_pkt))
|
||||
if (rawpacket_queue(&ctrack->delayed, &dst, desync_fwmark, ifout, data_pkt, *len_pkt, len_payload))
|
||||
{
|
||||
DLOG("DELAY desync until reasm is complete (%u)\n", rawpacket_queue_count(&ctrack->delayed));
|
||||
DLOG("DELAY desync until reasm is complete (#%u)\n", rawpacket_queue_count(&ctrack->delayed));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1512,7 +1553,7 @@ static void packet_debug(bool replay, uint8_t proto, const struct ip *ip, const
|
||||
}
|
||||
|
||||
|
||||
static uint8_t dpi_desync_packet_play(bool replay, uint32_t fwmark, const char *ifout, uint8_t *data_pkt, size_t *len_pkt)
|
||||
static uint8_t dpi_desync_packet_play(bool replay, size_t reasm_offset, uint32_t fwmark, const char *ifout, uint8_t *data_pkt, size_t *len_pkt)
|
||||
{
|
||||
struct ip *ip;
|
||||
struct ip6_hdr *ip6hdr;
|
||||
@ -1532,14 +1573,14 @@ static uint8_t dpi_desync_packet_play(bool replay, uint32_t fwmark, const char *
|
||||
case IPPROTO_TCP:
|
||||
if (tcphdr)
|
||||
{
|
||||
verdict = dpi_desync_tcp_packet_play(replay, fwmark, ifout, data_pkt, len_pkt, ip, ip6hdr, tcphdr, transport_len, data_payload, len_payload);
|
||||
verdict = dpi_desync_tcp_packet_play(replay, reasm_offset, fwmark, ifout, data_pkt, len_pkt, ip, ip6hdr, tcphdr, transport_len, data_payload, len_payload);
|
||||
verdict_tcp_csum_fix(verdict, tcphdr, transport_len, ip, ip6hdr);
|
||||
}
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
if (udphdr)
|
||||
{
|
||||
verdict = dpi_desync_udp_packet_play(replay, fwmark, ifout, data_pkt, len_pkt, ip, ip6hdr, udphdr, transport_len, data_payload, len_payload);
|
||||
verdict = dpi_desync_udp_packet_play(replay, reasm_offset, fwmark, ifout, data_pkt, len_pkt, ip, ip6hdr, udphdr, transport_len, data_payload, len_payload);
|
||||
verdict_udp_csum_fix(verdict, udphdr, transport_len, ip, ip6hdr);
|
||||
}
|
||||
break;
|
||||
@ -1549,37 +1590,35 @@ static uint8_t dpi_desync_packet_play(bool replay, uint32_t fwmark, const char *
|
||||
}
|
||||
uint8_t dpi_desync_packet(uint32_t fwmark, const char *ifout, uint8_t *data_pkt, size_t *len_pkt)
|
||||
{
|
||||
return dpi_desync_packet_play(false, fwmark, ifout, data_pkt, len_pkt);
|
||||
return dpi_desync_packet_play(false, 0, fwmark, ifout, data_pkt, len_pkt);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static bool replay_queue(struct rawpacket_tailhead *q)
|
||||
{
|
||||
struct rawpacket *rp = rawpacket_dequeue(q);
|
||||
if (rp)
|
||||
struct rawpacket *rp;
|
||||
size_t offset;
|
||||
unsigned int i;
|
||||
bool b = true;
|
||||
for (i=1,offset=0 ; (rp=rawpacket_dequeue(q)) ; offset+=rp->len_payload, rawpacket_free(rp), i++)
|
||||
{
|
||||
DLOG("REPLAYING first delayed packet\n")
|
||||
bool b = true;
|
||||
uint8_t verdict = dpi_desync_packet_play(true, rp->fwmark, rp->ifout, rp->packet, &rp->len);
|
||||
DLOG("REPLAYING delayed packet #%u offset %zu\n",i,offset)
|
||||
uint8_t verdict = dpi_desync_packet_play(true, offset, rp->fwmark, rp->ifout, rp->packet, &rp->len);
|
||||
switch(verdict & VERDICT_MASK)
|
||||
{
|
||||
case VERDICT_MODIFY:
|
||||
DLOG("SENDING first delayed packet modified\n")
|
||||
DLOG("SENDING delayed packet #%u modified\n", i)
|
||||
b &= rawsend_rp(rp);
|
||||
break;
|
||||
case VERDICT_PASS:
|
||||
DLOG("SENDING first delayed packet unmodified\n")
|
||||
DLOG("SENDING delayed packet #%u unmodified\n", i)
|
||||
b &= rawsend_rp(rp);
|
||||
break;
|
||||
case VERDICT_DROP:
|
||||
DLOG("DROPPING first delayed packet\n")
|
||||
DLOG("DROPPING delayed packet #%u\n", i)
|
||||
break;
|
||||
}
|
||||
rawpacket_free(rp);
|
||||
DLOG("SENDING %u remaining delayed packets\n", rawpacket_queue_count(q))
|
||||
b &= rawsend_queue(q);
|
||||
return b;
|
||||
}
|
||||
return false;
|
||||
return b;
|
||||
}
|
||||
|
172
nfq/nfqws.c
172
nfq/nfqws.c
@ -791,6 +791,8 @@ static void exithelp(void)
|
||||
" --dpi-desync-repeats=<N>\t\t\t; send every desync packet N times\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\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-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"
|
||||
@ -828,6 +830,26 @@ static void exithelp_clean(void)
|
||||
exithelp();
|
||||
}
|
||||
|
||||
bool parse_httpreqpos(const char *s, enum httpreqpos *pos)
|
||||
{
|
||||
if (!strcmp(s, "method"))
|
||||
*pos = httpreqpos_method;
|
||||
else if (!strcmp(s, "host"))
|
||||
*pos = httpreqpos_host;
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
bool parse_tlspos(const char *s, enum tlspos *pos)
|
||||
{
|
||||
if (!strcmp(s, "sni"))
|
||||
*pos = tlspos_sni;
|
||||
else if (!strcmp(s, "sniext"))
|
||||
*pos = tlspos_sniext;
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
@ -943,41 +965,43 @@ int main(int argc, char **argv)
|
||||
{"dpi-desync-repeats",required_argument,0,0}, // optidx=21
|
||||
{"dpi-desync-skip-nosni",optional_argument,0,0},// optidx=22
|
||||
{"dpi-desync-split-pos",required_argument,0,0},// optidx=23
|
||||
{"dpi-desync-ipfrag-pos-tcp",required_argument,0,0},// optidx=24
|
||||
{"dpi-desync-ipfrag-pos-udp",required_argument,0,0},// optidx=25
|
||||
{"dpi-desync-badseq-increment",required_argument,0,0},// optidx=26
|
||||
{"dpi-desync-badack-increment",required_argument,0,0},// optidx=27
|
||||
{"dpi-desync-any-protocol",optional_argument,0,0},// optidx=28
|
||||
{"dpi-desync-fake-http",required_argument,0,0},// optidx=29
|
||||
{"dpi-desync-fake-tls",required_argument,0,0},// optidx=30
|
||||
{"dpi-desync-fake-unknown",required_argument,0,0},// optidx=31
|
||||
{"dpi-desync-fake-syndata",required_argument,0,0},// optidx=32
|
||||
{"dpi-desync-fake-quic",required_argument,0,0},// optidx=33
|
||||
{"dpi-desync-fake-wireguard",required_argument,0,0},// optidx=34
|
||||
{"dpi-desync-fake-dht",required_argument,0,0},// optidx=35
|
||||
{"dpi-desync-fake-unknown-udp",required_argument,0,0},// optidx=36
|
||||
{"dpi-desync-udplen-increment",required_argument,0,0},// optidx=37
|
||||
{"dpi-desync-udplen-pattern",required_argument,0,0},// optidx=38
|
||||
{"dpi-desync-cutoff",required_argument,0,0},// optidx=39
|
||||
{"dpi-desync-start",required_argument,0,0},// optidx=40
|
||||
{"hostlist",required_argument,0,0}, // optidx=41
|
||||
{"hostlist-exclude",required_argument,0,0}, // optidx=42
|
||||
{"hostlist-auto",required_argument,0,0}, // optidx=43
|
||||
{"hostlist-auto-fail-threshold",required_argument,0,0}, // optidx=44
|
||||
{"hostlist-auto-fail-time",required_argument,0,0}, // optidx=45
|
||||
{"hostlist-auto-retrans-threshold",required_argument,0,0}, // optidx=46
|
||||
{"hostlist-auto-debug",required_argument,0,0}, // optidx=47
|
||||
{"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
|
||||
|
||||
#ifdef __linux__
|
||||
{"bind-fix4",no_argument,0,0}, // optidx=48
|
||||
{"bind-fix6",no_argument,0,0}, // optidx=49
|
||||
{"bind-fix4",no_argument,0,0}, // optidx=50
|
||||
{"bind-fix6",no_argument,0,0}, // optidx=51
|
||||
#elif defined(__CYGWIN__)
|
||||
{"wf-iface",required_argument,0,0}, // optidx=48
|
||||
{"wf-l3",required_argument,0,0}, // optidx=49
|
||||
{"wf-tcp",required_argument,0,0}, // optidx=50
|
||||
{"wf-udp",required_argument,0,0}, // optidx=51
|
||||
{"wf-raw",required_argument,0,0}, // optidx=52
|
||||
{"wf-save",required_argument,0,0}, // optidx=53
|
||||
{"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
|
||||
#endif
|
||||
{NULL,0,NULL,0}
|
||||
};
|
||||
@ -1210,13 +1234,27 @@ int main(int argc, char **argv)
|
||||
params.desync_skip_nosni = !optarg || atoi(optarg);
|
||||
break;
|
||||
case 23: /* dpi-desync-split-pos */
|
||||
if (sscanf(optarg,"%u",¶ms.desync_split_pos)<1 || params.desync_split_pos<1 || params.desync_split_pos>DPI_DESYNC_MAX_FAKE_LEN)
|
||||
if (sscanf(optarg,"%u",¶ms.desync_split_pos)<1 || params.desync_split_pos<1)
|
||||
{
|
||||
fprintf(stderr, "dpi-desync-split-pos must be within 1..%u range\n",DPI_DESYNC_MAX_FAKE_LEN);
|
||||
fprintf(stderr, "dpi-desync-split-pos is not valid\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 24: /* dpi-desync-ipfrag-pos-tcp */
|
||||
case 24: /* dpi-desync-split-http-req */
|
||||
if (!parse_httpreqpos(optarg, ¶ms.desync_split_http_req))
|
||||
{
|
||||
fprintf(stderr, "Invalid argument for dpi-desync-split-http-req\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 25: /* dpi-desync-split-tls */
|
||||
if (!parse_tlspos(optarg, ¶ms.desync_split_tls))
|
||||
{
|
||||
fprintf(stderr, "Invalid argument for dpi-desync-split-tls\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 26: /* dpi-desync-ipfrag-pos-tcp */
|
||||
if (sscanf(optarg,"%u",¶ms.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);
|
||||
@ -1228,7 +1266,7 @@ int main(int argc, char **argv)
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 25: /* dpi-desync-ipfrag-pos-udp */
|
||||
case 27: /* dpi-desync-ipfrag-pos-udp */
|
||||
if (sscanf(optarg,"%u",¶ms.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);
|
||||
@ -1240,63 +1278,63 @@ int main(int argc, char **argv)
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 26: /* dpi-desync-badseq-increments */
|
||||
case 28: /* dpi-desync-badseq-increments */
|
||||
if (!parse_badseq_increment(optarg,¶ms.desync_badseq_increment))
|
||||
{
|
||||
fprintf(stderr, "dpi-desync-badseq-increment should be signed decimal or signed 0xHEX\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 27: /* dpi-desync-badack-increment */
|
||||
case 29: /* dpi-desync-badack-increment */
|
||||
if (!parse_badseq_increment(optarg,¶ms.desync_badseq_ack_increment))
|
||||
{
|
||||
fprintf(stderr, "dpi-desync-badack-increment should be signed decimal or signed 0xHEX\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 28: /* dpi-desync-any-protocol */
|
||||
case 30: /* dpi-desync-any-protocol */
|
||||
params.desync_any_proto = !optarg || atoi(optarg);
|
||||
break;
|
||||
case 29: /* dpi-desync-fake-http */
|
||||
case 31: /* dpi-desync-fake-http */
|
||||
params.fake_http_size = sizeof(params.fake_http);
|
||||
load_file_or_exit(optarg,params.fake_http,¶ms.fake_http_size);
|
||||
break;
|
||||
case 30: /* dpi-desync-fake-tls */
|
||||
case 32: /* dpi-desync-fake-tls */
|
||||
params.fake_tls_size = sizeof(params.fake_tls);
|
||||
load_file_or_exit(optarg,params.fake_tls,¶ms.fake_tls_size);
|
||||
break;
|
||||
case 31: /* dpi-desync-fake-unknown */
|
||||
case 33: /* dpi-desync-fake-unknown */
|
||||
params.fake_unknown_size = sizeof(params.fake_unknown);
|
||||
load_file_or_exit(optarg,params.fake_unknown,¶ms.fake_unknown_size);
|
||||
break;
|
||||
case 32: /* dpi-desync-fake-syndata */
|
||||
case 34: /* dpi-desync-fake-syndata */
|
||||
params.fake_syndata_size = sizeof(params.fake_syndata);
|
||||
load_file_or_exit(optarg,params.fake_syndata,¶ms.fake_syndata_size);
|
||||
break;
|
||||
case 33: /* dpi-desync-fake-quic */
|
||||
case 35: /* dpi-desync-fake-quic */
|
||||
params.fake_quic_size = sizeof(params.fake_quic);
|
||||
load_file_or_exit(optarg,params.fake_quic,¶ms.fake_quic_size);
|
||||
break;
|
||||
case 34: /* dpi-desync-fake-wireguard */
|
||||
case 36: /* dpi-desync-fake-wireguard */
|
||||
params.fake_wg_size = sizeof(params.fake_wg);
|
||||
load_file_or_exit(optarg,params.fake_wg,¶ms.fake_wg_size);
|
||||
break;
|
||||
case 35: /* dpi-desync-fake-dht */
|
||||
case 37: /* dpi-desync-fake-dht */
|
||||
params.fake_dht_size = sizeof(params.fake_dht);
|
||||
load_file_or_exit(optarg,params.fake_dht,¶ms.fake_dht_size);
|
||||
break;
|
||||
case 36: /* dpi-desync-fake-unknown-udp */
|
||||
case 38: /* dpi-desync-fake-unknown-udp */
|
||||
params.fake_unknown_udp_size = sizeof(params.fake_unknown_udp);
|
||||
load_file_or_exit(optarg,params.fake_unknown_udp,¶ms.fake_unknown_udp_size);
|
||||
break;
|
||||
case 37: /* dpi-desync-udplen-increment */
|
||||
case 39: /* dpi-desync-udplen-increment */
|
||||
if (sscanf(optarg,"%d",¶ms.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 38: /* dpi-desync-udplen-pattern */
|
||||
case 40: /* dpi-desync-udplen-pattern */
|
||||
{
|
||||
char buf[sizeof(params.udplen_pattern)];
|
||||
size_t sz=sizeof(buf);
|
||||
@ -1304,35 +1342,35 @@ int main(int argc, char **argv)
|
||||
fill_pattern(params.udplen_pattern,sizeof(params.udplen_pattern),buf,sz);
|
||||
}
|
||||
break;
|
||||
case 39: /* desync-cutoff */
|
||||
case 41: /* desync-cutoff */
|
||||
if (!parse_cutoff(optarg, ¶ms.desync_cutoff, ¶ms.desync_cutoff_mode))
|
||||
{
|
||||
fprintf(stderr, "invalid desync-cutoff value\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 40: /* desync-start */
|
||||
case 42: /* desync-start */
|
||||
if (!parse_cutoff(optarg, ¶ms.desync_start, ¶ms.desync_start_mode))
|
||||
{
|
||||
fprintf(stderr, "invalid desync-start value\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 41: /* hostlist */
|
||||
case 43: /* hostlist */
|
||||
if (!strlist_add(¶ms.hostlist_files, optarg))
|
||||
{
|
||||
fprintf(stderr, "strlist_add failed\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 42: /* hostlist-exclude */
|
||||
case 44: /* hostlist-exclude */
|
||||
if (!strlist_add(¶ms.hostlist_exclude_files, optarg))
|
||||
{
|
||||
fprintf(stderr, "strlist_add failed\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 43: /* hostlist-auto */
|
||||
case 45: /* hostlist-auto */
|
||||
if (*params.hostlist_auto_filename)
|
||||
{
|
||||
fprintf(stderr, "only one auto hostlist is supported\n");
|
||||
@ -1365,7 +1403,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 44: /* hostlist-auto-fail-threshold */
|
||||
case 46: /* 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)
|
||||
{
|
||||
@ -1373,7 +1411,7 @@ int main(int argc, char **argv)
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 45: /* hostlist-auto-fail-time */
|
||||
case 47: /* hostlist-auto-fail-time */
|
||||
params.hostlist_auto_fail_time = (uint8_t)atoi(optarg);
|
||||
if (params.hostlist_auto_fail_time<1)
|
||||
{
|
||||
@ -1381,7 +1419,7 @@ int main(int argc, char **argv)
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 46: /* hostlist-auto-retrans-threshold */
|
||||
case 48: /* 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)
|
||||
{
|
||||
@ -1389,7 +1427,7 @@ int main(int argc, char **argv)
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 47: /* hostlist-auto-debug */
|
||||
case 49: /* hostlist-auto-debug */
|
||||
{
|
||||
FILE *F = fopen(optarg,"a+t");
|
||||
if (!F)
|
||||
@ -1407,28 +1445,28 @@ int main(int argc, char **argv)
|
||||
}
|
||||
break;
|
||||
#ifdef __linux__
|
||||
case 48: /* bind-fix4 */
|
||||
case 50: /* bind-fix4 */
|
||||
params.bind_fix4 = true;
|
||||
break;
|
||||
case 49: /* bind-fix6 */
|
||||
case 51: /* bind-fix6 */
|
||||
params.bind_fix6 = true;
|
||||
break;
|
||||
#elif defined(__CYGWIN__)
|
||||
case 48: /* wf-iface */
|
||||
case 50: /* wf-iface */
|
||||
if (!sscanf(optarg,"%u.%u",&IfIdx,&SubIfIdx))
|
||||
{
|
||||
fprintf(stderr, "bad value for --wf-iface\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 49: /* wf-l3 */
|
||||
case 51: /* wf-l3 */
|
||||
if (!wf_make_l3(optarg,&wf_ipv4,&wf_ipv6))
|
||||
{
|
||||
fprintf(stderr, "bad value for --wf-l3\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 50: /* wf-tcp */
|
||||
case 52: /* wf-tcp */
|
||||
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)))
|
||||
{
|
||||
@ -1436,7 +1474,7 @@ int main(int argc, char **argv)
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 51: /* wf-udp */
|
||||
case 53: /* wf-udp */
|
||||
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)))
|
||||
{
|
||||
@ -1444,7 +1482,7 @@ int main(int argc, char **argv)
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 52: /* wf-raw */
|
||||
case 54: /* wf-raw */
|
||||
if (optarg[0]=='@')
|
||||
{
|
||||
size_t sz = sizeof(windivert_filter)-1;
|
||||
@ -1457,7 +1495,7 @@ int main(int argc, char **argv)
|
||||
windivert_filter[sizeof(windivert_filter) - 1] = '\0';
|
||||
}
|
||||
break;
|
||||
case 53: /* wf-save */
|
||||
case 55: /* wf-save */
|
||||
strncpy(wf_save_file, optarg, sizeof(wf_save_file));
|
||||
wf_save_file[sizeof(wf_save_file) - 1] = '\0';
|
||||
break;
|
||||
@ -1514,6 +1552,8 @@ int main(int argc, char **argv)
|
||||
DLOG("autottl ipv4 %u:%u-%u\n",params.desync_autottl.delta,params.desync_autottl.min,params.desync_autottl.max)
|
||||
if (AUTOTTL_ENABLED(params.desync_autottl6))
|
||||
DLOG("autottl ipv6 %u:%u-%u\n",params.desync_autottl6.delta,params.desync_autottl6.min,params.desync_autottl6.max)
|
||||
if (params.desync_split_tls==tlspos_none && params.desync_split_pos) params.desync_split_tls=tlspos_pos;
|
||||
if (params.desync_split_http_req==httpreqpos_none && params.desync_split_pos) params.desync_split_http_req=httpreqpos_pos;
|
||||
|
||||
if (!LoadIncludeHostLists())
|
||||
{
|
||||
|
@ -25,7 +25,7 @@ void rawpacket_queue_destroy(struct rawpacket_tailhead *q)
|
||||
while((rp = rawpacket_dequeue(q))) rawpacket_free(rp);
|
||||
}
|
||||
|
||||
struct rawpacket *rawpacket_queue(struct rawpacket_tailhead *q,const struct sockaddr_storage* dst,uint32_t fwmark,const char *ifout,const void *data,size_t len)
|
||||
struct rawpacket *rawpacket_queue(struct rawpacket_tailhead *q,const struct sockaddr_storage* dst,uint32_t fwmark,const char *ifout,const void *data,size_t len,size_t len_payload)
|
||||
{
|
||||
struct rawpacket *rp = malloc(sizeof(struct rawpacket));
|
||||
if (!rp) return NULL;
|
||||
@ -48,6 +48,7 @@ struct rawpacket *rawpacket_queue(struct rawpacket_tailhead *q,const struct sock
|
||||
rp->ifout[0]=0;
|
||||
memcpy(rp->packet,data,len);
|
||||
rp->len=len;
|
||||
rp->len_payload=len_payload;
|
||||
|
||||
TAILQ_INSERT_TAIL(q, rp, next);
|
||||
|
||||
|
@ -11,7 +11,7 @@ struct rawpacket
|
||||
struct sockaddr_storage dst;
|
||||
char ifout[IFNAMSIZ+1];
|
||||
uint32_t fwmark;
|
||||
size_t len;
|
||||
size_t len, len_payload;
|
||||
uint8_t *packet;
|
||||
TAILQ_ENTRY(rawpacket) next;
|
||||
};
|
||||
@ -21,6 +21,6 @@ void rawpacket_queue_init(struct rawpacket_tailhead *q);
|
||||
void rawpacket_queue_destroy(struct rawpacket_tailhead *q);
|
||||
bool rawpacket_queue_empty(const struct rawpacket_tailhead *q);
|
||||
unsigned int rawpacket_queue_count(const struct rawpacket_tailhead *q);
|
||||
struct rawpacket *rawpacket_queue(struct rawpacket_tailhead *q,const struct sockaddr_storage* dst,uint32_t fwmark,const char *ifout,const void *data,size_t len);
|
||||
struct rawpacket *rawpacket_queue(struct rawpacket_tailhead *q,const struct sockaddr_storage* dst,uint32_t fwmark,const char *ifout,const void *data,size_t len,size_t len_payload);
|
||||
struct rawpacket *rawpacket_dequeue(struct rawpacket_tailhead *q);
|
||||
void rawpacket_free(struct rawpacket *rp);
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "pools.h"
|
||||
#include "conntrack.h"
|
||||
#include "desync.h"
|
||||
#include "protocol.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
@ -50,6 +51,8 @@ struct params_s
|
||||
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;
|
||||
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
|
||||
unsigned int desync_start, desync_cutoff;
|
||||
uint8_t desync_ttl, desync_ttl6;
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include <string.h>
|
||||
|
||||
const char *http_methods[] = { "GET /","POST /","HEAD /","OPTIONS /","PUT /","DELETE /","CONNECT /","TRACE /",NULL };
|
||||
bool IsHttp(const uint8_t *data, size_t len)
|
||||
const char *HttpMethod(const uint8_t *data, size_t len)
|
||||
{
|
||||
const char **method;
|
||||
size_t method_len;
|
||||
@ -16,10 +16,34 @@ bool IsHttp(const uint8_t *data, size_t len)
|
||||
{
|
||||
method_len = strlen(*method);
|
||||
if (method_len <= len && !memcmp(data, *method, method_len))
|
||||
return true;
|
||||
return *method;
|
||||
}
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
bool IsHttp(const uint8_t *data, size_t len)
|
||||
{
|
||||
return !!HttpMethod(data,len);
|
||||
}
|
||||
// pHost points to "Host: ..."
|
||||
bool HttpFindHost(uint8_t **pHost,uint8_t *buf,size_t bs)
|
||||
{
|
||||
if (!*pHost)
|
||||
{
|
||||
*pHost = memmem(buf, bs, "\nHost:", 6);
|
||||
if (*pHost) (*pHost)++;
|
||||
}
|
||||
return !!*pHost;
|
||||
}
|
||||
bool HttpFindHostConst(const uint8_t **pHost,const uint8_t *buf,size_t bs)
|
||||
{
|
||||
if (!*pHost)
|
||||
{
|
||||
*pHost = memmem(buf, bs, "\nHost:", 6);
|
||||
if (*pHost) (*pHost)++;
|
||||
}
|
||||
return !!*pHost;
|
||||
}
|
||||
|
||||
bool IsHttpReply(const uint8_t *data, size_t len)
|
||||
{
|
||||
// HTTP/1.x 200\r\n
|
||||
@ -106,6 +130,37 @@ bool HttpReplyLooksLikeDPIRedirect(const uint8_t *data, size_t len, const char *
|
||||
|
||||
return strcasecmp(dhost, drhost)!=0;
|
||||
}
|
||||
size_t HttpPos(enum httpreqpos tpos_type, size_t hpos_pos, const uint8_t *http, size_t sz)
|
||||
{
|
||||
const uint8_t *method, *host;
|
||||
int i;
|
||||
|
||||
switch(tpos_type)
|
||||
{
|
||||
case httpreqpos_method:
|
||||
// recognize some tpws pre-applied hacks
|
||||
method=http;
|
||||
if (sz<10) break;
|
||||
if (*method=='\n' || *method=='\r') method++;
|
||||
if (*method=='\n' || *method=='\r') method++;
|
||||
for (i=0;i<7;i++) if (*method>='A' && *method<='Z') method++;
|
||||
if (i<3 || *method!=' ') break;
|
||||
return method-http-1;
|
||||
case httpreqpos_host:
|
||||
if (HttpFindHostConst(&host,http,sz) && (host-http+7)<sz)
|
||||
{
|
||||
host+=5;
|
||||
if (*host==' ') host++;
|
||||
return host-http;
|
||||
}
|
||||
break;
|
||||
case httpreqpos_pos:
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return hpos_pos<sz ? hpos_pos : 0;
|
||||
}
|
||||
|
||||
|
||||
uint16_t TLSRecordDataLen(const uint8_t *data)
|
||||
@ -250,6 +305,23 @@ bool TLSHelloExtractHostFromHandshake(const uint8_t *data, size_t len, char *hos
|
||||
if (!TLSFindExtInHandshake(data, len, 0, &ext, &elen, bPartialIsOK)) return false;
|
||||
return TLSExtractHostFromExt(ext, elen, host, len_host);
|
||||
}
|
||||
size_t TLSPos(enum tlspos tpos_type, size_t tpos_pos, const uint8_t *tls, size_t sz, uint8_t type)
|
||||
{
|
||||
size_t elen;
|
||||
const uint8_t *ext;
|
||||
switch(tpos_type)
|
||||
{
|
||||
case tlspos_sni:
|
||||
case tlspos_sniext:
|
||||
if (TLSFindExt(tls,sz,0,&ext,&elen,false))
|
||||
return (tpos_type==tlspos_sni) ? ext-tls+6 : ext-tls+1;
|
||||
// fall through
|
||||
case tlspos_pos:
|
||||
return tpos_pos<sz ? tpos_pos : 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -7,7 +7,11 @@
|
||||
#include "crypto/aes-gcm.h"
|
||||
#include "helpers.h"
|
||||
|
||||
extern const char *http_methods[9];
|
||||
const char *HttpMethod(const uint8_t *data, size_t len);
|
||||
bool IsHttp(const uint8_t *data, size_t len);
|
||||
bool HttpFindHost(uint8_t **pHost,uint8_t *buf,size_t bs);
|
||||
bool HttpFindHostConst(const uint8_t **pHost,const uint8_t *buf,size_t bs);
|
||||
// header must be passed like this : "\nHost:"
|
||||
bool HttpExtractHeader(const uint8_t *data, size_t len, const char *header, char *buf, size_t len_buf);
|
||||
bool HttpExtractHost(const uint8_t *data, size_t len, char *host, size_t len_host);
|
||||
@ -17,6 +21,8 @@ const char *HttpFind2ndLevelDomain(const char *host);
|
||||
int HttpReplyCode(const uint8_t *data, size_t len);
|
||||
// must be pre-checked by IsHttpReply
|
||||
bool HttpReplyLooksLikeDPIRedirect(const uint8_t *data, size_t len, const char *host);
|
||||
enum httpreqpos { httpreqpos_none = 0, httpreqpos_method, httpreqpos_host, httpreqpos_pos };
|
||||
size_t HttpPos(enum httpreqpos tpos_type, size_t hpos_pos, const uint8_t *http, size_t sz);
|
||||
|
||||
uint16_t TLSRecordDataLen(const uint8_t *data);
|
||||
size_t TLSRecordLen(const uint8_t *data);
|
||||
@ -29,6 +35,8 @@ bool TLSFindExt(const uint8_t *data, size_t len, uint16_t type, const uint8_t **
|
||||
bool TLSFindExtInHandshake(const uint8_t *data, size_t len, uint16_t type, const uint8_t **ext, size_t *len_ext, bool bPartialIsOK);
|
||||
bool TLSHelloExtractHost(const uint8_t *data, size_t len, char *host, size_t len_host, bool bPartialIsOK);
|
||||
bool TLSHelloExtractHostFromHandshake(const uint8_t *data, size_t len, char *host, size_t len_host, bool bPartialIsOK);
|
||||
enum tlspos { tlspos_none = 0, tlspos_sni, tlspos_sniext, tlspos_pos };
|
||||
size_t TLSPos(enum tlspos tpos_type, size_t tpos_pos, const uint8_t *tls, size_t sz, uint8_t type);
|
||||
|
||||
bool IsWireguardHandshakeInitiation(const uint8_t *data, size_t len);
|
||||
bool IsDhtD1(const uint8_t *data, size_t len);
|
||||
|
@ -9,12 +9,11 @@
|
||||
#include "tpws.h"
|
||||
#include "pools.h"
|
||||
#include "helpers.h"
|
||||
#include "protocol.h"
|
||||
|
||||
#define HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT 3
|
||||
#define HOSTLIST_AUTO_FAIL_TIME_DEFAULT 60
|
||||
|
||||
enum httpreqpos { httpreqpos_none = 0, httpreqpos_method, httpreqpos_host };
|
||||
enum tlspos { tlspos_none = 0, tlspos_sni, tlspos_sniext, tlspos_pos };
|
||||
enum bindll { unwanted=0, no, prefer, force };
|
||||
|
||||
#define MAX_BINDS 32
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
|
||||
const char *http_methods[] = { "GET /","POST /","HEAD /","OPTIONS /","PUT /","DELETE /","CONNECT /","TRACE /",NULL };
|
||||
bool IsHttp(const uint8_t *data, size_t len)
|
||||
const char *HttpMethod(const uint8_t *data, size_t len)
|
||||
{
|
||||
const char **method;
|
||||
size_t method_len;
|
||||
@ -17,9 +17,32 @@ bool IsHttp(const uint8_t *data, size_t len)
|
||||
{
|
||||
method_len = strlen(*method);
|
||||
if (method_len <= len && !memcmp(data, *method, method_len))
|
||||
return true;
|
||||
return *method;
|
||||
}
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
bool IsHttp(const uint8_t *data, size_t len)
|
||||
{
|
||||
return !!HttpMethod(data,len);
|
||||
}
|
||||
// pHost points to "Host: ..."
|
||||
bool HttpFindHost(uint8_t **pHost,uint8_t *buf,size_t bs)
|
||||
{
|
||||
if (!*pHost)
|
||||
{
|
||||
*pHost = memmem(buf, bs, "\nHost:", 6);
|
||||
if (*pHost) (*pHost)++;
|
||||
}
|
||||
return !!*pHost;
|
||||
}
|
||||
bool HttpFindHostConst(const uint8_t **pHost,const uint8_t *buf,size_t bs)
|
||||
{
|
||||
if (!*pHost)
|
||||
{
|
||||
*pHost = memmem(buf, bs, "\nHost:", 6);
|
||||
if (*pHost) (*pHost)++;
|
||||
}
|
||||
return !!*pHost;
|
||||
}
|
||||
bool IsHttpReply(const uint8_t *data, size_t len)
|
||||
{
|
||||
@ -107,6 +130,37 @@ bool HttpReplyLooksLikeDPIRedirect(const uint8_t *data, size_t len, const char *
|
||||
|
||||
return strcasecmp(dhost, drhost)!=0;
|
||||
}
|
||||
size_t HttpPos(enum httpreqpos tpos_type, size_t hpos_pos, const uint8_t *http, size_t sz)
|
||||
{
|
||||
const uint8_t *method, *host;
|
||||
int i;
|
||||
|
||||
switch(tpos_type)
|
||||
{
|
||||
case httpreqpos_method:
|
||||
// recognize some tpws pre-applied hacks
|
||||
method=http;
|
||||
if (sz<10) break;
|
||||
if (*method=='\n' || *method=='\r') method++;
|
||||
if (*method=='\n' || *method=='\r') method++;
|
||||
for (i=0;i<7;i++) if (*method>='A' && *method<='Z') method++;
|
||||
if (i<3 || *method!=' ') break;
|
||||
return method-http-1;
|
||||
case httpreqpos_host:
|
||||
if (HttpFindHostConst(&host,http,sz) && (host-http+7)<sz)
|
||||
{
|
||||
host+=5;
|
||||
if (*host==' ') host++;
|
||||
return host-http;
|
||||
}
|
||||
break;
|
||||
case httpreqpos_pos:
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return hpos_pos<sz ? hpos_pos : 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -241,3 +295,20 @@ bool TLSHelloExtractHostFromHandshake(const uint8_t *data, size_t len, char *hos
|
||||
if (!TLSFindExtInHandshake(data, len, 0, &ext, &elen, bPartialIsOK)) return false;
|
||||
return TLSExtractHostFromExt(ext, elen, host, len_host);
|
||||
}
|
||||
size_t TLSPos(enum tlspos tpos_type, size_t tpos_pos, const uint8_t *tls, size_t sz, uint8_t type)
|
||||
{
|
||||
size_t elen;
|
||||
const uint8_t *ext;
|
||||
switch(tpos_type)
|
||||
{
|
||||
case tlspos_sni:
|
||||
case tlspos_sniext:
|
||||
if (TLSFindExt(tls,sz,0,&ext,&elen,false))
|
||||
return (tpos_type==tlspos_sni) ? ext-tls+6 : ext-tls+1;
|
||||
// fall through
|
||||
case tlspos_pos:
|
||||
return tpos_pos<sz ? tpos_pos : 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,11 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
extern const char *http_methods[9];
|
||||
const char *HttpMethod(const uint8_t *data, size_t len);
|
||||
bool IsHttp(const uint8_t *data, size_t len);
|
||||
bool HttpFindHost(uint8_t **pHost,uint8_t *buf,size_t bs);
|
||||
bool HttpFindHostConst(const uint8_t **pHost,const uint8_t *buf,size_t bs);
|
||||
// header must be passed like this : "\nHost:"
|
||||
bool HttpExtractHeader(const uint8_t *data, size_t len, const char *header, char *buf, size_t len_buf);
|
||||
bool HttpExtractHost(const uint8_t *data, size_t len, char *host, size_t len_host);
|
||||
@ -14,6 +18,8 @@ const char *HttpFind2ndLevelDomain(const char *host);
|
||||
int HttpReplyCode(const uint8_t *data, size_t len);
|
||||
// must be pre-checked by IsHttpReply
|
||||
bool HttpReplyLooksLikeDPIRedirect(const uint8_t *data, size_t len, const char *host);
|
||||
enum httpreqpos { httpreqpos_none = 0, httpreqpos_method, httpreqpos_host, httpreqpos_pos };
|
||||
size_t HttpPos(enum httpreqpos tpos_type, size_t hpos_pos, const uint8_t *http, size_t sz);
|
||||
|
||||
uint16_t TLSRecordDataLen(const uint8_t *data);
|
||||
size_t TLSRecordLen(const uint8_t *data);
|
||||
@ -23,3 +29,5 @@ bool TLSFindExt(const uint8_t *data, size_t len, uint16_t type, const uint8_t **
|
||||
bool TLSFindExtInHandshake(const uint8_t *data, size_t len, uint16_t type, const uint8_t **ext, size_t *len_ext, bool bPartialIsOK);
|
||||
bool TLSHelloExtractHost(const uint8_t *data, size_t len, char *host, size_t len_host, bool bPartialIsOK);
|
||||
bool TLSHelloExtractHostFromHandshake(const uint8_t *data, size_t len, char *host, size_t len_host, bool bPartialIsOK);
|
||||
enum tlspos { tlspos_none = 0, tlspos_sni, tlspos_sniext, tlspos_pos };
|
||||
size_t TLSPos(enum tlspos tpos_type, size_t tpos_pos, const uint8_t *tls, size_t sz, uint8_t type);
|
||||
|
@ -8,48 +8,13 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// pHost points to "Host: ..."
|
||||
static bool find_host(uint8_t **pHost,uint8_t *buf,size_t bs)
|
||||
{
|
||||
if (!*pHost)
|
||||
{
|
||||
*pHost = memmem(buf, bs, "\nHost:", 6);
|
||||
if (*pHost)
|
||||
{
|
||||
(*pHost)++;
|
||||
VPRINT("Found Host: at pos %td",*pHost - buf)
|
||||
}
|
||||
}
|
||||
return !!*pHost;
|
||||
}
|
||||
|
||||
static size_t tls_pos(enum tlspos tpos_type, size_t tpos_pos, const uint8_t *tls, size_t sz, uint8_t type)
|
||||
{
|
||||
size_t elen;
|
||||
const uint8_t *ext;
|
||||
switch(tpos_type)
|
||||
{
|
||||
case tlspos_sni:
|
||||
case tlspos_sniext:
|
||||
if (TLSFindExt(tls,sz,0,&ext,&elen,false))
|
||||
return (tpos_type==tlspos_sni) ? ext-tls+6 : ext-tls+1;
|
||||
// fall through
|
||||
case tlspos_pos:
|
||||
return tpos_pos;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const char *http_methods[] = { "GET /","POST /","HEAD /","OPTIONS /","PUT /","DELETE /","CONNECT /","TRACE /",NULL };
|
||||
// segment buffer has at least 5 extra bytes to extend data block
|
||||
void tamper_out(t_ctrack *ctrack, uint8_t *segment,size_t segment_buffer_size,size_t *size, size_t *split_pos, uint8_t *split_flags)
|
||||
{
|
||||
uint8_t *p, *pp, *pHost = NULL;
|
||||
size_t method_len = 0, pos;
|
||||
const char **method;
|
||||
bool bIsHttp = false, bBypass = false, bHaveHost = false, bHostExcluded = false;
|
||||
const char *method;
|
||||
bool bBypass = false, bHaveHost = false, bHostExcluded = false;
|
||||
char bRemovedHostSpace = 0;
|
||||
char *pc, Host[256];
|
||||
|
||||
@ -58,22 +23,13 @@ void tamper_out(t_ctrack *ctrack, uint8_t *segment,size_t segment_buffer_size,si
|
||||
*split_pos=0;
|
||||
*split_flags=0;
|
||||
|
||||
for (method = http_methods; *method; method++)
|
||||
if ((method = HttpMethod(segment,*size)))
|
||||
{
|
||||
method_len = strlen(*method);
|
||||
if (method_len <= *size && !memcmp(segment, *method, method_len))
|
||||
{
|
||||
bIsHttp = true;
|
||||
method_len -= 2; // "GET /" => "GET"
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (bIsHttp)
|
||||
{
|
||||
VPRINT("Data block looks like http request start : %s", *method)
|
||||
method_len = strlen(method)-2;
|
||||
VPRINT("Data block looks like http request start : %s", method)
|
||||
if (!ctrack->l7proto) ctrack->l7proto=HTTP;
|
||||
// cpu saving : we search host only if and when required. we do not research host every time we need its position
|
||||
if ((params.hostlist || params.hostlist_exclude) && find_host(&pHost,segment,*size))
|
||||
if ((params.hostlist || params.hostlist_exclude) && HttpFindHost(&pHost,segment,*size))
|
||||
{
|
||||
p = pHost + 5;
|
||||
while (p < (segment + *size) && (*p == ' ' || *p == '\t')) p++;
|
||||
@ -135,7 +91,7 @@ void tamper_out(t_ctrack *ctrack, uint8_t *segment,size_t segment_buffer_size,si
|
||||
(*size)++; // block will grow by 1 byte
|
||||
if (pHost) pHost++; // Host: position will move by 1 byte
|
||||
}
|
||||
if ((params.hostdot || params.hosttab) && *size<segment_buffer_size && find_host(&pHost,segment,*size))
|
||||
if ((params.hostdot || params.hosttab) && *size<segment_buffer_size && HttpFindHost(&pHost,segment,*size))
|
||||
{
|
||||
p = pHost + 5;
|
||||
while (p < (segment + *size) && *p != '\r' && *p != '\n') p++;
|
||||
@ -148,7 +104,7 @@ void tamper_out(t_ctrack *ctrack, uint8_t *segment,size_t segment_buffer_size,si
|
||||
(*size)++; // block will grow by 1 byte
|
||||
}
|
||||
}
|
||||
if (params.domcase && find_host(&pHost,segment,*size))
|
||||
if (params.domcase && HttpFindHost(&pHost,segment,*size))
|
||||
{
|
||||
p = pHost + 5;
|
||||
pos = p - segment;
|
||||
@ -156,7 +112,7 @@ void tamper_out(t_ctrack *ctrack, uint8_t *segment,size_t segment_buffer_size,si
|
||||
for (; p < (segment + *size) && *p != '\r' && *p != '\n'; p++)
|
||||
*p = (((size_t)p) & 1) ? tolower(*p) : toupper(*p);
|
||||
}
|
||||
if (params.hostnospace && find_host(&pHost,segment,*size) && (pHost+5)<(segment+*size) && pHost[5] == ' ')
|
||||
if (params.hostnospace && HttpFindHost(&pHost,segment,*size) && (pHost+5)<(segment+*size) && pHost[5] == ' ')
|
||||
{
|
||||
p = pHost + 6;
|
||||
pos = p - segment;
|
||||
@ -165,12 +121,12 @@ void tamper_out(t_ctrack *ctrack, uint8_t *segment,size_t segment_buffer_size,si
|
||||
(*size)--; // block will shrink by 1 byte
|
||||
bRemovedHostSpace = 1;
|
||||
}
|
||||
if (params.hostcase && find_host(&pHost,segment,*size))
|
||||
if (params.hostcase && HttpFindHost(&pHost,segment,*size))
|
||||
{
|
||||
VPRINT("Changing 'Host:' => '%c%c%c%c:' at pos %td", params.hostspell[0], params.hostspell[1], params.hostspell[2], params.hostspell[3], pHost - segment)
|
||||
memcpy(pHost, params.hostspell, 4);
|
||||
}
|
||||
if (params.hostpad && find_host(&pHost,segment,*size))
|
||||
if (params.hostpad && HttpFindHost(&pHost,segment,*size))
|
||||
{
|
||||
// add : XXXXX: <padding?[\r\n|\n]
|
||||
char s[8];
|
||||
@ -217,18 +173,7 @@ void tamper_out(t_ctrack *ctrack, uint8_t *segment,size_t segment_buffer_size,si
|
||||
pHost = NULL; // invalidate
|
||||
}
|
||||
}
|
||||
switch (params.split_http_req)
|
||||
{
|
||||
case httpreqpos_method:
|
||||
*split_pos = method_len - 1 + params.methodeol + (params.methodeol && !params.unixeol);
|
||||
break;
|
||||
case httpreqpos_host:
|
||||
if (find_host(&pHost,segment,*size))
|
||||
*split_pos = pHost + 6 - bRemovedHostSpace - segment;
|
||||
break;
|
||||
default:
|
||||
if (params.split_pos < *size) *split_pos = params.split_pos;
|
||||
}
|
||||
*split_pos = HttpPos(params.split_http_req, params.split_pos, segment, *size);
|
||||
if (params.disorder_http) *split_flags |= SPLIT_FLAG_DISORDER;
|
||||
if (params.oob_http) *split_flags |= SPLIT_FLAG_OOB;
|
||||
}
|
||||
@ -258,11 +203,11 @@ void tamper_out(t_ctrack *ctrack, uint8_t *segment,size_t segment_buffer_size,si
|
||||
}
|
||||
else
|
||||
{
|
||||
spos = tls_pos(params.split_tls, params.split_pos, segment, *size, 0);
|
||||
spos = TLSPos(params.split_tls, params.split_pos, segment, *size, 0);
|
||||
|
||||
if ((5+*size)<=segment_buffer_size)
|
||||
{
|
||||
tpos = tls_pos(params.tlsrec, params.tlsrec_pos+5, segment, *size, 0);
|
||||
tpos = TLSPos(params.tlsrec, params.tlsrec_pos+5, segment, *size, 0);
|
||||
if (tpos>5)
|
||||
{
|
||||
// construct 2 TLS records from one
|
||||
|
@ -829,6 +829,7 @@ void parse_params(int argc, char *argv[])
|
||||
}
|
||||
if (!params.resolver_threads) params.resolver_threads = 5 + params.maxconn/50;
|
||||
if (params.split_tls==tlspos_none && params.split_pos) params.split_tls=tlspos_pos;
|
||||
if (params.split_http_req==httpreqpos_none && params.split_pos) params.split_http_req=httpreqpos_pos;
|
||||
|
||||
if (*params.hostlist_auto_filename) params.hostlist_auto_mod_time = file_mod_time(params.hostlist_auto_filename);
|
||||
if (!LoadIncludeHostLists())
|
||||
|
Loading…
Reference in New Issue
Block a user