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