mirror of
https://github.com/bol-van/zapret.git
synced 2024-11-30 05:50:53 +03:00
Compare commits
No commits in common. "3ad029efe0c42e858d61369a49c5d28ce628d609" and "5d6c91f7e9956738bdb5e1ceff065cdbeded5005" have entirely different histories.
3ad029efe0
...
5d6c91f7e9
287
blockcheck.sh
287
blockcheck.sh
@ -45,6 +45,7 @@ HTTP_PORT=${HTTP_PORT:-80}
|
||||
HTTPS_PORT=${HTTPS_PORT:-443}
|
||||
QUIC_PORT=${QUIC_PORT:-443}
|
||||
UNBLOCKED_DOM=${UNBLOCKED_DOM:-iana.org}
|
||||
[ "$CURL_VERBOSE" = 1 ] && CURL_CMD=1
|
||||
|
||||
HDRTEMP=/tmp/zapret-hdr.txt
|
||||
|
||||
@ -791,7 +792,7 @@ pktws_ipt_prepare()
|
||||
# disable PF to avoid interferences
|
||||
pf_is_avail && pfctl -qd
|
||||
for ip in $3; do
|
||||
IPFW_ADD divert $IPFW_DIVERT_PORT $1 from me to $ip $2 proto ip${IPV} out not diverted
|
||||
IPFW_ADD divert $IPFW_DIVERT_PORT $1 from me to $ip $2 proto ip${IPV} out not diverted not sockarg
|
||||
done
|
||||
;;
|
||||
opf)
|
||||
@ -866,7 +867,7 @@ pktws_ipt_prepare_tcp()
|
||||
;;
|
||||
ipfw)
|
||||
for ip in $2; do
|
||||
IPFW_ADD divert $IPFW_DIVERT_PORT tcp from $ip $1 to me proto ip${IPV} tcpflags syn,ack in not diverted
|
||||
IPFW_ADD divert $IPFW_DIVERT_PORT tcp from $ip $1 to me proto ip${IPV} tcpflags syn,ack in not diverted not sockarg
|
||||
done
|
||||
;;
|
||||
esac
|
||||
@ -993,6 +994,7 @@ ws_curl_test()
|
||||
# $2 - test function
|
||||
# $3 - domain
|
||||
# $4,$5,$6, ... - ws params
|
||||
|
||||
local code ws_start=$1 testf=$2 dom=$3
|
||||
shift
|
||||
shift
|
||||
@ -1086,7 +1088,7 @@ test_has_split()
|
||||
}
|
||||
test_has_fake()
|
||||
{
|
||||
[ "$1" = fake ] || starts_with "$1" fake,
|
||||
contains "$1" fake
|
||||
}
|
||||
warn_fool()
|
||||
{
|
||||
@ -1103,34 +1105,25 @@ pktws_curl_test_update_vary()
|
||||
# $4 - desync mode
|
||||
# $5,$6,... - strategy
|
||||
|
||||
local testf=$1 sec=$2 domain=$3 desync=$4 proto zerofake= splits= pos fake ret=1
|
||||
local testf=$1 sec=$2 domain=$3 desync=$4 zerofake split fake
|
||||
|
||||
shift; shift; shift; shift
|
||||
|
||||
proto=http
|
||||
[ "$sec" = 0 ] || proto=tls
|
||||
test_has_fake $desync && zerofake="--dpi-desync-fake-$proto=0x00000000"
|
||||
test_has_split $desync && {
|
||||
splits="method+2 midsld"
|
||||
[ "$sec" = 0 ] || splits="1 midsld 1,midsld"
|
||||
}
|
||||
zerofake=http
|
||||
[ "$sec" = 0 ] || zerofake=tls
|
||||
zerofake="--dpi-desync-fake-$zerofake=0x00000000"
|
||||
|
||||
for fake in '' $zerofake ; do
|
||||
if [ -n "$splits" ]; then
|
||||
for pos in $splits ; do
|
||||
pktws_curl_test_update $testf $domain --dpi-desync=$desync "$@" --dpi-desync-split-pos=$pos $fake && {
|
||||
[ "$SCANLEVEL" = force ] || return 0
|
||||
ret=0
|
||||
}
|
||||
done
|
||||
else
|
||||
pktws_curl_test_update $testf $domain --dpi-desync=$desync "$@" $fake && {
|
||||
[ "$SCANLEVEL" = force ] || return 0
|
||||
ret=0
|
||||
}
|
||||
fi
|
||||
for split in '' '--dpi-desync-split-pos=1' ; do
|
||||
pktws_curl_test_update $testf $domain --dpi-desync=$desync "$@" $fake $split && return 0
|
||||
# split-pos=1 is meaningful for DPIs searching for 16 03 in TLS. no reason to apply to http
|
||||
[ "$sec" = 1 ] || break
|
||||
test_has_split $desync || break
|
||||
done
|
||||
test_has_fake $desync || break
|
||||
done
|
||||
|
||||
return $ret
|
||||
return 1
|
||||
}
|
||||
|
||||
pktws_check_domain_http_bypass_()
|
||||
@ -1139,10 +1132,7 @@ pktws_check_domain_http_bypass_()
|
||||
# $2 - encrypted test : 0 = plain, 1 - encrypted with server reply risk, 2 - encrypted without server reply risk
|
||||
# $3 - domain
|
||||
|
||||
local ok ttls s f f2 e desync pos fooling frag sec="$2" delta splits
|
||||
local need_split need_disorder need_fakedsplit need_fakeddisorder need_fake need_wssize
|
||||
local splits_http='method+2 midsld method+2,midsld'
|
||||
local splits_tls='2 1 sniext+1 sniext+4 host+1 midsld 1,midsld 1,sniext+1,host+1,midsld-2,midsld,midsld+2,endhost-1'
|
||||
local tests='fake' ret ok ttls s f e desync pos fooling frag sec="$2" delta hostcase
|
||||
|
||||
[ "$sec" = 0 ] && {
|
||||
for s in '--hostcase' '--hostspell=hoSt' '--hostnospace' '--domcase'; do
|
||||
@ -1150,62 +1140,74 @@ pktws_check_domain_http_bypass_()
|
||||
done
|
||||
}
|
||||
|
||||
ttls=$(seq -s ' ' $MIN_TTL $MAX_TTL)
|
||||
need_wssize=1
|
||||
for e in '' '--wssize 1:6'; do
|
||||
need_split=
|
||||
need_disorder=
|
||||
|
||||
[ -n "$e" ] && {
|
||||
pktws_curl_test_update $1 $3 $e && [ "$SCANLEVEL" = quick ] && return
|
||||
}
|
||||
|
||||
for desync in multisplit multidisorder; do
|
||||
ok=0
|
||||
splits="$splits_http"
|
||||
[ "$sec" = 0 ] || splits="$splits_tls"
|
||||
for pos in $splits; do
|
||||
pktws_curl_test_update $1 $3 --dpi-desync=$desync --dpi-desync-split-pos=$pos $e && {
|
||||
s="--dpi-desync=split2"
|
||||
ok=0
|
||||
pktws_curl_test_update $1 $3 $s
|
||||
ret=$?
|
||||
[ "$ret" = 0 ] && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
ok=1
|
||||
}
|
||||
[ "$ret" != 0 -o "$SCANLEVEL" = force ] && {
|
||||
if [ "$sec" = 0 ]; then
|
||||
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
|
||||
else
|
||||
for pos in sni sniext; do
|
||||
pktws_curl_test_update $1 $3 $s --dpi-desync-split-tls=$pos && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
ok=1
|
||||
need_wssize=0
|
||||
[ "$SCANLEVEL" = force ] || break
|
||||
}
|
||||
done
|
||||
[ "$ok" = 1 -a "$SCANLEVEL" != force ] || {
|
||||
case $desync in
|
||||
multisplit)
|
||||
need_split=1
|
||||
;;
|
||||
multidisorder)
|
||||
need_disorder=1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
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
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
ok=1
|
||||
[ "$SCANLEVEL" = force ] || break
|
||||
elif [ "$sec" = 0 ]; then
|
||||
pktws_curl_test_update $1 $3 $s --hostcase && [ "$SCANLEVEL" = quick ] && return
|
||||
fi
|
||||
done
|
||||
}
|
||||
[ "$ok" = 1 -a "$SCANLEVEL" != force ] || tests="$tests split fake,split2 fake,split"
|
||||
|
||||
need_fakedsplit=1
|
||||
need_fakeddisorder=1
|
||||
need_fake=1
|
||||
for desync in fake ${need_split:+fakedsplit fake,multisplit fake,fakedsplit} ${need_disorder:+fakeddisorder fake,multidisorder fake,fakeddisorder}; do
|
||||
[ "$need_fake" = 0 ] && test_has_fake "$desync" && continue
|
||||
[ "$need_fakedsplit" = 0 ] && contains "$desync" fakedsplit && continue
|
||||
[ "$need_fakeddisorder" = 0 ] && contains "$desync" fakeddisorder && continue
|
||||
ok=0
|
||||
pktws_curl_test_update $1 $3 --dpi-desync=disorder2
|
||||
ret=$?
|
||||
[ "$ret" = 0 -a "$SCANLEVEL" = quick ] && return
|
||||
[ "$ret" != 0 -o "$SCANLEVEL" = force ] && {
|
||||
pktws_curl_test_update $1 $3 --dpi-desync=disorder2 --dpi-desync-split-pos=1
|
||||
ret=$?
|
||||
[ "$ret" = 0 -a "$SCANLEVEL" = quick ] && return
|
||||
}
|
||||
[ "$ret" != 0 -o "$SCANLEVEL" = force ] && tests="$tests disorder fake,disorder2 fake,disorder"
|
||||
|
||||
ttls=$(seq -s ' ' $MIN_TTL $MAX_TTL)
|
||||
for e in '' '--wssize 1:6'; do
|
||||
[ -n "$e" ] && {
|
||||
pktws_curl_test_update $1 $3 $e && [ "$SCANLEVEL" = quick ] && return
|
||||
for desync in split2 disorder2; do
|
||||
pktws_curl_test_update_vary $1 $2 $3 $desync $e && [ "$SCANLEVEL" = quick ] && return
|
||||
done
|
||||
}
|
||||
for desync in $tests; do
|
||||
for ttl in $ttls; do
|
||||
pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-ttl=$ttl $e && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
ok=1
|
||||
need_wssize=0
|
||||
break
|
||||
}
|
||||
done
|
||||
# only skip tests if TTL succeeded. do not skip if TTL failed but fooling succeeded
|
||||
[ $ok = 1 -a "$SCANLEVEL" != force ] && {
|
||||
[ "$desync" = fake ] && need_fake=0
|
||||
[ "$desync" = fakedsplit ] && need_fakedsplit=0
|
||||
[ "$desync" = fakeddisorder ] && need_fakeddisorder=0
|
||||
}
|
||||
f=
|
||||
[ "$UNAME" = "OpenBSD" ] || f="badsum"
|
||||
f="$f badseq datanoack md5sig"
|
||||
@ -1214,68 +1216,37 @@ pktws_check_domain_http_bypass_()
|
||||
pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-fooling=$fooling $e && {
|
||||
warn_fool $fooling
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
need_wssize=0
|
||||
}
|
||||
done
|
||||
done
|
||||
|
||||
[ "$IPV" = 6 ] && {
|
||||
f="hopbyhop ${need_split:+hopbyhop,multisplit} ${need_disorder:+hopbyhop,multidisorder} destopt ${need_split:+destopt,multisplit} ${need_disorder:+destopt,multidisorder}"
|
||||
[ -n "$IP6_DEFRAG_DISABLE" ] && f="$f ipfrag1 ${need_split:+ ipfrag1,multisplit} ${need_disorder:+ ipfrag1,multidisorder}"
|
||||
f="hopbyhop hopbyhop,split2 hopbyhop,disorder2 destopt destopt,split2 destopt,disorder2"
|
||||
[ -n "$IP6_DEFRAG_DISABLE" ] && f="$f ipfrag1 ipfrag1,split2 ipfrag1,disorder2"
|
||||
for desync in $f; do
|
||||
pktws_curl_test_update_vary $1 $2 $3 $desync $e && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
need_wssize=0
|
||||
}
|
||||
pktws_curl_test_update_vary $1 $2 $3 $desync $e && [ "$SCANLEVEL" = quick ] && return
|
||||
done
|
||||
}
|
||||
|
||||
[ "$need_split" = 1 ] && {
|
||||
# relative markers can be anywhere, even in subsequent packets. first packet can be MTU-full.
|
||||
# make additional split pos "10" to guarantee enough space for seqovl and likely to be before midsld,sniext,...
|
||||
# method is always expected in the beginning of the first packet
|
||||
f="method+2 method+2,midsld"
|
||||
[ "$sec" = 0 ] || f="10 10,sniext+1 10,sniext+4 10,midsld"
|
||||
for pos in $f; do
|
||||
pktws_curl_test_update $1 $3 --dpi-desync=multisplit --dpi-desync-split-pos=$pos --dpi-desync-split-seqovl=1 $e && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
need_wssize=0
|
||||
}
|
||||
done
|
||||
[ "$sec" != 0 ] && pktws_curl_test_update $1 $3 --dpi-desync=multisplit --dpi-desync-split-pos=2 --dpi-desync-split-seqovl=336 --dpi-desync-split-seqovl-pattern="$ZAPRET_BASE/files/fake/tls_clienthello_iana_org.bin" $e && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
need_wssize=0
|
||||
}
|
||||
}
|
||||
[ "$need_disorder" = 1 ] && {
|
||||
for desync in split2 disorder2; do
|
||||
s="--dpi-desync=$desync"
|
||||
if [ "$sec" = 0 ]; then
|
||||
for pos in 'method+1 method+2' 'midsld-1 midsld' 'method+1 method+2,midsld'; do
|
||||
f="$(extract_arg 1 $pos)"
|
||||
f2="$(extract_arg 2 $pos)"
|
||||
pktws_curl_test_update $1 $3 --dpi-desync=multidisorder --dpi-desync-split-pos=$f2 --dpi-desync-split-seqovl=$f $e && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
need_wssize=0
|
||||
}
|
||||
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 '1 2' 'sniext sniext+1' 'sniext+3 sniext+4' 'midsld-1 midsld' '1 2,midsld'; do
|
||||
f=$(extract_arg 1 $pos)
|
||||
f2=$(extract_arg 2 $pos)
|
||||
pktws_curl_test_update $1 $3 --dpi-desync=multidisorder --dpi-desync-split-pos=$f2 --dpi-desync-split-seqovl=$f $e && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
need_wssize=0
|
||||
}
|
||||
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
|
||||
[ "$sec" != 0 -a $desync = split2 ] && {
|
||||
pktws_curl_test_update $1 $3 $s --dpi-desync-split-seqovl=336 --dpi-desync-split-seqovl-pattern="$ZAPRET_BASE/files/fake/tls_clienthello_iana_org.bin" $e && [ "$SCANLEVEL" = quick ] && return
|
||||
}
|
||||
done
|
||||
|
||||
need_fakedsplit=1
|
||||
need_fakeddisorder=1
|
||||
need_fake=1
|
||||
for desync in fake ${need_split:+fakedsplit fake,multisplit fake,fakedsplit} ${need_disorder:+fakeddisorder fake,multidisorder fake,fakeddisorder}; do
|
||||
[ "$need_fake" = 0 ] && test_has_fake "$desync" && continue
|
||||
[ "$need_fakedsplit" = 0 ] && contains "$desync" fakedsplit && continue
|
||||
[ "$need_fakeddisorder" = 0 ] && contains "$desync" fakeddisorder && continue
|
||||
for desync in $tests; do
|
||||
ok=0
|
||||
for delta in 1 2 3 4 5; do
|
||||
pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-ttl=1 --dpi-desync-autottl=$delta $e && ok=1
|
||||
@ -1285,25 +1256,18 @@ pktws_check_domain_http_bypass_()
|
||||
echo "WARNING ! although autottl worked it requires testing on multiple domains to find out reliable delta"
|
||||
echo "WARNING ! if a reliable delta cannot be found it's a good idea not to use autottl"
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
need_wssize=0
|
||||
[ "$SCANLEVEL" = force ] || {
|
||||
[ "$desync" = fake ] && need_fake=0
|
||||
[ "$desync" = fakedsplit ] && need_fakedsplit=0
|
||||
[ "$desync" = fakeddisorder ] && need_fakeddisorder=0
|
||||
}
|
||||
}
|
||||
done
|
||||
|
||||
s="http_iana_org.bin"
|
||||
[ "$sec" = 0 ] || s="tls_clienthello_iana_org.bin"
|
||||
for desync in syndata ${need_split:+syndata,multisplit} ${need_disorder:+syndata,multidisorder} ; do
|
||||
for desync in syndata syndata,split2 syndata,disorder2 ; do
|
||||
pktws_curl_test_update_vary $1 $2 $3 $desync $e && [ "$SCANLEVEL" = quick ] && return
|
||||
pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-fake-syndata="$ZAPRET_BASE/files/fake/$s" $e && [ "$SCANLEVEL" = quick ] && return
|
||||
done
|
||||
|
||||
# do not do wssize test for http and TLS 1.3. it's useless
|
||||
[ "$sec" = 1 ] || break
|
||||
[ "$SCANLEVEL" = force -o "$need_wssize" = 1 ] || break
|
||||
done
|
||||
}
|
||||
pktws_check_domain_http_bypass()
|
||||
@ -1374,28 +1338,15 @@ tpws_check_domain_http_bypass_()
|
||||
# $2 - encrypted test : 0 = plain, 1 - encrypted with server reply risk, 2 - encrypted without server reply risk
|
||||
# $3 - domain
|
||||
|
||||
local s mss s2 s3 oobdis pos sec="$2"
|
||||
local splits_tls='2 1 sniext+1 sniext+4 host+1 midsld 1,midsld 1,sniext+1,host+1,midsld,endhost-1'
|
||||
local splits_http='method+2 midsld method+2,midsld'
|
||||
|
||||
# simulteneous oob and disorder works properly only in linux. other systems retransmit oob byte without URG tcp flag and poison tcp stream.
|
||||
[ "$UNAME" = Linux ] && oobdis='--oob --disorder'
|
||||
local s mss s2 s3 pos sec="$2"
|
||||
if [ "$sec" = 0 ]; then
|
||||
for s in '--hostcase' '--hostspell=hoSt' '--hostdot' '--hosttab' '--hostnospace' '--domcase' ; do
|
||||
for s in '--hostcase' '--hostspell=hoSt' '--hostdot' '--hosttab' '--hostnospace' '--domcase' \
|
||||
'--hostpad=1024' '--hostpad=2048' '--hostpad=4096' '--hostpad=8192' '--hostpad=16384' ; do
|
||||
tpws_curl_test_update $1 $3 $s && [ "$SCANLEVEL" = quick ] && return
|
||||
done
|
||||
for s in 1024 2048 4096 8192 16384 ; do
|
||||
tpws_curl_test_update $1 $3 --hostpad=$s && [ "$SCANLEVEL" != force ] && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
break
|
||||
}
|
||||
done
|
||||
for s2 in '' '--hostcase' '--oob' '--disorder' ${oobdis:+"$oobdis"}; do
|
||||
for s in $splits_http ; do
|
||||
tpws_curl_test_update $1 $3 --split-pos=$s $s2 && [ "$SCANLEVEL" != force ] && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
break
|
||||
}
|
||||
for s2 in '' '--oob' '--disorder' '--oob --disorder'; do
|
||||
for s in '--split-http-req=method' '--split-http-req=method --hostcase' '--split-http-req=host' '--split-http-req=host --hostcase' ; do
|
||||
tpws_curl_test_update $1 $3 $s $s2 && [ "$SCANLEVEL" = quick ] && return
|
||||
done
|
||||
done
|
||||
for s in '--methodspace' '--unixeol' '--methodeol'; do
|
||||
@ -1404,21 +1355,30 @@ tpws_check_domain_http_bypass_()
|
||||
else
|
||||
for mss in '' 88; do
|
||||
s3=${mss:+--mss=$mss}
|
||||
for s2 in '' '--oob' '--disorder' ${oobdis:+"$oobdis"}; do
|
||||
for pos in $splits_tls; do
|
||||
tpws_curl_test_update $1 $3 --split-pos=$pos $s2 $s3 && warn_mss $s3 && [ "$SCANLEVEL" != force ] && {
|
||||
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 ] && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
break
|
||||
}
|
||||
done
|
||||
done
|
||||
for s in '' '--oob' '--disorder' ${oobdis:+"$oobdis"}; do
|
||||
for s2 in '--tlsrec=midsld' '--tlsrec=sniext+1 --split-pos=midsld' '--tlsrec=sniext+4 --split-pos=midsld' '--tlsrec=sniext+1 --split-pos=1,midsld' '--tlsrec=sniext+4 --split-pos=1,midsld' ; do
|
||||
tpws_curl_test_update $1 $3 $s2 $s $s3 && warn_mss $s3 && [ "$SCANLEVEL" != force ] && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
break
|
||||
}
|
||||
done
|
||||
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 ] && {
|
||||
[ "$SCANLEVEL" = quick ] && return
|
||||
break
|
||||
}
|
||||
done
|
||||
# only linux supports mss
|
||||
[ "$UNAME" = Linux -a "$sec" = 1 ] || break
|
||||
@ -1722,6 +1682,17 @@ ask_params()
|
||||
echo "installed curl version does not support http3 QUIC. tests disabled."
|
||||
fi
|
||||
|
||||
IGNORE_CA=0
|
||||
CURL_OPT=
|
||||
[ $ENABLE_HTTPS_TLS13 = 1 -o $ENABLE_HTTPS_TLS12 = 1 ] && {
|
||||
echo
|
||||
echo "on limited systems like openwrt CA certificates might not be installed to preserve space"
|
||||
echo "in such a case curl cannot verify server certificate and you should either install ca-bundle or disable verification"
|
||||
echo "however disabling verification will break https check if ISP does MitM attack and substitutes server certificate"
|
||||
ask_yes_no_var IGNORE_CA "do not verify server certificate"
|
||||
[ "$IGNORE_CA" = 1 ] && CURL_OPT=-k
|
||||
}
|
||||
|
||||
echo
|
||||
echo "sometimes ISPs use multiple DPIs or load balancing. bypass strategies may work unstable."
|
||||
printf "how many times to repeat each test (default: 1) : "
|
||||
|
@ -60,22 +60,11 @@ starts_with()
|
||||
esac
|
||||
return 1
|
||||
}
|
||||
extract_arg()
|
||||
{
|
||||
# $1 - arg number
|
||||
# $2,$3,... - args
|
||||
local n=$1
|
||||
while [ -n "$1" ]; do
|
||||
shift
|
||||
[ $n -eq 1 ] && { echo "$1"; return 0; }
|
||||
n=$(($n-1))
|
||||
done
|
||||
return 1
|
||||
}
|
||||
find_str_in_list()
|
||||
{
|
||||
# $1 - string
|
||||
# $2 - space separated values
|
||||
|
||||
local v
|
||||
[ -n "$1" ] && {
|
||||
for v in $2; do
|
||||
|
@ -221,7 +221,7 @@ check_system()
|
||||
else
|
||||
echo system is not either systemd, openrc or openwrt based
|
||||
echo easy installer can set up config settings but can\'t configure auto start
|
||||
echo you have to do it manually. check readme.md for manual setup info.
|
||||
echo you have to do it manually. check readme.txt for manual setup info.
|
||||
if [ -n "$1" ] || ask_yes_no N "do you want to continue"; then
|
||||
SYSTEM=linux
|
||||
else
|
||||
@ -232,7 +232,7 @@ check_system()
|
||||
elif [ "$UNAME" = "Darwin" ]; then
|
||||
SYSTEM=macos
|
||||
else
|
||||
echo easy installer only supports Linux and MacOS. check readme.md for supported systems and manual setup info.
|
||||
echo easy installer only supports Linux and MacOS. check readme.txt for supported systems and manual setup info.
|
||||
exitp 5
|
||||
fi
|
||||
echo system is based on $SYSTEM
|
||||
|
@ -163,7 +163,7 @@ static void fill_udphdr(struct udphdr *udp, uint16_t nsport, uint16_t ndport, ui
|
||||
udp->uh_sum = 0;
|
||||
}
|
||||
|
||||
static void fill_iphdr(struct ip *ip, const struct in_addr *src, const struct in_addr *dst, uint16_t pktlen, uint8_t proto, uint8_t ttl, uint8_t tos, uint16_t ip_id)
|
||||
static void fill_iphdr(struct ip *ip, const struct in_addr *src, const struct in_addr *dst, uint16_t pktlen, uint8_t proto, uint8_t ttl, uint8_t tos)
|
||||
{
|
||||
ip->ip_tos = tos;
|
||||
ip->ip_sum = 0;
|
||||
@ -171,7 +171,7 @@ static void fill_iphdr(struct ip *ip, const struct in_addr *src, const struct in
|
||||
ip->ip_v = 4;
|
||||
ip->ip_hl = 5;
|
||||
ip->ip_len = htons(pktlen);
|
||||
ip->ip_id = ip_id;
|
||||
ip->ip_id = 0;
|
||||
ip->ip_ttl = ttl;
|
||||
ip->ip_p = proto;
|
||||
ip->ip_src = *src;
|
||||
@ -196,7 +196,6 @@ bool prepare_tcp_segment4(
|
||||
uint32_t *timestamps,
|
||||
uint8_t ttl,
|
||||
uint8_t tos,
|
||||
uint16_t ip_id,
|
||||
uint32_t fooling,
|
||||
uint32_t badseq_increment,
|
||||
uint32_t badseq_ack_increment,
|
||||
@ -212,7 +211,7 @@ bool prepare_tcp_segment4(
|
||||
struct tcphdr *tcp = (struct tcphdr*)(ip+1);
|
||||
uint8_t *payload = (uint8_t*)(tcp+1)+tcpoptlen;
|
||||
|
||||
fill_iphdr(ip, &src->sin_addr, &dst->sin_addr, pktlen, IPPROTO_TCP, ttl, tos, ip_id);
|
||||
fill_iphdr(ip, &src->sin_addr, &dst->sin_addr, pktlen, IPPROTO_TCP, ttl, tos);
|
||||
fill_tcphdr(tcp,fooling,tcp_flags,nseq,nack_seq,src->sin_port,dst->sin_port,nwsize,scale_factor,timestamps,badseq_increment,badseq_ack_increment,len);
|
||||
|
||||
memcpy(payload,data,len);
|
||||
@ -315,9 +314,7 @@ bool prepare_tcp_segment(
|
||||
uint8_t scale_factor,
|
||||
uint32_t *timestamps,
|
||||
uint8_t ttl,
|
||||
uint8_t tos,
|
||||
uint16_t ip_id,
|
||||
uint32_t flow_label,
|
||||
uint8_t tos, uint32_t flow_label,
|
||||
uint32_t fooling,
|
||||
uint32_t badseq_increment,
|
||||
uint32_t badseq_ack_increment,
|
||||
@ -325,7 +322,7 @@ bool prepare_tcp_segment(
|
||||
uint8_t *buf, size_t *buflen)
|
||||
{
|
||||
return (src->sa_family==AF_INET && dst->sa_family==AF_INET) ?
|
||||
prepare_tcp_segment4((struct sockaddr_in *)src,(struct sockaddr_in *)dst,tcp_flags,nseq,nack_seq,nwsize,scale_factor,timestamps,ttl,tos,ip_id,fooling,badseq_increment,badseq_ack_increment,data,len,buf,buflen) :
|
||||
prepare_tcp_segment4((struct sockaddr_in *)src,(struct sockaddr_in *)dst,tcp_flags,nseq,nack_seq,nwsize,scale_factor,timestamps,ttl,tos,fooling,badseq_increment,badseq_ack_increment,data,len,buf,buflen) :
|
||||
(src->sa_family==AF_INET6 && dst->sa_family==AF_INET6) ?
|
||||
prepare_tcp_segment6((struct sockaddr_in6 *)src,(struct sockaddr_in6 *)dst,tcp_flags,nseq,nack_seq,nwsize,scale_factor,timestamps,ttl,flow_label,fooling,badseq_increment,badseq_ack_increment,data,len,buf,buflen) :
|
||||
false;
|
||||
@ -337,7 +334,6 @@ bool prepare_udp_segment4(
|
||||
const struct sockaddr_in *src, const struct sockaddr_in *dst,
|
||||
uint8_t ttl,
|
||||
uint8_t tos,
|
||||
uint16_t ip_id,
|
||||
uint32_t fooling,
|
||||
const uint8_t *padding, size_t padding_size,
|
||||
int padlen,
|
||||
@ -361,7 +357,7 @@ bool prepare_udp_segment4(
|
||||
uint8_t *payload = (uint8_t*)(udp+1);
|
||||
|
||||
|
||||
fill_iphdr(ip, &src->sin_addr, &dst->sin_addr, pktlen, IPPROTO_UDP, ttl, tos, ip_id);
|
||||
fill_iphdr(ip, &src->sin_addr, &dst->sin_addr, pktlen, IPPROTO_UDP, ttl, tos);
|
||||
fill_udphdr(udp, src->sin_port, dst->sin_port, datalen);
|
||||
|
||||
memcpy(payload,data,len);
|
||||
@ -467,9 +463,7 @@ bool prepare_udp_segment6(
|
||||
bool prepare_udp_segment(
|
||||
const struct sockaddr *src, const struct sockaddr *dst,
|
||||
uint8_t ttl,
|
||||
uint8_t tos,
|
||||
uint16_t ip_id,
|
||||
uint32_t flow_label,
|
||||
uint8_t tos, uint32_t flow_label,
|
||||
uint32_t fooling,
|
||||
const uint8_t *padding, size_t padding_size,
|
||||
int padlen,
|
||||
@ -477,7 +471,7 @@ bool prepare_udp_segment(
|
||||
uint8_t *buf, size_t *buflen)
|
||||
{
|
||||
return (src->sa_family==AF_INET && dst->sa_family==AF_INET) ?
|
||||
prepare_udp_segment4((struct sockaddr_in *)src,(struct sockaddr_in *)dst,ttl,tos,ip_id,fooling,padding,padding_size,padlen,data,len,buf,buflen) :
|
||||
prepare_udp_segment4((struct sockaddr_in *)src,(struct sockaddr_in *)dst,ttl,tos,fooling,padding,padding_size,padlen,data,len,buf,buflen) :
|
||||
(src->sa_family==AF_INET6 && dst->sa_family==AF_INET6) ?
|
||||
prepare_udp_segment6((struct sockaddr_in6 *)src,(struct sockaddr_in6 *)dst,ttl,flow_label,fooling,padding,padding_size,padlen,data,len,buf,buflen) :
|
||||
false;
|
||||
|
@ -61,7 +61,6 @@ uint32_t net16_add(uint16_t netorder_value, uint16_t cpuorder_increment);
|
||||
#define VERDICT_NOCSUM 4
|
||||
|
||||
#define IP4_TOS(ip_header) (ip_header ? ip_header->ip_tos : 0)
|
||||
#define IP4_IP_ID(ip_header) (ip_header ? ip_header->ip_id : 0)
|
||||
#define IP6_FLOW(ip6_header) (ip6_header ? ip6_header->ip6_ctlun.ip6_un1.ip6_un1_flow : 0)
|
||||
|
||||
// seq and wsize have network byte order
|
||||
@ -74,7 +73,6 @@ bool prepare_tcp_segment4(
|
||||
uint32_t *timestamps,
|
||||
uint8_t ttl,
|
||||
uint8_t tos,
|
||||
uint16_t ip_id,
|
||||
uint32_t fooling,
|
||||
uint32_t badseq_increment,
|
||||
uint32_t badseq_ack_increment,
|
||||
@ -102,9 +100,7 @@ bool prepare_tcp_segment(
|
||||
uint8_t scale_factor,
|
||||
uint32_t *timestamps,
|
||||
uint8_t ttl,
|
||||
uint8_t tos,
|
||||
uint16_t ip_id,
|
||||
uint32_t flow_label,
|
||||
uint8_t tos, uint32_t flow_label,
|
||||
uint32_t fooling,
|
||||
uint32_t badseq_increment,
|
||||
uint32_t badseq_ack_increment,
|
||||
@ -116,7 +112,6 @@ bool prepare_udp_segment4(
|
||||
const struct sockaddr_in *src, const struct sockaddr_in *dst,
|
||||
uint8_t ttl,
|
||||
uint8_t tos,
|
||||
uint16_t ip_id,
|
||||
uint32_t fooling,
|
||||
const uint8_t *padding, size_t padding_size,
|
||||
int padlen,
|
||||
@ -134,9 +129,7 @@ bool prepare_udp_segment6(
|
||||
bool prepare_udp_segment(
|
||||
const struct sockaddr *src, const struct sockaddr *dst,
|
||||
uint8_t ttl,
|
||||
uint8_t tos,
|
||||
uint16_t ip_id,
|
||||
uint32_t flow_label,
|
||||
uint8_t tos, uint32_t flow_label,
|
||||
uint32_t fooling,
|
||||
const uint8_t *padding, size_t padding_size,
|
||||
int padlen,
|
||||
|
170
nfq/desync.c
170
nfq/desync.c
@ -603,22 +603,6 @@ static void autottl_discover(t_ctrack *ctrack, bool bIpv6)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BSD
|
||||
// BSD pass to divert socket ip_id=0 and does not auto set it if sent via divert socket
|
||||
static uint16_t IP4_IP_ID_FIX(const struct ip *ip)
|
||||
{
|
||||
return ip ? ip->ip_id ? ip->ip_id : (uint16_t)random() : 0;
|
||||
}
|
||||
#define IP4_IP_ID_NEXT(ip_id) net16_add(ip_id,+1)
|
||||
#define IP4_IP_ID_PREV(ip_id) net16_add(ip_id,-1)
|
||||
#else
|
||||
// in linux kernel sets increasing ip_id if it's zero
|
||||
#define IP4_IP_ID_FIX(x) 0
|
||||
#define IP4_IP_ID_NEXT(ip_id) ip_id
|
||||
#define IP4_IP_ID_PREV(ip_id) ip_id
|
||||
#endif
|
||||
|
||||
|
||||
static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint32_t fwmark, const char *ifout, struct dissect *dis)
|
||||
{
|
||||
uint8_t verdict=VERDICT_PASS;
|
||||
@ -803,7 +787,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
case DESYNC_SYNACK:
|
||||
pkt1_len = sizeof(pkt1);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, TH_SYN|TH_ACK, dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||
ttl_fake,IP4_TOS(dis->ip),IP4_IP_ID_FIX(dis->ip),IP6_FLOW(dis->ip6),
|
||||
ttl_fake,IP4_TOS(dis->ip),IP6_FLOW(dis->ip6),
|
||||
dp->desync_fooling_mode,dp->desync_badseq_increment,dp->desync_badseq_ack_increment,
|
||||
NULL, 0, pkt1, &pkt1_len))
|
||||
{
|
||||
@ -827,7 +811,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
}
|
||||
pkt1_len = sizeof(pkt1);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||
ttl_orig,IP4_TOS(dis->ip),IP4_IP_ID_FIX(dis->ip),IP6_FLOW(dis->ip6),
|
||||
ttl_orig,IP4_TOS(dis->ip),IP6_FLOW(dis->ip6),
|
||||
0,0,0, dp->fake_syndata,dp->fake_syndata_size, pkt1,&pkt1_len))
|
||||
{
|
||||
return verdict;
|
||||
@ -860,7 +844,6 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
size_t multisplit_pos[MAX_SPLITS];
|
||||
int multisplit_count;
|
||||
int i;
|
||||
uint16_t ip_id;
|
||||
t_l7proto l7proto = UNKNOWN;
|
||||
|
||||
if (replay)
|
||||
@ -1182,6 +1165,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
DLOG("all multisplit pos are outside of this packet\n");
|
||||
}
|
||||
}
|
||||
seqovl_pos = ResolvePos(rdata_payload, rlen_payload, l7proto, &dp->seqovl);
|
||||
}
|
||||
else if (dp->desync_mode==DESYNC_FAKEDSPLIT || dp->desync_mode==DESYNC_FAKEDDISORDER || dp->desync_mode2==DESYNC_FAKEDSPLIT || dp->desync_mode2==DESYNC_FAKEDDISORDER)
|
||||
{
|
||||
@ -1203,26 +1187,15 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
DLOG("normalized regular split pos : %zu\n",split_pos);
|
||||
else
|
||||
DLOG("regular split pos is outside of this packet\n");
|
||||
seqovl_pos = ResolvePos(rdata_payload, rlen_payload, l7proto, &dp->seqovl);
|
||||
}
|
||||
else
|
||||
{
|
||||
multisplit_count=0;
|
||||
split_pos = 0;
|
||||
split_pos = seqovl_pos = 0;
|
||||
}
|
||||
if (dp->desync_mode==DESYNC_FAKEDSPLIT || dp->desync_mode==DESYNC_MULTISPLIT || dp->desync_mode2==DESYNC_FAKEDSPLIT || dp->desync_mode2==DESYNC_MULTISPLIT)
|
||||
{
|
||||
// split seqovl only uses absolute positive values
|
||||
seqovl_pos = (dp->seqovl.marker==PM_ABS && dp->seqovl.pos>0) ? dp->seqovl.pos : 0;
|
||||
if (seqovl_pos) DLOG("seqovl : %zu\n",seqovl_pos);
|
||||
}
|
||||
else if (dp->desync_mode==DESYNC_FAKEDDISORDER || dp->desync_mode==DESYNC_MULTIDISORDER || dp->desync_mode2==DESYNC_FAKEDDISORDER || dp->desync_mode2==DESYNC_MULTIDISORDER)
|
||||
{
|
||||
seqovl_pos = ResolvePos(rdata_payload, rlen_payload, l7proto, &dp->seqovl);
|
||||
seqovl_pos = pos_normalize(seqovl_pos,reasm_offset,dis->len_payload);
|
||||
if (seqovl_pos) DLOG("normalized seqovl : %zu\n",seqovl_pos);
|
||||
}
|
||||
else
|
||||
seqovl_pos = 0;
|
||||
seqovl_pos = pos_normalize(seqovl_pos,reasm_offset,dis->len_payload);
|
||||
if (seqovl_pos) DLOG("normalized seqovl pos : %zu\n",seqovl_pos);
|
||||
|
||||
// we do not need reasm buffer anymore
|
||||
reasm_orig_cancel(ctrack);
|
||||
@ -1243,7 +1216,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
case DESYNC_FAKE:
|
||||
if (reasm_offset) break;
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||
ttl_fake,IP4_TOS(dis->ip),IP4_IP_ID_FIX(dis->ip),IP6_FLOW(dis->ip6),
|
||||
ttl_fake,IP4_TOS(dis->ip),IP6_FLOW(dis->ip6),
|
||||
dp->desync_fooling_mode,dp->desync_badseq_increment,dp->desync_badseq_ack_increment,
|
||||
fake, fake_size, pkt1, &pkt1_len))
|
||||
{
|
||||
@ -1257,7 +1230,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
case DESYNC_RSTACK:
|
||||
if (reasm_offset) break;
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, TH_RST | (dp->desync_mode==DESYNC_RSTACK ? TH_ACK:0), dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||
ttl_fake,IP4_TOS(dis->ip),IP4_IP_ID_FIX(dis->ip),IP6_FLOW(dis->ip6),
|
||||
ttl_fake,IP4_TOS(dis->ip),IP6_FLOW(dis->ip6),
|
||||
dp->desync_fooling_mode,dp->desync_badseq_increment,dp->desync_badseq_ack_increment,
|
||||
NULL, 0, pkt1, &pkt1_len))
|
||||
{
|
||||
@ -1275,7 +1248,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
(!multisplit_count && (dp->desync_mode2==DESYNC_MULTISPLIT || dp->desync_mode2==DESYNC_MULTIDISORDER))))
|
||||
{
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||
ttl_orig,IP4_TOS(dis->ip),IP4_IP_ID_FIX(dis->ip),IP6_FLOW(dis->ip6),
|
||||
ttl_orig,IP4_TOS(dis->ip),IP6_FLOW(dis->ip6),
|
||||
fooling_orig,0,0,
|
||||
dis->data_payload, dis->len_payload, pkt1, &pkt1_len))
|
||||
{
|
||||
@ -1307,9 +1280,6 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
uint8_t ovlseg[DPI_DESYNC_MAX_FAKE_LEN+100], *seg;
|
||||
size_t seg_len,from,to;
|
||||
unsigned int seqovl;
|
||||
|
||||
ip_id = IP4_IP_ID_FIX(dis->ip);
|
||||
|
||||
for (i=0,from=0 ; i<=multisplit_count ; i++)
|
||||
{
|
||||
to = i==multisplit_count ? dis->len_payload : multisplit_pos[i];
|
||||
@ -1345,11 +1315,10 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
pkt1_len = sizeof(pkt1);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig,
|
||||
net32_add(dis->tcp->th_seq,from-seqovl), dis->tcp->th_ack,
|
||||
dis->tcp->th_win, scale_factor, timestamps,ttl_orig,IP4_TOS(dis->ip),ip_id,IP6_FLOW(dis->ip6),
|
||||
dis->tcp->th_win, scale_factor, timestamps,ttl_orig,IP4_TOS(dis->ip),IP6_FLOW(dis->ip6),
|
||||
fooling_orig,0,0,
|
||||
seg, seg_len, pkt1, &pkt1_len))
|
||||
return verdict;
|
||||
ip_id=IP4_IP_ID_NEXT(ip_id);
|
||||
DLOG("sending multisplit part %d %zu-%zu len=%zu seqovl=%u : ",i+1,from,to-1,to-from,seqovl);
|
||||
hexdump_limited_dlog(seg,seg_len,PKTDATA_MAXDUMP); DLOG("\n");
|
||||
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
||||
@ -1379,9 +1348,6 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
uint8_t ovlseg[DPI_DESYNC_MAX_FAKE_LEN+100], *seg;
|
||||
size_t seg_len,from,to;
|
||||
unsigned int seqovl;
|
||||
|
||||
ip_id = IP4_IP_ID_FIX(dis->ip);
|
||||
|
||||
for (i=multisplit_count-1,to=dis->len_payload ; i>=-1 ; i--)
|
||||
{
|
||||
from = i>=0 ? multisplit_pos[i] : 0;
|
||||
@ -1414,11 +1380,10 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
pkt1_len = sizeof(pkt1);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig,
|
||||
net32_add(dis->tcp->th_seq,from-seqovl), dis->tcp->th_ack,
|
||||
dis->tcp->th_win, scale_factor, timestamps,ttl_orig,IP4_TOS(dis->ip),ip_id,IP6_FLOW(dis->ip6),
|
||||
dis->tcp->th_win, scale_factor, timestamps,ttl_orig,IP4_TOS(dis->ip),IP6_FLOW(dis->ip6),
|
||||
fooling_orig,0,0,
|
||||
seg, seg_len, pkt1, &pkt1_len))
|
||||
return verdict;
|
||||
ip_id=IP4_IP_ID_PREV(ip_id);
|
||||
DLOG("sending multisplit part %d %zu-%zu len=%zu seqovl=%u : ",i+2,from,to-1,to-from,seqovl);
|
||||
hexdump_limited_dlog(seg,seg_len,PKTDATA_MAXDUMP); DLOG("\n");
|
||||
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
||||
@ -1436,8 +1401,6 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
size_t seg_len;
|
||||
unsigned int seqovl;
|
||||
|
||||
ip_id = IP4_IP_ID_FIX(dis->ip);
|
||||
|
||||
if (seqovl_pos>=split_pos)
|
||||
{
|
||||
DLOG("seqovl>=split_pos (%u>=%zu). cancelling seqovl.\n",seqovl_pos,split_pos);
|
||||
@ -1446,42 +1409,44 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
else
|
||||
seqovl = seqovl_pos;
|
||||
|
||||
if (seqovl)
|
||||
if (split_pos<dis->len_payload)
|
||||
{
|
||||
seg_len = dis->len_payload-split_pos+seqovl;
|
||||
if (seg_len>sizeof(fakeseg))
|
||||
if (seqovl)
|
||||
{
|
||||
DLOG("seqovl is too large\n");
|
||||
return verdict;
|
||||
seg_len = dis->len_payload-split_pos+seqovl;
|
||||
if (seg_len>sizeof(fakeseg))
|
||||
{
|
||||
DLOG("seqovl is too large\n");
|
||||
return verdict;
|
||||
}
|
||||
fill_pattern(fakeseg,seqovl,dp->seqovl_pattern,sizeof(dp->seqovl_pattern));
|
||||
memcpy(fakeseg+seqovl,dis->data_payload+split_pos,dis->len_payload-split_pos);
|
||||
seg = fakeseg;
|
||||
}
|
||||
fill_pattern(fakeseg,seqovl,dp->seqovl_pattern,sizeof(dp->seqovl_pattern));
|
||||
memcpy(fakeseg+seqovl,dis->data_payload+split_pos,dis->len_payload-split_pos);
|
||||
seg = fakeseg;
|
||||
else
|
||||
{
|
||||
seg = dis->data_payload+split_pos;
|
||||
seg_len = dis->len_payload-split_pos;
|
||||
}
|
||||
|
||||
pkt1_len = sizeof(pkt1);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, net32_add(dis->tcp->th_seq , split_pos - seqovl), dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||
ttl_orig,IP4_TOS(dis->ip),IP6_FLOW(dis->ip6),
|
||||
fooling_orig,dp->desync_badseq_increment,dp->desync_badseq_ack_increment,
|
||||
seg, seg_len, pkt1, &pkt1_len))
|
||||
return verdict;
|
||||
DLOG("sending 2nd out-of-order tcp segment %zu-%zu len=%zu seqovl=%u : ",split_pos,dis->len_payload-1, dis->len_payload-split_pos, seqovl);
|
||||
hexdump_limited_dlog(seg,seg_len,PKTDATA_MAXDUMP); DLOG("\n");
|
||||
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
||||
return verdict;
|
||||
}
|
||||
else
|
||||
{
|
||||
seg = dis->data_payload+split_pos;
|
||||
seg_len = dis->len_payload-split_pos;
|
||||
}
|
||||
pkt1_len = sizeof(pkt1);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, net32_add(dis->tcp->th_seq , split_pos - seqovl), dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||
ttl_orig,IP4_TOS(dis->ip),ip_id,IP6_FLOW(dis->ip6),
|
||||
fooling_orig,dp->desync_badseq_increment,dp->desync_badseq_ack_increment,
|
||||
seg, seg_len, pkt1, &pkt1_len))
|
||||
return verdict;
|
||||
ip_id=IP4_IP_ID_PREV(ip_id);
|
||||
DLOG("sending 2nd out-of-order tcp segment %zu-%zu len=%zu seqovl=%u : ",split_pos,dis->len_payload-1, dis->len_payload-split_pos, seqovl);
|
||||
hexdump_limited_dlog(seg,seg_len,PKTDATA_MAXDUMP); DLOG("\n");
|
||||
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
||||
return verdict;
|
||||
|
||||
seg_len = sizeof(fakeseg);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||
ttl_fake,IP4_TOS(dis->ip),ip_id,IP6_FLOW(dis->ip6),
|
||||
ttl_fake,IP4_TOS(dis->ip),IP6_FLOW(dis->ip6),
|
||||
dp->desync_fooling_mode,dp->desync_badseq_increment,dp->desync_badseq_ack_increment,
|
||||
zeropkt, split_pos, fakeseg, &seg_len))
|
||||
return verdict;
|
||||
ip_id=IP4_IP_ID_PREV(ip_id);
|
||||
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(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, seg_len))
|
||||
@ -1489,17 +1454,15 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
|
||||
pkt1_len = sizeof(pkt1);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||
ttl_orig,IP4_TOS(dis->ip),ip_id,IP6_FLOW(dis->ip6),
|
||||
ttl_orig,IP4_TOS(dis->ip),IP6_FLOW(dis->ip6),
|
||||
fooling_orig,dp->desync_badseq_increment,dp->desync_badseq_ack_increment,
|
||||
dis->data_payload, split_pos, pkt1, &pkt1_len))
|
||||
return verdict;
|
||||
ip_id=IP4_IP_ID_PREV(ip_id);
|
||||
DLOG("sending 1st out-of-order tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos);
|
||||
hexdump_limited_dlog(dis->data_payload,split_pos,PKTDATA_MAXDUMP); DLOG("\n");
|
||||
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
||||
return verdict;
|
||||
|
||||
if (dis->ip) ((struct ip*)fakeseg)->ip_id = ip_id;
|
||||
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(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, seg_len))
|
||||
@ -1514,15 +1477,12 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
uint8_t fakeseg[DPI_DESYNC_MAX_FAKE_LEN+100],ovlseg[DPI_DESYNC_MAX_FAKE_LEN+100], *seg;
|
||||
size_t fakeseg_len,seg_len;
|
||||
|
||||
ip_id = IP4_IP_ID_FIX(dis->ip);
|
||||
|
||||
fakeseg_len = sizeof(fakeseg);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||
ttl_fake,IP4_TOS(dis->ip),ip_id,IP6_FLOW(dis->ip6),
|
||||
ttl_fake,IP4_TOS(dis->ip),IP6_FLOW(dis->ip6),
|
||||
dp->desync_fooling_mode,dp->desync_badseq_increment,dp->desync_badseq_ack_increment,
|
||||
zeropkt, split_pos, fakeseg, &fakeseg_len))
|
||||
return verdict;
|
||||
ip_id=IP4_IP_ID_NEXT(ip_id);
|
||||
DLOG("sending fake(1) 1st tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos);
|
||||
hexdump_limited_dlog(zeropkt,split_pos,PKTDATA_MAXDUMP); DLOG("\n");
|
||||
if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, fakeseg_len))
|
||||
@ -1554,11 +1514,10 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
|
||||
pkt1_len = sizeof(pkt1);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, net32_add(dis->tcp->th_seq,-seqovl), dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||
ttl_orig,IP4_TOS(dis->ip),ip_id,IP6_FLOW(dis->ip6),
|
||||
ttl_orig,IP4_TOS(dis->ip),IP6_FLOW(dis->ip6),
|
||||
fooling_orig,dp->desync_badseq_increment,dp->desync_badseq_ack_increment,
|
||||
seg, seg_len, pkt1, &pkt1_len))
|
||||
return verdict;
|
||||
ip_id=IP4_IP_ID_NEXT(ip_id);
|
||||
DLOG("sending 1st tcp segment 0-%zu len=%zu seqovl=%u : ",split_pos-1, split_pos, seqovl);
|
||||
hexdump_limited_dlog(seg,seg_len,PKTDATA_MAXDUMP); DLOG("\n");
|
||||
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
||||
@ -1576,23 +1535,25 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (dis->ip) ((struct ip*)fakeseg)->ip_id = ip_id;
|
||||
ip_id=IP4_IP_ID_NEXT(ip_id);
|
||||
|
||||
DLOG("sending fake(2) 1st tcp segment 0-%zu len=%zu : ",split_pos-1, split_pos);
|
||||
hexdump_limited_dlog(zeropkt,split_pos,PKTDATA_MAXDUMP); DLOG("\n");
|
||||
if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, fakeseg_len))
|
||||
return verdict;
|
||||
|
||||
pkt1_len = sizeof(pkt1);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, net32_add(dis->tcp->th_seq,split_pos), dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||
ttl_orig,IP4_TOS(dis->ip),ip_id,IP6_FLOW(dis->ip6),
|
||||
fooling_orig,dp->desync_badseq_increment,dp->desync_badseq_ack_increment,
|
||||
dis->data_payload+split_pos, dis->len_payload-split_pos, pkt1, &pkt1_len))
|
||||
return verdict;
|
||||
DLOG("sending 2nd tcp segment %zu-%zu len=%zu : ",split_pos,dis->len_payload-1, dis->len_payload-split_pos);
|
||||
hexdump_limited_dlog(dis->data_payload+split_pos,dis->len_payload-split_pos,PKTDATA_MAXDUMP); DLOG("\n");
|
||||
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
||||
return verdict;
|
||||
if (split_pos<dis->len_payload)
|
||||
{
|
||||
pkt1_len = sizeof(pkt1);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, net32_add(dis->tcp->th_seq,split_pos), dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||
ttl_orig,IP4_TOS(dis->ip),IP6_FLOW(dis->ip6),
|
||||
fooling_orig,dp->desync_badseq_increment,dp->desync_badseq_ack_increment,
|
||||
dis->data_payload+split_pos, dis->len_payload-split_pos, pkt1, &pkt1_len))
|
||||
return verdict;
|
||||
DLOG("sending 2nd tcp segment %zu-%zu len=%zu : ",split_pos,dis->len_payload-1, dis->len_payload-split_pos);
|
||||
hexdump_limited_dlog(dis->data_payload+split_pos,dis->len_payload-split_pos,PKTDATA_MAXDUMP); DLOG("\n");
|
||||
if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
|
||||
return verdict;
|
||||
}
|
||||
|
||||
return VERDICT_DROP;
|
||||
}
|
||||
@ -1605,9 +1566,8 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
uint8_t pkt3[DPI_DESYNC_MAX_FAKE_LEN+100], *pkt_orig;
|
||||
size_t pkt_orig_len;
|
||||
|
||||
ip_id = IP4_IP_ID_FIX(dis->ip);
|
||||
uint32_t ident = dis->ip ? ip_id ? ip_id : htons(1+random()%0xFFFF) : htonl(1+random()%0xFFFFFFFF);
|
||||
size_t ipfrag_pos = (dp->desync_ipfrag_pos_tcp && dp->desync_ipfrag_pos_tcp<dis->transport_len) ? dp->desync_ipfrag_pos_tcp : 24;
|
||||
uint32_t ident = dis->ip ? dis->ip->ip_id ? dis->ip->ip_id : htons(1+random()%0xFFFF) : htonl(1+random()%0xFFFFFFFF);
|
||||
|
||||
pkt1_len = sizeof(pkt1);
|
||||
pkt2_len = sizeof(pkt2);
|
||||
@ -1775,7 +1735,6 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
size_t fake_size;
|
||||
char host[256];
|
||||
bool bHaveHost=false;
|
||||
uint16_t ip_id;
|
||||
|
||||
if (IsQUICInitial(dis->data_payload,dis->len_payload))
|
||||
{
|
||||
@ -2046,7 +2005,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
break;
|
||||
}
|
||||
case DESYNC_FAKE:
|
||||
if (!prepare_udp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, ttl_fake, IP4_TOS(dis->ip),IP4_IP_ID_FIX(dis->ip),IP6_FLOW(dis->ip6), dp->desync_fooling_mode, NULL, 0, 0, fake, fake_size, pkt1, &pkt1_len))
|
||||
if (!prepare_udp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, ttl_fake, IP4_TOS(dis->ip),IP6_FLOW(dis->ip6), dp->desync_fooling_mode, NULL, 0, 0, fake, fake_size, pkt1, &pkt1_len))
|
||||
return verdict;
|
||||
DLOG("sending fake : ");
|
||||
hexdump_limited_dlog(fake,fake_size,PKTDATA_MAXDUMP); DLOG("\n");
|
||||
@ -2061,7 +2020,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
if (dis->ip6 && (dp->desync_mode2==DESYNC_NONE || !desync_valid_second_stage_udp(dp->desync_mode2)))
|
||||
{
|
||||
if (!prepare_udp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst,
|
||||
ttl_orig,IP4_TOS(dis->ip),IP4_IP_ID_FIX(dis->ip),IP6_FLOW(dis->ip6),
|
||||
ttl_orig,IP4_TOS(dis->ip),IP6_FLOW(dis->ip6),
|
||||
fooling_orig,NULL,0,0,
|
||||
dis->data_payload, dis->len_payload, pkt1, &pkt1_len))
|
||||
{
|
||||
@ -2084,7 +2043,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
{
|
||||
case DESYNC_UDPLEN:
|
||||
pkt1_len = sizeof(pkt1);
|
||||
if (!prepare_udp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, ttl_orig,IP4_TOS(dis->ip),IP4_IP_ID_FIX(dis->ip),IP6_FLOW(dis->ip6), fooling_orig, dp->udplen_pattern, sizeof(dp->udplen_pattern), dp->udplen_increment, dis->data_payload, dis->len_payload, pkt1, &pkt1_len))
|
||||
if (!prepare_udp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, ttl_orig,IP4_TOS(dis->ip),IP6_FLOW(dis->ip6), fooling_orig, dp->udplen_pattern, sizeof(dp->udplen_pattern), dp->udplen_increment, dis->data_payload, dis->len_payload, pkt1, &pkt1_len))
|
||||
{
|
||||
DLOG("could not construct packet with modified length. too large ?\n");
|
||||
break;
|
||||
@ -2109,7 +2068,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
memcpy(pkt2+pkt2_len,dis->data_payload+1,szcopy);
|
||||
pkt2_len+=szcopy;
|
||||
pkt1_len = sizeof(pkt1);
|
||||
if (!prepare_udp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, ttl_orig,IP4_TOS(dis->ip),IP4_IP_ID_FIX(dis->ip),IP6_FLOW(dis->ip6), fooling_orig, NULL, 0 , 0, pkt2, pkt2_len, pkt1, &pkt1_len))
|
||||
if (!prepare_udp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, ttl_orig,IP4_TOS(dis->ip),IP6_FLOW(dis->ip6), fooling_orig, NULL, 0 , 0, pkt2, pkt2_len, pkt1, &pkt1_len))
|
||||
{
|
||||
DLOG("could not construct packet with modified length. too large ?\n");
|
||||
break;
|
||||
@ -2131,10 +2090,9 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
uint8_t pkt3[DPI_DESYNC_MAX_FAKE_LEN+100], *pkt_orig;
|
||||
size_t pkt_orig_len;
|
||||
|
||||
// freebsd do not set ip.id
|
||||
ip_id = IP4_IP_ID_FIX(dis->ip);
|
||||
uint32_t ident = dis->ip ? ip_id ? ip_id : htons(1+random()%0xFFFF) : htonl(1+random()%0xFFFFFFFF);
|
||||
size_t ipfrag_pos = (dp->desync_ipfrag_pos_udp && dp->desync_ipfrag_pos_udp<dis->transport_len) ? dp->desync_ipfrag_pos_udp : sizeof(struct udphdr);
|
||||
// freebsd do not set ip.id
|
||||
uint32_t ident = dis->ip ? dis->ip->ip_id ? dis->ip->ip_id : htons(1+random()%0xFFFF) : htonl(1+random()%0xFFFFFFFF);
|
||||
|
||||
pkt1_len = sizeof(pkt1);
|
||||
pkt2_len = sizeof(pkt2);
|
||||
|
@ -844,11 +844,6 @@ static void split_compat(struct desync_profile *dp)
|
||||
dp->splits[dp->split_count].pos = 2;
|
||||
dp->split_count++;
|
||||
}
|
||||
if ((dp->seqovl.marker!=PM_ABS || dp->seqovl.pos<0) && (dp->desync_mode==DESYNC_FAKEDSPLIT || dp->desync_mode==DESYNC_MULTISPLIT || dp->desync_mode2==DESYNC_FAKEDSPLIT || dp->desync_mode2==DESYNC_MULTISPLIT))
|
||||
{
|
||||
DLOG_ERR("split seqovl supports only absolute positive positions\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void SplitDebug(void)
|
||||
|
Loading…
Reference in New Issue
Block a user