Compare commits

..

8 Commits

7 changed files with 307 additions and 207 deletions

View File

@ -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 done
test_has_fake $desync || break 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)
done f2=$(extract_arg 2 $pos)
fi pktws_curl_test_update $1 $3 --dpi-desync=multidisorder --dpi-desync-split-pos=$f2 --dpi-desync-split-seqovl=$f $e && {
for pos in 2 3 4 5 10 50; do [ "$SCANLEVEL" = quick ] && return
pktws_curl_test_update $1 $3 $s --dpi-desync-split-seqovl=$(($pos - 1)) --dpi-desync-split-pos=$pos $e && [ "$SCANLEVEL" = quick ] && return need_wssize=0
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 done
fi
}
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,31 +1404,22 @@ 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
tpws_curl_test_update $1 $3 $s2 $s3 && warn_mss $s3 && [ "$SCANLEVEL" != force ] && {
[ "$SCANLEVEL" = quick ] && return [ "$SCANLEVEL" = quick ] && return
break break
} }
done done
done
# only linux supports mss # only linux supports mss
[ "$UNAME" = Linux -a "$sec" = 1 ] || break [ "$UNAME" = Linux -a "$sec" = 1 ] || break
done done
@ -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) : "

View File

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

View File

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

View File

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

View File

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

View File

@ -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;
} }
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); seqovl_pos = pos_normalize(seqovl_pos,reasm_offset,dis->len_payload);
if (seqovl_pos) DLOG("normalized seqovl pos : %zu\n",seqovl_pos); 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,8 +1446,6 @@ 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; seg_len = dis->len_payload-split_pos+seqovl;
@ -1428,25 +1463,25 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
seg = dis->data_payload+split_pos; seg = dis->data_payload+split_pos;
seg_len = dis->len_payload-split_pos; seg_len = dis->len_payload-split_pos;
} }
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 , split_pos - 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 , split_pos - 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_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); 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"); 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))
return verdict; 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,17 +1576,16 @@ 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); 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, 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), 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, dis->len_payload-split_pos, pkt1, &pkt1_len)) dis->data_payload+split_pos, dis->len_payload-split_pos, pkt1, &pkt1_len))
return verdict; return verdict;
@ -1553,7 +1593,6 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
hexdump_limited_dlog(dis->data_payload+split_pos,dis->len_payload-split_pos,PKTDATA_MAXDUMP); DLOG("\n"); 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)) if (!rawsend((struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
return verdict; 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);

View File

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