mirror of
https://github.com/bol-van/zapret.git
synced 2025-12-18 05:28:13 +03:00
Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
994e9c3488 | ||
|
|
d4cfb6800f | ||
|
|
a36e6ee60e | ||
|
|
813fe416f8 | ||
|
|
8e766744b6 | ||
|
|
0bc0997191 | ||
|
|
b056ba95a1 | ||
|
|
bae45abfbf | ||
|
|
21fc356476 | ||
|
|
88b6b791e9 | ||
|
|
48185174cf | ||
|
|
aa8d903bb1 | ||
|
|
cb653bedd6 | ||
|
|
534c88c96a | ||
|
|
7be9790839 | ||
|
|
14d7f27b6a | ||
|
|
97cefbace9 | ||
|
|
43cea80619 | ||
|
|
ce7d91a7ca | ||
|
|
105ac57655 | ||
|
|
06f5305617 | ||
|
|
45c3f00539 | ||
|
|
0c0c2547db | ||
|
|
60d182b97e | ||
|
|
907b530068 | ||
|
|
8763768180 | ||
|
|
793cd76621 | ||
|
|
9b47b21918 | ||
|
|
caa364e0ed | ||
|
|
76992dc3d9 | ||
|
|
0b8e0dc97d | ||
|
|
1408c38522 | ||
|
|
cea968d259 | ||
|
|
f91bca170a | ||
|
|
9d5c9191be | ||
|
|
f4ce79a97c | ||
|
|
845b9edf85 | ||
|
|
5ec5ce8246 | ||
|
|
29935b0934 | ||
|
|
fe12b55181 | ||
|
|
2cafc7ddeb | ||
|
|
2daf764760 | ||
|
|
078022bccf | ||
|
|
57778b6249 |
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -2,3 +2,4 @@
|
||||
*.cmd eol=crlf
|
||||
*.bat eol=crlf
|
||||
init.d/windivert.filter.examples/** eol=crlf
|
||||
files/** binary
|
||||
|
||||
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -468,7 +468,7 @@ jobs:
|
||||
(
|
||||
cd ${{ env.repo_dir }}
|
||||
rm -rf binaries/{android*,freebsd*,mac*,win*,x86_64/tpws_wsl.tgz} \
|
||||
init.d/{openrc,macos,pfsense,runit,s6,systemd} \
|
||||
init.d/{openrc,macos,pfsense,runit,s6,systemd,windivert.filter.examples} \
|
||||
tpws nfq ip2net mdig docs files/huawei Makefile
|
||||
)
|
||||
tar --owner=0 --group=0 -czf ${{ env.repo_dir }}-openwrt-embedded.tar.gz ${{ env.repo_dir }}
|
||||
|
||||
102
blockcheck.sh
102
blockcheck.sh
@@ -56,7 +56,7 @@ HDRTEMP=/tmp/zapret-hdr
|
||||
NFT_TABLE=blockcheck
|
||||
|
||||
DNSCHECK_DNS=${DNSCHECK_DNS:-8.8.8.8 1.1.1.1 77.88.8.1}
|
||||
DNSCHECK_DOM=${DNSCHECK_DOM:-pornhub.com ntc.party rutracker.org www.torproject.org bbc.com}
|
||||
DNSCHECK_DOM=${DNSCHECK_DOM:-pornhub.com ej.ru rutracker.org www.torproject.org bbc.com}
|
||||
DOH_SERVERS=${DOH_SERVERS:-"https://cloudflare-dns.com/dns-query https://dns.google/dns-query https://dns.quad9.net/dns-query https://dns.adguard.com/dns-query https://common.dot.dns.yandex.net/dns-query"}
|
||||
DNSCHECK_DIG1=/tmp/dig1.txt
|
||||
DNSCHECK_DIG2=/tmp/dig2.txt
|
||||
@@ -219,7 +219,7 @@ doh_resolve()
|
||||
# $1 - ip version 4/6
|
||||
# $2 - hostname
|
||||
# $3 - doh server URL. use $DOH_SERVER if empty
|
||||
$MDIG --family=$1 --dns-make-query=$2 | $CURL --max-time $CURL_MAX_TIME_DOH -s --data-binary @- -H "Content-Type: application/dns-message" "${3:-$DOH_SERVER}" | $MDIG --dns-parse-query
|
||||
"$MDIG" --family=$1 --dns-make-query=$2 | "$CURL" --max-time $CURL_MAX_TIME_DOH -s --data-binary @- -H "Content-Type: application/dns-message" "${3:-$DOH_SERVER}" | "$MDIG" --dns-parse-query
|
||||
}
|
||||
doh_find_working()
|
||||
{
|
||||
@@ -247,7 +247,7 @@ mdig_vars()
|
||||
# $1 - ip version 4/6
|
||||
# $2 - hostname
|
||||
|
||||
hostvar=$(echo $2 | sed -e 's/[\.-]/_/g')
|
||||
hostvar=$(echo $2 | sed -e 's/[\./?&#@%*$^:~=!()+-]/_/g')
|
||||
cachevar=DNSCACHE_${hostvar}_$1
|
||||
countvar=${cachevar}_COUNT
|
||||
eval count=\$${countvar}
|
||||
@@ -278,41 +278,45 @@ mdig_cache()
|
||||
mdig_resolve()
|
||||
{
|
||||
# $1 - ip version 4/6
|
||||
# $2 - hostname
|
||||
# $2 - var to receive result
|
||||
# $3 - hostname, possibly with uri : rutracker.org/xxx/xxxx
|
||||
local hostvar cachevar countvar count n sdom
|
||||
|
||||
local hostvar cachevar countvar count ip n
|
||||
mdig_vars "$@"
|
||||
split_by_separator "$3" / sdom
|
||||
mdig_vars "$1" "$sdom"
|
||||
if [ -n "$count" ]; then
|
||||
n=$(random 0 $(($count-1)))
|
||||
eval ip=\$${cachevar}_$n
|
||||
echo $ip
|
||||
eval $2=\$${cachevar}_$n
|
||||
return 0
|
||||
else
|
||||
mdig_cache "$@" && mdig_resolve "$@"
|
||||
mdig_cache "$1" "$sdom" && mdig_resolve "$1" "$2" "$sdom"
|
||||
fi
|
||||
}
|
||||
mdig_resolve_all()
|
||||
{
|
||||
# $1 - ip version 4/6
|
||||
# $2 - hostname
|
||||
# $2 - var to receive result
|
||||
# $3 - hostname
|
||||
|
||||
local hostvar cachevar countvar count ip ips n
|
||||
mdig_vars "$@"
|
||||
local hostvar cachevar countvar count ip__ ips__ n sdom
|
||||
|
||||
split_by_separator "$3" / sdom
|
||||
mdig_vars "$1" "$sdom"
|
||||
if [ -n "$count" ]; then
|
||||
n=0
|
||||
while [ "$n" -le $count ]; do
|
||||
eval ip=\$${cachevar}_$n
|
||||
if [ -n "$ips" ]; then
|
||||
ips="$ips $ip"
|
||||
eval ip__=\$${cachevar}_$n
|
||||
if [ -n "$ips__" ]; then
|
||||
ips__="$ips__ $ip__"
|
||||
else
|
||||
ips="$ip"
|
||||
ips__="$ip__"
|
||||
fi
|
||||
n=$(($n + 1))
|
||||
done
|
||||
echo "$ips"
|
||||
eval $2="\$ips__"
|
||||
return 0
|
||||
else
|
||||
mdig_cache "$@" && mdig_resolve_all "$@"
|
||||
mdig_cache "$1" "$sdom" && mdig_resolve_all "$1" "$2" "$sdom"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -423,7 +427,7 @@ check_system()
|
||||
}
|
||||
echo firewall type is $FWTYPE
|
||||
echo CURL=$CURL
|
||||
$CURL --version
|
||||
"$CURL" --version
|
||||
}
|
||||
|
||||
zp_already_running()
|
||||
@@ -479,7 +483,7 @@ check_prerequisites()
|
||||
exitp 6
|
||||
}
|
||||
|
||||
local prog progs='curl'
|
||||
local prog progs="$CURL"
|
||||
[ "$SKIP_PKTWS" = 1 ] || {
|
||||
case "$UNAME" in
|
||||
Linux)
|
||||
@@ -595,12 +599,12 @@ curl_translate_code()
|
||||
curl_supports_tls13()
|
||||
{
|
||||
local r
|
||||
$CURL --tlsv1.3 -Is -o /dev/null --max-time 1 http://127.0.0.1:65535 2>/dev/null
|
||||
"$CURL" --tlsv1.3 -Is -o /dev/null --max-time 1 http://127.0.0.1:65535 2>/dev/null
|
||||
# return code 2 = init failed. likely bad command line options
|
||||
[ $? = 2 ] && return 1
|
||||
# curl can have tlsv1.3 key present but ssl library without TLS 1.3 support
|
||||
# this is online test because there's no other way to trigger library incompatibility case
|
||||
$CURL --tlsv1.3 --max-time 1 -Is -o /dev/null https://iana.org 2>/dev/null
|
||||
"$CURL" --tlsv1.3 --max-time 1 -Is -o /dev/null https://iana.org 2>/dev/null
|
||||
r=$?
|
||||
[ $r != 4 -a $r != 35 ]
|
||||
}
|
||||
@@ -608,16 +612,16 @@ curl_supports_tls13()
|
||||
curl_supports_tlsmax()
|
||||
{
|
||||
# supported only in OpenSSL and LibreSSL
|
||||
$CURL --version | grep -Fq -e OpenSSL -e LibreSSL -e BoringSSL -e GnuTLS -e quictls || return 1
|
||||
"$CURL" --version | grep -Fq -e OpenSSL -e LibreSSL -e BoringSSL -e GnuTLS -e quictls || return 1
|
||||
# supported since curl 7.54
|
||||
$CURL --tls-max 1.2 -Is -o /dev/null --max-time 1 http://127.0.0.1:65535 2>/dev/null
|
||||
"$CURL" --tls-max 1.2 -Is -o /dev/null --max-time 1 http://127.0.0.1:65535 2>/dev/null
|
||||
# return code 2 = init failed. likely bad command line options
|
||||
[ $? != 2 ]
|
||||
}
|
||||
|
||||
curl_supports_connect_to()
|
||||
{
|
||||
$CURL --connect-to 127.0.0.1:: -o /dev/null --max-time 1 http://127.0.0.1:65535 2>/dev/null
|
||||
"$CURL" --connect-to 127.0.0.1:: -o /dev/null --max-time 1 http://127.0.0.1:65535 2>/dev/null
|
||||
[ "$?" != 2 ]
|
||||
}
|
||||
|
||||
@@ -625,7 +629,7 @@ curl_supports_http3()
|
||||
{
|
||||
# if it has http3 : curl: (3) HTTP/3 requested for non-HTTPS URL
|
||||
# otherwise : curl: (2) option --http3-only: is unknown
|
||||
$CURL --connect-to 127.0.0.1:: -o /dev/null --max-time 1 --http3-only http://127.0.0.1:65535 2>/dev/null
|
||||
"$CURL" --connect-to 127.0.0.1:: -o /dev/null --max-time 1 --http3-only http://127.0.0.1:65535 2>/dev/null
|
||||
[ "$?" != 2 ]
|
||||
}
|
||||
|
||||
@@ -653,10 +657,10 @@ curl_with_subst_ip()
|
||||
*:*) ip="[$ip]" ;;
|
||||
esac
|
||||
local connect_to="--connect-to $1::$ip${2:+:$2}" arg
|
||||
shift ; shift ; shift
|
||||
shift ; shift ; shift;
|
||||
[ "$CURL_VERBOSE" = 1 ] && arg="-v"
|
||||
[ "$CURL_CMD" = 1 ] && echo $CURL ${arg:+$arg }$connect_to "$@"
|
||||
ALL_PROXY="$ALL_PROXY" $CURL ${arg:+$arg }$connect_to "$@"
|
||||
ALL_PROXY="$ALL_PROXY" "$CURL" ${arg:+$arg }$connect_to "$@"
|
||||
}
|
||||
curl_with_dig()
|
||||
{
|
||||
@@ -665,10 +669,13 @@ curl_with_dig()
|
||||
# $3 - port
|
||||
# $4+ - curl params
|
||||
local dom=$2 port=$3
|
||||
local ip=$(mdig_resolve $1 $dom)
|
||||
local sdom suri ip
|
||||
|
||||
split_by_separator "$dom" / sdom suri
|
||||
mdig_resolve $1 ip $sdom
|
||||
shift ; shift ; shift
|
||||
if [ -n "$ip" ]; then
|
||||
curl_with_subst_ip $dom $port $ip "$@"
|
||||
curl_with_subst_ip "$sdom" "$port" "$ip" "$@"
|
||||
else
|
||||
return 6
|
||||
fi
|
||||
@@ -731,7 +738,7 @@ curl_test_https_tls12()
|
||||
# $3 - subst ip
|
||||
|
||||
# do not use tls 1.3 to make sure server certificate is not encrypted
|
||||
curl_probe $1 $2 $HTTPS_PORT "$3" -ISs -A "$USER_AGENT" --max-time $CURL_MAX_TIME $CURL_OPT --tlsv1.2 $TLSMAX12 "https://$2" -o /dev/null 2>&1
|
||||
curl_probe $1 $2 $HTTPS_PORT "$3" $HTTPS_HEAD -Ss -A "$USER_AGENT" --max-time $CURL_MAX_TIME $CURL_OPT --tlsv1.2 $TLSMAX12 "https://$2" -o /dev/null 2>&1
|
||||
}
|
||||
curl_test_https_tls13()
|
||||
{
|
||||
@@ -740,7 +747,7 @@ curl_test_https_tls13()
|
||||
# $3 - subst ip
|
||||
|
||||
# force TLS1.3 mode
|
||||
curl_probe $1 $2 $HTTPS_PORT "$3" -ISs -A "$USER_AGENT" --max-time $CURL_MAX_TIME $CURL_OPT --tlsv1.3 $TLSMAX13 "https://$2" -o /dev/null 2>&1
|
||||
curl_probe $1 $2 $HTTPS_PORT "$3" $HTTPS_HEAD -Ss -A "$USER_AGENT" --max-time $CURL_MAX_TIME $CURL_OPT --tlsv1.3 $TLSMAX13 "https://$2" -o /dev/null 2>&1
|
||||
}
|
||||
|
||||
curl_test_http3()
|
||||
@@ -749,7 +756,7 @@ curl_test_http3()
|
||||
# $2 - domain name
|
||||
|
||||
# force QUIC only mode without tcp
|
||||
curl_with_dig $1 $2 $QUIC_PORT -ISs -A "$USER_AGENT" --max-time $CURL_MAX_TIME_QUIC --http3-only $CURL_OPT "https://$2" -o /dev/null 2>&1
|
||||
curl_with_dig $1 $2 $QUIC_PORT $HTTPS_HEAD -Ss -A "$USER_AGENT" --max-time $CURL_MAX_TIME_QUIC --http3-only $CURL_OPT "https://$2" -o /dev/null 2>&1
|
||||
}
|
||||
|
||||
ipt_aux_scheme()
|
||||
@@ -999,7 +1006,7 @@ check_domain_port_block()
|
||||
echo
|
||||
echo \* port block tests ipv$IPV $1:$2
|
||||
if netcat_setup; then
|
||||
ips=$(mdig_resolve_all $IPV $1)
|
||||
mdig_resolve_all $IPV ips $1
|
||||
if [ -n "$ips" ]; then
|
||||
for ip in $ips; do
|
||||
if netcat_test $ip $2; then
|
||||
@@ -1699,7 +1706,7 @@ check_dpi_ip_block()
|
||||
|
||||
echo "> testing $UNBLOCKED_DOM on it's original ip"
|
||||
if curl_test $1 $UNBLOCKED_DOM; then
|
||||
unblocked_ip=$(mdig_resolve $IPV $UNBLOCKED_DOM)
|
||||
mdig_resolve $IPV unblocked_ip $UNBLOCKED_DOM
|
||||
[ -n "$unblocked_ip" ] || {
|
||||
echo $UNBLOCKED_DOM does not resolve. tests not possible.
|
||||
return 1
|
||||
@@ -1708,7 +1715,7 @@ check_dpi_ip_block()
|
||||
echo "> testing $blocked_dom on $unblocked_ip ($UNBLOCKED_DOM)"
|
||||
curl_test $1 $blocked_dom $unblocked_ip detail
|
||||
|
||||
blocked_ips=$(mdig_resolve_all $IPV $blocked_dom)
|
||||
mdig_resolve_all $IPV blocked_ips $blocked_dom
|
||||
for blocked_ip in $blocked_ips; do
|
||||
echo "> testing $UNBLOCKED_DOM on $blocked_ip ($blocked_dom)"
|
||||
curl_test $1 $UNBLOCKED_DOM $blocked_ip detail
|
||||
@@ -1759,6 +1766,8 @@ check_domain_http_tcp()
|
||||
# $3 - encrypted test : 0 = plain, 1 - encrypted with server reply risk, 2 - encrypted without server reply risk
|
||||
# $4 - domain
|
||||
|
||||
local ips
|
||||
|
||||
# in case was interrupted before
|
||||
pktws_ipt_unprepare_tcp $2
|
||||
ws_kill
|
||||
@@ -1767,15 +1776,11 @@ check_domain_http_tcp()
|
||||
|
||||
[ "$SKIP_IPBLOCK" = 1 ] || check_dpi_ip_block $1 $4
|
||||
|
||||
[ "$SKIP_TPWS" = 1 ] || {
|
||||
echo
|
||||
tpws_check_domain_http_bypass $1 $3 $4
|
||||
}
|
||||
|
||||
[ "$SKIP_PKTWS" = 1 ] || {
|
||||
echo
|
||||
echo preparing $PKTWSD redirection
|
||||
pktws_ipt_prepare_tcp $2 "$(mdig_resolve_all $IPV $4)"
|
||||
mdig_resolve_all $IPV ips $4
|
||||
pktws_ipt_prepare_tcp $2 "$ips"
|
||||
|
||||
pktws_check_domain_http_bypass $1 $3 $4
|
||||
|
||||
@@ -1789,6 +1794,8 @@ check_domain_http_udp()
|
||||
# $2 - port
|
||||
# $3 - domain
|
||||
|
||||
local ips
|
||||
|
||||
# in case was interrupted before
|
||||
pktws_ipt_unprepare_udp $2
|
||||
ws_kill
|
||||
@@ -1798,7 +1805,8 @@ check_domain_http_udp()
|
||||
[ "$SKIP_PKTWS" = 1 ] || {
|
||||
echo
|
||||
echo preparing $PKTWSD redirection
|
||||
pktws_ipt_prepare_udp $2 "$(mdig_resolve_all $IPV $3)"
|
||||
mdig_resolve_all $IPV ips $3
|
||||
pktws_ipt_prepare_udp $2 "$ips"
|
||||
|
||||
pktws_check_domain_http3_bypass $1 $3
|
||||
|
||||
@@ -1857,6 +1865,9 @@ configure_curl_opt()
|
||||
curl_supports_tls13 && TLS13=1
|
||||
HTTP3=
|
||||
curl_supports_http3 && HTTP3=1
|
||||
|
||||
HTTPS_HEAD=-I
|
||||
[ "$CURL_HTTPS_GET" = 1 ] && HTTPS_HEAD=
|
||||
}
|
||||
|
||||
linux_ipv6_defrag_can_be_disabled()
|
||||
@@ -1917,7 +1928,7 @@ ask_params()
|
||||
curl_supports_connect_to || {
|
||||
echo "installed curl does not support --connect-to option. pls install at least curl 7.49"
|
||||
echo "current curl version:"
|
||||
$CURL --version
|
||||
"$CURL" --version
|
||||
exitp 1
|
||||
}
|
||||
|
||||
@@ -1925,7 +1936,7 @@ ask_params()
|
||||
[ -n "$DOMAINS" ] || {
|
||||
DOMAINS="$DOMAINS_DEFAULT"
|
||||
[ "$BATCH" = 1 ] || {
|
||||
echo "specify domain(s) to test. multiple domains are space separated."
|
||||
echo "specify domain(s) to test. multiple domains are space separated. URIs are supported (rutracker.org/forum/index.php)"
|
||||
printf "domain(s) (default: $DOMAINS) : "
|
||||
read dom
|
||||
[ -n "$dom" ] && DOMAINS="$dom"
|
||||
@@ -2268,7 +2279,6 @@ sigsilent()
|
||||
exit 1
|
||||
}
|
||||
|
||||
|
||||
fsleep_setup
|
||||
fix_sbin_path
|
||||
check_system
|
||||
|
||||
@@ -4,6 +4,10 @@ which()
|
||||
# 'command -v' replacement does not work exactly the same way. it outputs shell aliases if present
|
||||
# $1 - executable name
|
||||
local IFS=:
|
||||
[ "$1" != "${1#/}" ] && [ -x "$1" ] && {
|
||||
echo "$1"
|
||||
return 0
|
||||
}
|
||||
for p in $PATH; do
|
||||
[ -x "$p/$1" ] && {
|
||||
echo "$p/$1"
|
||||
@@ -93,6 +97,18 @@ trim()
|
||||
{
|
||||
awk '{gsub(/^ +| +$/,"")}1'
|
||||
}
|
||||
split_by_separator()
|
||||
{
|
||||
# $1 - string
|
||||
# $2 - separator
|
||||
# $3 - var name to get "before" part
|
||||
# $4 - var name to get "after" part
|
||||
local before="${1%%$2*}"
|
||||
local after="${1#*$2}"
|
||||
[ "$after" = "$1" ] && after=
|
||||
[ -n "$3" ] && eval $3="\$before"
|
||||
[ -n "$4" ] && eval $4="\$after"
|
||||
}
|
||||
|
||||
dir_is_not_empty()
|
||||
{
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
apply_unspecified_desync_modes()
|
||||
{
|
||||
NFQWS_OPT_DESYNC_HTTP="${NFQWS_OPT_DESYNC_HTTP:-$NFQWS_OPT_DESYNC}"
|
||||
NFQWS_OPT_DESYNC_HTTP_SUFFIX="${NFQWS_OPT_DESYNC_HTTP_SUFFIX:-$NFQWS_OPT_DESYNC_SUFFIX}"
|
||||
NFQWS_OPT_DESYNC_HTTPS="${NFQWS_OPT_DESYNC_HTTPS:-$NFQWS_OPT_DESYNC}"
|
||||
NFQWS_OPT_DESYNC_HTTPS_SUFFIX="${NFQWS_OPT_DESYNC_HTTPS_SUFFIX:-$NFQWS_OPT_DESYNC_SUFFIX}"
|
||||
NFQWS_OPT_DESYNC_HTTP6="${NFQWS_OPT_DESYNC_HTTP6:-$NFQWS_OPT_DESYNC_HTTP}"
|
||||
NFQWS_OPT_DESYNC_HTTP6_SUFFIX="${NFQWS_OPT_DESYNC_HTTP6_SUFFIX:-$NFQWS_OPT_DESYNC_HTTP_SUFFIX}"
|
||||
NFQWS_OPT_DESYNC_HTTPS6="${NFQWS_OPT_DESYNC_HTTPS6:-$NFQWS_OPT_DESYNC_HTTPS}"
|
||||
NFQWS_OPT_DESYNC_HTTPS6_SUFFIX="${NFQWS_OPT_DESYNC_HTTPS6_SUFFIX:-$NFQWS_OPT_DESYNC_HTTPS_SUFFIX}"
|
||||
NFQWS_OPT_DESYNC_QUIC6="${NFQWS_OPT_DESYNC_QUIC6:-$NFQWS_OPT_DESYNC_QUIC}"
|
||||
NFQWS_OPT_DESYNC_QUIC6_SUFFIX="${NFQWS_OPT_DESYNC_QUIC6_SUFFIX:-$NFQWS_OPT_DESYNC_QUIC_SUFFIX}"
|
||||
}
|
||||
|
||||
get_nfqws_qnums()
|
||||
{
|
||||
# $1 - var name for ipv4 http
|
||||
# $2 - var name for ipv4 https
|
||||
# $3 - var name for ipv6 http
|
||||
# $4 - var name for ipv6 https
|
||||
local _qn _qns _qn6 _qns6
|
||||
|
||||
[ "$DISABLE_IPV4" = "1" ] || {
|
||||
_qn=$QNUM
|
||||
_qns=$_qn
|
||||
[ "$NFQWS_OPT_DESYNC_HTTP $NFQWS_OPT_DESYNC_HTTP_SUFFIX" = "$NFQWS_OPT_DESYNC_HTTPS $NFQWS_OPT_DESYNC_HTTPS_SUFFIX" ] || _qns=$(($QNUM+1))
|
||||
}
|
||||
[ "$DISABLE_IPV6" = "1" ] || {
|
||||
_qn6=$(($QNUM+2))
|
||||
_qns6=$(($QNUM+3))
|
||||
[ "$DISABLE_IPV4" = "1" ] || {
|
||||
if [ "$NFQWS_OPT_DESYNC_HTTP6 $NFQWS_OPT_DESYNC_HTTP6_SUFFIX" = "$NFQWS_OPT_DESYNC_HTTP $NFQWS_OPT_DESYNC_HTTP_SUFFIX" ]; then
|
||||
_qn6=$_qn;
|
||||
elif [ "$NFQWS_OPT_DESYNC_HTTP6 $NFQWS_OPT_DESYNC_HTTP6_SUFFIX" = "$NFQWS_OPT_DESYNC_HTTPS $NFQWS_OPT_DESYNC_HTTPS_SUFFIX" ]; then
|
||||
_qn6=$_qns;
|
||||
fi
|
||||
if [ "$NFQWS_OPT_DESYNC_HTTPS6 $NFQWS_OPT_DESYNC_HTTPS6_SUFFIX" = "$NFQWS_OPT_DESYNC_HTTP $NFQWS_OPT_DESYNC_HTTP_SUFFIX" ]; then
|
||||
_qns6=$_qn;
|
||||
elif [ "$NFQWS_OPT_DESYNC_HTTPS6 $NFQWS_OPT_DESYNC_HTTPS6_SUFFIX" = "$NFQWS_OPT_DESYNC_HTTPS $NFQWS_OPT_DESYNC_HTTPS_SUFFIX" ]; then
|
||||
_qns6=$_qns;
|
||||
fi
|
||||
}
|
||||
[ "$NFQWS_OPT_DESYNC_HTTPS6 $NFQWS_OPT_DESYNC_HTTPS6_SUFFIX" = "$NFQWS_OPT_DESYNC_HTTP6 $NFQWS_OPT_DESYNC_HTTP6_SUFFIX" ] && _qns6=$_qn6;
|
||||
}
|
||||
if [ "$MODE_HTTP" = 1 ]; then
|
||||
eval $1=$_qn
|
||||
eval $3=$_qn6
|
||||
else
|
||||
eval $1=
|
||||
eval $3=
|
||||
fi
|
||||
if [ "$MODE_HTTPS" = 1 ]; then
|
||||
eval $2=$_qns
|
||||
eval $4=$_qns6
|
||||
else
|
||||
eval $2=
|
||||
eval $4=
|
||||
fi
|
||||
}
|
||||
|
||||
get_nfqws_qnums_quic()
|
||||
{
|
||||
# $1 - var name for ipv4 quic
|
||||
# $2 - var name for ipv6 quic
|
||||
local _qn _qn6
|
||||
|
||||
[ "$DISABLE_IPV4" = "1" ] || {
|
||||
_qn=$(($QNUM+10))
|
||||
}
|
||||
[ "$DISABLE_IPV6" = "1" ] || {
|
||||
_qn6=$(($QNUM+11))
|
||||
[ "$DISABLE_IPV4" = "1" ] || {
|
||||
if [ "$NFQWS_OPT_DESYNC_QUIC $NFQWS_OPT_DESYNC_QUIC_SUFFIX" = "$NFQWS_OPT_DESYNC_QUIC6 $NFQWS_OPT_DESYNC_QUIC6_SUFFIX" ]; then
|
||||
_qn6=$_qn;
|
||||
fi
|
||||
}
|
||||
}
|
||||
if [ "$MODE_QUIC" = 1 ]; then
|
||||
eval $1=$_qn
|
||||
eval $2=$_qn6
|
||||
else
|
||||
eval $1=
|
||||
eval $2=
|
||||
fi
|
||||
}
|
||||
@@ -561,3 +561,23 @@ v72.1
|
||||
nfqws: --ip-id=seq|seqgroup|rnd|zero
|
||||
blockcheck: MIN_AUTOTTL_DELTA,MAX_AUTOTTL_DELTA
|
||||
init.d: 50-quic4all custom
|
||||
|
||||
72.2
|
||||
|
||||
nfqws: --wssize-forced-cutoff
|
||||
nfqws: --orig-tcp-flags, --dup-tcp-flags, --dpi-desync-tcp-flags
|
||||
nfqws: --dup-ip-id
|
||||
|
||||
73.3
|
||||
|
||||
blockcheck: support URIs
|
||||
blockcheck: CURL_HTTPS_GET=1 suppresses -I curl option for https (HEAD -> GET)
|
||||
|
||||
73.4
|
||||
|
||||
blockcheck: fix broken dns cache
|
||||
|
||||
73.5
|
||||
|
||||
nfqws: fix broken l7proto profile rediscovery
|
||||
nfqws: backport from nfqws2 nl80211 ssid discovery fix for newer kernels
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# zapret v72.1
|
||||
|
||||
# SCAMMER WARNING
|
||||
|
||||
This software is free and open source under [MIT license](./LICENSE.txt).
|
||||
@@ -153,6 +151,7 @@ nfqws takes the following parameters:
|
||||
--wsize=<window_size>[:<scale_factor>] ; set window size. 0 = do not modify. OBSOLETE !
|
||||
--wssize=<window_size>[:<scale_factor>] ; set window size for server. 0 = do not modify. default scale_factor = 0.
|
||||
--wssize-cutoff=[n|d|s]N ; apply server wsize only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N
|
||||
--wssize-forced-cutoff=0|1 ; 1(default)=auto cutoff wssize on known protocol
|
||||
--ctrack-timeouts=S:E:F[:U] ; internal conntrack timeouts for TCP SYN, ESTABLISHED, FIN stages, UDP timeout. default 60:300:60:60
|
||||
--ctrack-disable=[0|1] ; 1 or no argument disables conntrack
|
||||
--ipcache-lifetime=<int> ; time in seconds to keep cached hop count and domain name (default 7200). 0 = no expiration
|
||||
@@ -167,6 +166,8 @@ nfqws takes the following parameters:
|
||||
--orig-ttl6=<int> ; set ipv6 hop limit for original packets. by default ttl value is used
|
||||
--orig-autottl=[<delta>[:<min>[-<max>]]|-] ; auto ttl mode for both ipv4 and ipv6. default: +5:3-64. "0:0-0" or "-" disables autottl.
|
||||
--orig-autottl6=[<delta>[:<min>[-<max>]]|-] ; overrides --orig-autottl for ipv6 only
|
||||
--orig-tcp-flags-set=<int|0xHEX|flaglist> ; set these tcp flags (flags |= value). value can be int, hex or comma separated list : FIN,SYN,RST,PSH,ACK,URG,ECE,CWR,AE,R1,R2,R3
|
||||
--orig-tcp-flags-unset=<int|0xHEX|flaglist> ; unset these tcp flags (flags &= ~value)
|
||||
--orig-mod-start=[n|d|s]N ; apply orig TTL mod to packet numbers (n, default), data packet numbers (d), relative sequence (s) greater or equal than N
|
||||
--orig-mod-cutoff=[n|d|s]N ; apply orig TTL mod to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N
|
||||
--dup=<int> ; duplicate original packets. send N dups before original.
|
||||
@@ -175,10 +176,13 @@ nfqws takes the following parameters:
|
||||
--dup-ttl6=<int> ; set ipv6 hop limit for dups. by default ttl value is used
|
||||
--dup-autottl=[<delta>[:<min>[-<max>]]|-] ; auto ttl mode for both ipv4 and ipv6. default: -1:3-64. "0:0-0" or "-" disables autottl.
|
||||
--dup-autottl6=[<delta>[:<min>[-<max>]]|-] ; overrides --dup-autottl for ipv6 only
|
||||
--dup-tcp-flags-set=<int|0xHEX|flaglist> ; set these tcp flags (flags |= value). value can be int, hex or comma separated list : FIN,SYN,RST,PSH,ACK,URG,ECE,CWR,AE,R1,R2,R3
|
||||
--dup-tcp-flags-unset=<int|0xHEX|flaglist> ; unset these tcp flags (flags &= ~value)
|
||||
--dup-fooling=<mode>[,<mode>] ; can use multiple comma separated values. modes : none md5sig badseq badsum datanoack hopbyhop hopbyhop2
|
||||
--dup-ts-increment=<int|0xHEX> ; ts fooling TSval signed increment for dup. default -600000
|
||||
--dup-badseq-increment=<int|0xHEX> ; badseq fooling seq signed increment for dup. default -10000
|
||||
--dup-badack-increment=<int|0xHEX> ; badseq fooling ackseq signed increment for dup. default -66000
|
||||
--dup-ip-id=same|zero|seq|rnd ; ipv4 ip_id mode for dupped packets
|
||||
--dup-start=[n|d|s]N ; apply dup to packet numbers (n, default), data packet numbers (d), relative sequence (s) greater or equal than N
|
||||
--dup-cutoff=[n|d|s]N ; apply dup to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N
|
||||
--ip-id=zero|seq|seqgroup|rnd ; ipv4 ip_id assignment scheme
|
||||
@@ -188,6 +192,8 @@ nfqws takes the following parameters:
|
||||
--dpi-desync-ttl6=<int> ; set ipv6 hop limit for desync packet. by default ttl value is used.
|
||||
--dpi-desync-autottl=[<delta>[:<min>[-<max>]]|-] ; auto ttl mode for both ipv4 and ipv6. default: -1:3-20. "0:0-0" or "-" disables autottl.
|
||||
--dpi-desync-autottl6=[<delta>[:<min>[-<max>]]|-] ; overrides --dpi-desync-autottl for ipv6 only
|
||||
--dpi-desync-tcp-flags-set=<int|0xHEX|flaglist> ; set these tcp flags (flags |= value). value can be int, hex or comma separated list : FIN,SYN,RST,PSH,ACK,URG,ECE,CWR,AE,R1,R2,R3
|
||||
--dpi-desync-tcp-flags-unset=<int|0xHEX|flaglist> ; unset these tcp flags (flags &= ~value)
|
||||
--dpi-desync-fooling=<mode>[,<mode>] ; can use multiple comma separated values. modes : none md5sig ts badseq badsum datanoack hopbyhop hopbyhop2
|
||||
--dpi-desync-repeats=<N> ; send every desync packet N times
|
||||
--dpi-desync-skip-nosni=0|1 ; 1(default)=do not act on ClientHello without SNI (ESNI ?)
|
||||
@@ -298,6 +304,10 @@ Fakes are separate generated by nfqws packets carrying false information for DPI
|
||||
* **datanoack** sends tcp fakes without ACK flag. Servers do not accept this but DPI may accept.
|
||||
This mode may break NAT and may not work with iptables if masquerade is used, even from the router itself.
|
||||
Works with nftables properly. Likely requires external IP address (some ISPs pass these packets through their NAT).
|
||||
* Manipulate **tcp flags** with `--dpi-desync-tcp-flags-set` and `--dpi-desync-tcp-flags-unset`.
|
||||
Invalid tcp flags combination may cause server to drop the packet but DPI can accept it.
|
||||
For example, set SYN in fakes. This may not work with all servers.
|
||||
`datanoack` can be replaced to `--dpi-desync-tcp-flags-unset=ACK`.
|
||||
* **ts** adds to TSval ts increment value (-600000 by default). Servers discard packets with TSval in some range.
|
||||
Practical tests suggest increment between -100 and -0x80000000.
|
||||
Timestamps are generated by client OS. In linux timestamps are enabled by default. In windows by default timestamps are disabled.
|
||||
@@ -513,7 +523,7 @@ There are DPIs that analyze responses from the server, particularly the certific
|
||||
In the disorder variant, a selective acknowledgement (SACK) usually arrives first, then a full ACK.
|
||||
If, instead of ACK or SACK, there is an RST packet with minimal delay, DPI cuts you off at the request stage.
|
||||
If the RST is after a full ACK after a delay of about ping to the server, then probably DPI acts on the server response. The DPI may be satisfied with good ClientHello and stop monitoring the TCP session without checking ServerHello. Then you were lucky. 'fake' option could work.
|
||||
If it does not stop monitoring and persistently checks the ServerHello, --wssize parameter may help (see [CONNTRACK](#conntrack)).
|
||||
If it does not stop monitoring and persistently checks the ServerHello, `--wssize` parameter may help (see [CONNTRACK](#conntrack)).
|
||||
Otherwise it is hardly possible to overcome this without the help of the server.
|
||||
The best solution is to enable TLS 1.3 support on the server. TLS 1.3 sends the server certificate in encrypted form.
|
||||
This is recommendation to all admins of blocked sites. Enable TLS 1.3. You will give more opportunities to overcome DPI.
|
||||
@@ -576,7 +586,7 @@ That's why conntrack is required to know when to stop applying low window size.
|
||||
If you do not stop and set the low wssize all the time, the speed will drop catastrophically.
|
||||
Linux can overcome this using connbytes filter but other OS may not include similar filter.
|
||||
|
||||
In http(s) case wssize stops after the first http request or TLS ClientHello.
|
||||
In http(s) case wssize stops after the first http request or TLS ClientHello unless `--wssize-forced-cutoff=0` is specified.
|
||||
|
||||
If you deal with a non-http(s) protocol you need `--wssize-cutoff`. It sets the threshold where wssize stops.
|
||||
|
||||
@@ -584,6 +594,7 @@ Threshold can be prefixed with 'n' (packet number starting from 1), 'd' (data pa
|
||||
's' (relative sequence number - sent by client bytes + 1).
|
||||
|
||||
If a http request or TLS ClientHello packet is detected wssize stops immediately ignoring wssize-cutoff option.
|
||||
This action is called "forced wssize cutoff" and can disabled using `--wssize-forced-cutoff=0`.
|
||||
|
||||
If your protocol is prone to long inactivity, you should increase ESTABLISHED phase timeout using `--ctrack-timeouts`.
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# zapret v72.1
|
||||
|
||||
# ВНИМАНИЕ, остерегайтесь мошенников
|
||||
|
||||
zapret является свободным и open source.
|
||||
@@ -184,11 +182,14 @@ dvtws, собираемый из тех же исходников (см. [док
|
||||
--wsize=<winsize>[:<scale_factor>] ; менять tcp window size на указанный размер в SYN,ACK. если не задан scale_factor, то он не меняется (устарело !)
|
||||
--wssize=<winsize>[:<scale_factor>] ; менять tcp window size на указанный размер в исходящих пакетах. scale_factor по умолчанию 0. (см. conntrack !)
|
||||
--wssize-cutoff=[n|d|s]N ; изменять server window size в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N
|
||||
--wssize-forced-cutoff=0|1 ; 1(default)=автоматически отключать wssize в случае обнаружения известного протокола
|
||||
--synack-split=[syn|synack|acksyn] ; выполнить tcp split handshake. вместо SYN,ACK отсылать только SYN, SYN+ACK или ACK+SYN
|
||||
--orig-ttl=<int> ; модифицировать TTL оригинального пакета
|
||||
--orig-ttl6=<int> ; модифицировать ipv6 hop limit оригинальных пакетов. если не указано, используется значение --orig-ttl
|
||||
--orig-autottl=[<delta>[:<min>[-<max>]]|-] ; режим auto ttl для ipv4 и ipv6. по умолчанию: +5:3-64. "0:0-0" или "-" отключает функцию
|
||||
--orig-autottl6=[<delta>[:<min>[-<max>]]|-] ; переопределение предыдущего параметра для ipv6
|
||||
--orig-tcp-flags-set=<int|0xHEX|flaglist> ; устанавливать указанные tcp флаги (flags |= value). число , либо список через запятую : FIN,SYN,RST,PSH,ACK,URG,ECE,CWR,AE,R1,R2,R3
|
||||
--orig-tcp-flags-unset=<int|0xHEX|flaglist> ; удалять указанные tcp флаги (flags &= ~value)
|
||||
--orig-mod-start=[n|d|s]N ; применять orig-mod только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру больше или равно N
|
||||
--orig-mod-cutoff=[n|d|s]N ; применять orig-mod только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N
|
||||
--dup=<int> ; высылать N дубликатов до оригинала
|
||||
@@ -197,10 +198,13 @@ dvtws, собираемый из тех же исходников (см. [док
|
||||
--dup-ttl6=<int> ; модифицировать ipv6 hop limit дубликатов. если не указано, используется значение --dup-ttl
|
||||
--dup-autottl=[<delta>[:<min>[-<max>]]|-] ; режим auto ttl для ipv4 и ipv6. по умолчанию: +1:3-64. "0:0-0" или "-" отключает функцию
|
||||
--dup-autottl6=[<delta>[:<min>[-<max>]]|-] ; переопределение предыдущего параметра для ipv6
|
||||
--dup-tcp-flags-set=<int|0xHEX|flaglist> ; устанавливать указанные tcp флаги (flags |= value). число , либо список через запятую : FIN,SYN,RST,PSH,ACK,URG,ECE,CWR,AE,R1,R2,R3
|
||||
--dup-tcp-flags-unset=<int|0xHEX|flaglist> ; удалять указанные tcp флаги (flags &= ~value)
|
||||
--dup-fooling=<fooling> ; дополнительные методики как сделать, чтобы дубликат не дошел до сервера. none md5sig badseq badsum datanoack ts hopbyhop hopbyhop2
|
||||
--dup-ts-increment=<int|0xHEX> ; инкремент TSval для ts. по умолчанию -600000
|
||||
--dup-badseq-increment=<int|0xHEX> ; инкремент sequence number для badseq. по умолчанию -10000
|
||||
--dup-badack-increment=<int|0xHEX> ; инкремент ack sequence number для badseq. по умолчанию -66000
|
||||
--dup-ip-id=same|zero|seq|rnd ; режим назначения ip_id для пакетов dup
|
||||
--dup-start=[n|d|s]N ; применять dup только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру больше или равно N
|
||||
--dup-cutoff=[n|d|s]N ; применять dup только в исходящих пакетах (n), пакетах данных (d), относительных sequence (s) по номеру меньше N
|
||||
--hostcase ; менять регистр заголовка "Host:" по умолчанию на "host:".
|
||||
@@ -215,6 +219,8 @@ dvtws, собираемый из тех же исходников (см. [док
|
||||
--dpi-desync-ttl6=<int> ; установить ipv6 hop limit для десинхронизирующих пакетов. если не указано, используется значение --dpi-desync-ttl
|
||||
--dpi-desync-autottl=[<delta>[:<min>[-<max>]]|-] ; режим auto ttl для ipv4 и ipv6. по умолчанию: 1:3-20. "0:0-0" или "-" отключает функцию
|
||||
--dpi-desync-autottl6=[<delta>[:<min>[-<max>]]|-] ; переопределение предыдущего параметра для ipv6
|
||||
--dpi-desync-tcp-flags-set=<int|0xHEX|flaglist> ; устанавливать указанные tcp флаги (flags |= value). число , либо список через запятую : FIN,SYN,RST,PSH,ACK,URG,ECE,CWR,AE,R1,R2,R3
|
||||
--dpi-desync-tcp-flags-unset=<int|0xHEX|flaglist> ; удалять указанные tcp флаги (flags &= ~value)
|
||||
--dpi-desync-fooling=<fooling> ; дополнительные методики как сделать, чтобы фейковый пакет не дошел до сервера. none md5sig badseq badsum datanoack ts hopbyhop hopbyhop2
|
||||
--dpi-desync-repeats=<N> ; посылать каждый генерируемый в nfqws пакет N раз (не влияет на остальные пакеты)
|
||||
--dpi-desync-skip-nosni=0|1 ; 1(default)=не применять dpi desync для запросов без hostname в SNI, в частности для ESNI
|
||||
@@ -355,6 +361,10 @@ hex строка начинается с "0x". Имя файла можно пи
|
||||
выяснено, что многие провайдерские NAT не отбрасывают эти пакеты, потому работает даже с внутренним провайдерским IP.
|
||||
Но linux NAT оно не пройдет, так что за домашним роутером эта техника скорее всего не сработает, но может сработать с него.
|
||||
Может сработать и через роутер, если подключение по проводу, и на роутере включено аппаратное ускорение.
|
||||
* Манипуляция tcp флагами с помощью `--dpi-desync-tcp-flags-set` и `--dpi-desync-tcp-flags-unset`. Можно сделать инвалидное
|
||||
сочетание флагов, которое сервер не примет, а DPI - примет. Например, установить SYN в фейках. Но это может работать не на всех серверах.
|
||||
`datanoack` может быть заменен `--dpi-desync-tcp-flags-unset=ACK`.
|
||||
Пакеты с инвалидными флагами могут отбрасываться, проходя через NAT.
|
||||
* `ts` прибавляет к значению TSval таймштампа tcp значение ts increment (по умолчанию -600000). Сервера отбрасывают пакеты
|
||||
с TSval в определенных пределах. По практическим тестам инкремент должен быть где-то от -100 до -0x80000000.
|
||||
timestamps генерирует клиентская ОС. В linux таймштампы включены по умолчанию, в windows выключены по умолчанию.
|
||||
@@ -469,7 +479,7 @@ hex строка начинается с "0x". Имя файла можно пи
|
||||
`altorder=1` шлет фрагменты в таком порядке, чтобы при последовательной сборке сегментов на DPI он получил полностью собранный оригинал запроса с подмененным хостом.
|
||||
Реальный хост идет отдельным сегментом уже после. То есть в этом варианте применяется разновидность disorder. Сервер принимает фрагменты с нарушенным порядком sequence.
|
||||
|
||||
Опционально можно разрезать оригинальный фейк. Например, `--dpi-desync-hostfakesplit-midhost=midsld`. Позиция нарезки должна попадать внутрь хоста.
|
||||
Опционально можно разрезать оригинальный хост. Например, `--dpi-desync-hostfakesplit-midhost=midsld`. Позиция нарезки должна попадать внутрь хоста.
|
||||
Многопакетные запросы поддерживаются только, если исходная нарезка пакетов не включает позиции имени хоста. В последнем случае дурение отменяется.
|
||||
|
||||
Вариант `fakedsplit` имеет несколько альтернативных порядков нарезки - от 0 до 3. Режим задается в параметре `--dpi-desync-fakedsplit-mod=altorder=N`.
|
||||
@@ -649,7 +659,7 @@ ipcache представляет собой структуру в памяти
|
||||
DPI может отстать от потока, если ClientHello его удовлетворил и не проверять ServerHello.
|
||||
Тогда вам повезло. Вариант fake может сработать.
|
||||
Если же он не отстает и упорно проверяет ServerHello, то можно попробовать заставить сервер высылать ServerHello частями
|
||||
через параметр --wssize (см. conntrack).
|
||||
через параметр `--wssize` (см. conntrack).
|
||||
Если и это не помогает, то сделать с этим что-либо вряд ли возможно без помощи со стороны сервера.
|
||||
Лучшее решение - включить на сервере поддержку TLS 1.3. В нем сертификат сервера передается в зашифрованном виде.
|
||||
Это рекомендация ко всем админам блокируемых сайтов. Включайте TLS 1.3. Так вы дадите больше возможностей преодолеть DPI.
|
||||
@@ -702,7 +712,8 @@ conntrack - простенький, он не писался с учетом в
|
||||
Если вы имеете дело с не http(s), то вам потребуется параметр `--wssize-cutoff`. Он устанавливает предел, с которого действие
|
||||
wssize прекращается. Префикс d перед номером означает учитывать только пакеты с data payload, префикс s - relative sequence number,
|
||||
проще говоря количество переданных клиентом байтов + 1.
|
||||
Если проскочит пакет с http request или TLS ClientHello, действие wssize прекращается сразу же, не дожидаясь wssize-cutoff.
|
||||
Если проскочит пакет с http request или TLS ClientHello, действие wssize прекращается сразу же, не дожидаясь wssize-cutoff,
|
||||
если не указан параметр `--wssize-forced-cutoff=0`.
|
||||
Если ваш протокол склонен к долгому бездействию, следует увеличить таймаут фазы ESTABLISHED через параметр `--ctrack-timeouts`.
|
||||
Таймаут по умолчанию низкий - всего 5 минут.
|
||||
Не забывайте, что nfqws кормится приходящими на него пакетами. Если вы ограничили поступление пакетов через connbytes,
|
||||
@@ -888,13 +899,6 @@ L7 протокол становится известен обычно посл
|
||||
При выборе профиля имеет значение куда идет конкретный обрабатываемый пакет. На какой интерфейс. Или с какого интерфейса пакет пришел, если он считается входящим.
|
||||
Поэтому даже если у вас часть трафика идет на одну сеть, часть на другую, а часть вообще не идет по wifi, то все это можно настроить.
|
||||
|
||||
Информация о подключенных сетях берется способом, используемым командой `iw dev <ifname> info` (nl80211).
|
||||
К сожалению, на ядрах с 5.19 до самых последних (6.14 не работает) этот способ сломан.
|
||||
В этом случае используется способ iwgetid (wireless extensions).
|
||||
wireless extensions считаются deprecated и на новых ядрах реализованы как прослойка совместимости.
|
||||
Некоторые ядра могут быть собраны без wireless extensions.
|
||||
Перед использованием `--filter-ssid` удостоверьтесь, что любая из этих команд возвращает SSID.
|
||||
|
||||
Сканируются все wifi интерфейсы, составляется список interface->SSID. Он обновляется по мере поступления
|
||||
пакетов, но не чаще 1 раза в секунду.
|
||||
|
||||
@@ -1652,7 +1656,7 @@ LISTS_RELOAD=- отключает перезагрузку листов.
|
||||
|
||||
В системе запуска это обыграно следующим образом.
|
||||
Присутствуют 2 include списка :
|
||||
`ipset/zapret-hosts-users.txt.gz` или `ipset/zapret-hosts-users.txt`,
|
||||
`ipset/zapret-hosts-user.txt.gz` или `ipset/zapret-hosts-user.txt`,
|
||||
`ipset/zapret-hosts.txt.gz` или `ipset/zapret-hosts.txt`
|
||||
и 1 exclude список
|
||||
`ipset/zapret-hosts-user-exclude.txt.gz` или `ipset/zapret-hosts-user-exclude.txt`
|
||||
@@ -1803,6 +1807,7 @@ CURL_MAX_TIME_QUIC - время таймаута curl для quic. если не
|
||||
CURL_MAX_TIME_DOH - время таймаута curl для DoH серверов
|
||||
CURL_CMD=1 - показывать команды curl
|
||||
CURL_OPT - дополнительные параметры curl. `-k` - игнор сертификатов. `-v` - подробный вывод протокола
|
||||
CURL_HTTPS_GET=1 - использовать метод GET вместо HEAD для https
|
||||
DOMAINS - список тестируемых доменов через пробел
|
||||
IPVS=4|6|46 - тестируемые версии ip протокола
|
||||
ENABLE_HTTP=0|1 - включить тест plain http
|
||||
|
||||
@@ -7,7 +7,7 @@ tpws is static binary. It doesn't need a distribution.
|
||||
|
||||
Install `WSL` : `dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all`
|
||||
|
||||
Copy `binaries/x86_64/tpws_wsl.tgz` to the target system.
|
||||
From release copy `binaries/linux-x86_64/tpws_wsl.tgz` to the target system.
|
||||
Run : `wsl --import tpws "%USERPROFILE%\tpws" tpws_wsl.tgz`
|
||||
|
||||
Run tpws : `wsl -d tpws --exec /tpws --uid=1 --no-resolve --socks --bind-addr=127.0.0.1 --port=1080 <fooling_options>`
|
||||
@@ -16,7 +16,7 @@ Configure socks as `127.0.0.1:1080` in a browser or another program.
|
||||
|
||||
Cleanup : `wsl --unregister tpws`
|
||||
|
||||
Tested in windows 10 build 19041 (20.04).
|
||||
Tested in windows 10 build 19041 (20.04) with WSL1.
|
||||
|
||||
`--oob` , `--mss` and `--disorder` do not work.
|
||||
RST detection in autohostlist scheme may not work.
|
||||
|
||||
@@ -12,7 +12,7 @@ tpws в режиме socks можно запускать под более-ме
|
||||
Установить WSL :
|
||||
`dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all`
|
||||
|
||||
Скопировать на целевую систему `binaries/x86_64/tpws_wsl.tgz`.
|
||||
Из релиза скопировать на целевую систему `binaries/linux-x86_64/tpws_wsl.tgz`.
|
||||
|
||||
Выполнить :
|
||||
`wsl --import tpws "%USERPROFILE%\tpws" tpws_wsl.tgz`
|
||||
@@ -24,8 +24,12 @@ tpws в режиме socks можно запускать под более-ме
|
||||
|
||||
Удаление : `wsl --unregister tpws`
|
||||
|
||||
|
||||
> [!NOTE]
|
||||
> Проверено на windows 10 build 19041 (20.04).
|
||||
> Проверено на windows 10 build 19041 (20.04) под WSL1. На WSL2 эти команды могут не сработать.
|
||||
Если у вас есть WSL2, значит у вас есть работающая виртуалка с linux.
|
||||
Если вы умеете с ней обращаться, tpws на ней запустить возможно без всяких проблем.
|
||||
|
||||
|
||||
Возможные проблемы:
|
||||
- Не работают функции `--oob` и `--mss` из-за ограничений реализации WSL.
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
172.16.0.0/12
|
||||
192.168.0.0/16
|
||||
169.254.0.0/16
|
||||
100.64.0.0/10
|
||||
::1
|
||||
fc00::/7
|
||||
fe80::/10
|
||||
|
||||
@@ -5,9 +5,11 @@ int aes_gcm_crypt(int mode, uint8_t *output, const uint8_t *input, size_t input_
|
||||
int ret = 0;
|
||||
gcm_context ctx;
|
||||
|
||||
gcm_setkey(&ctx, key, (const uint)key_len);
|
||||
ret = gcm_crypt_and_tag(&ctx, mode, iv, iv_len, adata, adata_len, input, output, input_length, atag, atag_len);
|
||||
gcm_zero_ctx(&ctx);
|
||||
if (!(ret = gcm_setkey(&ctx, key, (const uint)key_len)))
|
||||
{
|
||||
ret = gcm_crypt_and_tag(&ctx, mode, iv, iv_len, adata, adata_len, input, output, input_length, atag, atag_len);
|
||||
gcm_zero_ctx(&ctx);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -367,7 +367,7 @@ int aes_setkey(aes_context *ctx, // AES context provided by our caller
|
||||
}
|
||||
|
||||
#if AES_DECRYPTION
|
||||
if (mode == DECRYPT) // expand our key for encryption or decryption
|
||||
if (mode == AES_DECRYPT) // expand our key for encryption or decryption
|
||||
return(aes_set_decryption_key(ctx, key, keysize));
|
||||
else /* ENCRYPT */
|
||||
#endif /* AES_DECRYPTION */
|
||||
@@ -399,7 +399,7 @@ int aes_cipher(aes_context *ctx,
|
||||
|
||||
#if AES_DECRYPTION // whether AES decryption is supported
|
||||
|
||||
if (ctx->mode == DECRYPT)
|
||||
if (ctx->mode == AES_DECRYPT)
|
||||
{
|
||||
for (i = (ctx->rounds >> 1) - 1; i > 0; i--)
|
||||
{
|
||||
|
||||
@@ -246,7 +246,7 @@ int gcm_setkey(gcm_context *ctx, // pointer to caller-provided gcm context
|
||||
*
|
||||
******************************************************************************/
|
||||
int gcm_start(gcm_context *ctx, // pointer to user-provided GCM context
|
||||
int mode, // GCM_ENCRYPT or GCM_DECRYPT
|
||||
int mode, // AES_ENCRYPT or AES_DECRYPT
|
||||
const uchar *iv, // pointer to initialization vector
|
||||
size_t iv_len, // IV length in bytes (should == 12)
|
||||
const uchar *add, // ptr to additional AEAD data (NULL if none)
|
||||
@@ -288,6 +288,7 @@ int gcm_start(gcm_context *ctx, // pointer to user-provided GCM context
|
||||
for (i = 0; i < 16; i++) ctx->y[i] ^= work_buf[i];
|
||||
gcm_mult(ctx, ctx->y, ctx->y);
|
||||
}
|
||||
|
||||
if ((ret = aes_cipher(&ctx->aes_ctx, ctx->y, ctx->base_ectr)) != 0)
|
||||
return(ret);
|
||||
|
||||
@@ -427,7 +428,7 @@ int gcm_finish(gcm_context *ctx, // pointer to user-provided GCM context
|
||||
******************************************************************************/
|
||||
int gcm_crypt_and_tag(
|
||||
gcm_context *ctx, // gcm context with key already setup
|
||||
int mode, // cipher direction: GCM_ENCRYPT or GCM_DECRYPT
|
||||
int mode, // cipher direction: AES_ENCRYPT or AES_DECRYPT
|
||||
const uchar *iv, // pointer to the 12-byte initialization vector
|
||||
size_t iv_len, // byte length if the IV. should always be 12
|
||||
const uchar *add, // pointer to the non-ciphered additional data
|
||||
|
||||
185
nfq/darkmagic.c
185
nfq/darkmagic.c
@@ -111,7 +111,7 @@ bool tcp_has_sack(struct tcphdr *tcp)
|
||||
|
||||
// n prefix (nsport, nwsize) means network byte order
|
||||
static void fill_tcphdr(
|
||||
struct tcphdr *tcp, uint32_t fooling, uint8_t tcp_flags,
|
||||
struct tcphdr *tcp, uint32_t fooling, uint16_t tcp_flags,
|
||||
bool sack,
|
||||
uint16_t nmss,
|
||||
uint32_t nseq, uint32_t nack_seq,
|
||||
@@ -142,7 +142,8 @@ static void fill_tcphdr(
|
||||
tcp->th_off = 5;
|
||||
if ((fooling & FOOL_DATANOACK) && !(tcp_flags & (TH_SYN|TH_RST)) && data_len)
|
||||
tcp_flags &= ~TH_ACK;
|
||||
*((uint8_t*)tcp+13)= tcp_flags;
|
||||
tcp->th_flags = (uint8_t)tcp_flags;
|
||||
tcp->th_x2 = (tcp_flags>>8) & 0xF;
|
||||
tcp->th_win = nwsize;
|
||||
if (nmss)
|
||||
{
|
||||
@@ -231,7 +232,7 @@ static void fill_ip6hdr(struct ip6_hdr *ip6, const struct in6_addr *src, const s
|
||||
|
||||
bool prepare_tcp_segment4(
|
||||
const struct sockaddr_in *src, const struct sockaddr_in *dst,
|
||||
uint8_t tcp_flags,
|
||||
uint16_t tcp_flags,
|
||||
bool sack,
|
||||
uint16_t nmss,
|
||||
uint32_t nseq, uint32_t nack_seq,
|
||||
@@ -271,7 +272,7 @@ bool prepare_tcp_segment4(
|
||||
|
||||
bool prepare_tcp_segment6(
|
||||
const struct sockaddr_in6 *src, const struct sockaddr_in6 *dst,
|
||||
uint8_t tcp_flags,
|
||||
uint16_t tcp_flags,
|
||||
bool sack,
|
||||
uint16_t nmss,
|
||||
uint32_t nseq, uint32_t nack_seq,
|
||||
@@ -358,7 +359,7 @@ bool prepare_tcp_segment6(
|
||||
|
||||
bool prepare_tcp_segment(
|
||||
const struct sockaddr *src, const struct sockaddr *dst,
|
||||
uint8_t tcp_flags,
|
||||
uint16_t tcp_flags,
|
||||
bool sack,
|
||||
uint16_t nmss,
|
||||
uint32_t nseq, uint32_t nack_seq,
|
||||
@@ -681,6 +682,20 @@ bool rewrite_ttl(struct ip *ip, struct ip6_hdr *ip6, uint8_t ttl)
|
||||
return false;
|
||||
}
|
||||
|
||||
void apply_tcp_flags(struct tcphdr *tcp, uint16_t fl)
|
||||
{
|
||||
if (tcp)
|
||||
{
|
||||
tcp->th_flags = (uint8_t)fl;
|
||||
tcp->th_x2 = (fl>>8) & 0xF;
|
||||
}
|
||||
}
|
||||
uint16_t get_tcp_flags(const struct tcphdr *tcp)
|
||||
{
|
||||
return tcp->th_flags | (tcp->th_x2<<8);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void extract_ports(const struct tcphdr *tcphdr, const struct udphdr *udphdr, uint8_t *proto, uint16_t *sport, uint16_t *dport)
|
||||
{
|
||||
@@ -921,7 +936,6 @@ void proto_skip_ipv6(uint8_t **data, size_t *len, uint8_t *proto_type, uint8_t *
|
||||
{
|
||||
case 0: // Hop-by-Hop Options
|
||||
case 43: // routing
|
||||
case 51: // authentication
|
||||
case 60: // Destination Options
|
||||
case 135: // mobility
|
||||
case 139: // Host Identity Protocol Version v2
|
||||
@@ -932,6 +946,11 @@ void proto_skip_ipv6(uint8_t **data, size_t *len, uint8_t *proto_type, uint8_t *
|
||||
case 44: // fragment. length fixed to 8, hdrlen field defined as reserved
|
||||
hdrlen = 8;
|
||||
break;
|
||||
case 51: // authentication
|
||||
// special case. length in ah header is in 32-bit words minus 2
|
||||
if (*len < 2) return; // error
|
||||
hdrlen = 8 + ((*data)[1] << 2);
|
||||
break;
|
||||
case 59: // no next header
|
||||
return; // error
|
||||
default:
|
||||
@@ -1851,9 +1870,9 @@ bool rawsend_queue(struct rawpacket_tailhead *q)
|
||||
|
||||
// linux-specific wlan retrieval implementation
|
||||
|
||||
typedef void netlink_prepare_nlh_cb_t(struct nlmsghdr *nlh);
|
||||
typedef void netlink_prepare_nlh_cb_t(struct nlmsghdr *nlh, void *param);
|
||||
|
||||
static bool netlink_genl_simple_transact(struct mnl_socket* nl, uint16_t type, uint16_t flags, uint8_t cmd, uint8_t version, netlink_prepare_nlh_cb_t cb_prepare_nlh, mnl_cb_t cb_data, void *data)
|
||||
static bool netlink_genl_simple_transact(struct mnl_socket* nl, uint16_t type, uint16_t flags, uint8_t cmd, uint8_t version, netlink_prepare_nlh_cb_t cb_prepare_nlh, void *prepare_data, mnl_cb_t cb_data, void *data)
|
||||
{
|
||||
char buf[MNL_SOCKET_BUFFER_SIZE];
|
||||
struct nlmsghdr *nlh;
|
||||
@@ -1868,7 +1887,7 @@ static bool netlink_genl_simple_transact(struct mnl_socket* nl, uint16_t type, u
|
||||
genl->cmd = cmd;
|
||||
genl->version = version;
|
||||
|
||||
if (cb_prepare_nlh) cb_prepare_nlh(nlh);
|
||||
if (cb_prepare_nlh) cb_prepare_nlh(nlh, prepare_data);
|
||||
|
||||
if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0)
|
||||
{
|
||||
@@ -1892,7 +1911,7 @@ static bool netlink_genl_simple_transact(struct mnl_socket* nl, uint16_t type, u
|
||||
return false;
|
||||
}
|
||||
|
||||
static void wlan_id_prepare(struct nlmsghdr *nlh)
|
||||
static void wlan_id_prepare(struct nlmsghdr *nlh, void *param)
|
||||
{
|
||||
mnl_attr_put_strz(nlh, CTRL_ATTR_FAMILY_NAME, "nl80211");
|
||||
}
|
||||
@@ -1924,7 +1943,7 @@ static int wlan_id_cb(const struct nlmsghdr *nlh, void *data)
|
||||
static uint16_t wlan_get_family_id(struct mnl_socket* nl)
|
||||
{
|
||||
uint16_t id;
|
||||
return netlink_genl_simple_transact(nl, GENL_ID_CTRL, NLM_F_REQUEST | NLM_F_ACK, CTRL_CMD_GETFAMILY, 1, wlan_id_prepare, wlan_id_cb, &id) ? id : 0;
|
||||
return netlink_genl_simple_transact(nl, GENL_ID_CTRL, NLM_F_REQUEST | NLM_F_ACK, CTRL_CMD_GETFAMILY, 1, wlan_id_prepare, NULL, wlan_id_cb, &id) ? id : 0;
|
||||
}
|
||||
|
||||
static int wlan_info_attr_cb(const struct nlattr *attr, void *data)
|
||||
@@ -1959,42 +1978,130 @@ static int wlan_info_attr_cb(const struct nlattr *attr, void *data)
|
||||
}
|
||||
return MNL_CB_OK;
|
||||
}
|
||||
struct wlan_info_req
|
||||
{
|
||||
struct wlan_interface_collection *wc;
|
||||
bool bReqSSID;
|
||||
};
|
||||
static int wlan_info_cb(const struct nlmsghdr *nlh, void *data)
|
||||
{
|
||||
int ret;
|
||||
struct wlan_info_req *wr = (struct wlan_info_req*)data;
|
||||
if (wr->wc->count>=WLAN_INTERFACE_MAX) return MNL_CB_OK;
|
||||
memset(wr->wc->wlan + wr->wc->count,0,sizeof(struct wlan_interface));
|
||||
ret = mnl_attr_parse(nlh, sizeof(struct genlmsghdr), wlan_info_attr_cb, wr->wc->wlan + wr->wc->count);
|
||||
if (ret>=0 && (!wr->bReqSSID || *wr->wc->wlan[wr->wc->count].ssid) && *wr->wc->wlan[wr->wc->count].ifname && wr->wc->wlan[wr->wc->count].ifindex)
|
||||
wr->wc->count++;
|
||||
return ret;
|
||||
}
|
||||
static bool wlan_info(struct mnl_socket* nl, uint16_t wlan_family_id, struct wlan_interface_collection* w, bool bReqSSID)
|
||||
{
|
||||
struct wlan_info_req req = { .bReqSSID = bReqSSID, .wc = w };
|
||||
return netlink_genl_simple_transact(nl, wlan_family_id, NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP, NL80211_CMD_GET_INTERFACE, 0, NULL, NULL, wlan_info_cb, &req);
|
||||
}
|
||||
|
||||
|
||||
static void scan_prepare(struct nlmsghdr *nlh, void *param)
|
||||
{
|
||||
mnl_attr_put_u32(nlh, NL80211_ATTR_IFINDEX, *(int*)param);
|
||||
}
|
||||
static uint8_t *find_ie(uint8_t *buf, size_t len, uint8_t ie)
|
||||
{
|
||||
while (len>=2)
|
||||
{
|
||||
if (len<(2+buf[1])) break;
|
||||
if (buf[0]==ie) return buf;
|
||||
buf+=buf[1]+2;
|
||||
len-=buf[1]+2;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
static int scan_info_attr_cb(const struct nlattr *attr, void *data)
|
||||
{
|
||||
struct wlan_interface *wlan = (struct wlan_interface *)data;
|
||||
const struct nlattr *nested;
|
||||
uint8_t *payload, *ie;
|
||||
uint16_t payload_len;
|
||||
bool ok;
|
||||
|
||||
switch(mnl_attr_get_type(attr))
|
||||
{
|
||||
case NL80211_ATTR_IFINDEX:
|
||||
if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
|
||||
{
|
||||
DLOG_PERROR("mnl_attr_validate");
|
||||
return MNL_CB_ERROR;
|
||||
}
|
||||
wlan->ifindex = mnl_attr_get_u32(attr);
|
||||
if (!if_indextoname(wlan->ifindex, wlan->ifname))
|
||||
DLOG_PERROR("if_indextoname");
|
||||
break;
|
||||
case NL80211_ATTR_BSS:
|
||||
if (mnl_attr_validate(attr, MNL_TYPE_NESTED) < 0)
|
||||
{
|
||||
DLOG_PERROR("mnl_attr_validate");
|
||||
return MNL_CB_ERROR;
|
||||
}
|
||||
ok = false;
|
||||
mnl_attr_for_each_nested(nested, attr)
|
||||
{
|
||||
if (mnl_attr_get_type(nested)==NL80211_BSS_STATUS)
|
||||
{
|
||||
uint32_t status = mnl_attr_get_u32(nested);
|
||||
if (status==NL80211_BSS_STATUS_ASSOCIATED || status==NL80211_BSS_STATUS_AUTHENTICATED || status==NL80211_BSS_STATUS_IBSS_JOINED)
|
||||
{
|
||||
ok=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!ok) break;
|
||||
mnl_attr_for_each_nested(nested, attr)
|
||||
{
|
||||
switch(mnl_attr_get_type(nested))
|
||||
{
|
||||
case NL80211_BSS_INFORMATION_ELEMENTS:
|
||||
payload_len = mnl_attr_get_payload_len(nested);
|
||||
payload = mnl_attr_get_payload(nested);
|
||||
ie = find_ie(payload,payload_len,0);
|
||||
if (ie)
|
||||
{
|
||||
uint8_t l = ie[1];
|
||||
if (l>=(sizeof(wlan->ssid))) l=sizeof(wlan->ssid)-1;
|
||||
memcpy(wlan->ssid,ie+2,l);
|
||||
wlan->ssid[l]=0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return MNL_CB_OK;
|
||||
}
|
||||
static int scan_info_cb(const struct nlmsghdr *nlh, void *data)
|
||||
{
|
||||
int ret;
|
||||
struct wlan_interface_collection *wc = (struct wlan_interface_collection*)data;
|
||||
if (wc->count>=WLAN_INTERFACE_MAX) return MNL_CB_OK;
|
||||
memset(wc->wlan+wc->count,0,sizeof(wc->wlan[0]));
|
||||
ret = mnl_attr_parse(nlh, sizeof(struct genlmsghdr), wlan_info_attr_cb, wc->wlan+wc->count);
|
||||
if (ret>=0 && *wc->wlan[wc->count].ifname && wc->wlan[wc->count].ifindex)
|
||||
{
|
||||
if (*wc->wlan[wc->count].ssid)
|
||||
wc->count++;
|
||||
else
|
||||
{
|
||||
// sometimes nl80211 does not return SSID but wireless ext does
|
||||
int wext_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (wext_fd!=-1)
|
||||
{
|
||||
struct iwreq req;
|
||||
snprintf(req.ifr_ifrn.ifrn_name,sizeof(req.ifr_ifrn.ifrn_name),"%s",wc->wlan[wc->count].ifname);
|
||||
req.u.essid.pointer = wc->wlan[wc->count].ssid;
|
||||
req.u.essid.length = sizeof(wc->wlan[wc->count].ssid);
|
||||
req.u.essid.flags = 0;
|
||||
if (ioctl(wext_fd, SIOCGIWESSID, &req)!=-1)
|
||||
if (*wc->wlan[wc->count].ssid)
|
||||
wc->count++;
|
||||
close(wext_fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = mnl_attr_parse(nlh, sizeof(struct genlmsghdr), scan_info_attr_cb, wc->wlan+wc->count);
|
||||
if (ret>=0 && *wc->wlan[wc->count].ssid && *wc->wlan[wc->count].ifname && wc->wlan[wc->count].ifindex)
|
||||
wc->count++;
|
||||
return ret;
|
||||
}
|
||||
static bool wlan_info(struct mnl_socket* nl, uint16_t wlan_family_id, struct wlan_interface_collection* w)
|
||||
static bool scan_info(struct mnl_socket* nl, uint16_t wlan_family_id, struct wlan_interface_collection* w)
|
||||
{
|
||||
return netlink_genl_simple_transact(nl, wlan_family_id, NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP, NL80211_CMD_GET_INTERFACE, 0, NULL, wlan_info_cb, w);
|
||||
struct wlan_interface_collection wc_all = { .count = 0 };
|
||||
// wlan_info does not return ssid since kernel 5.19
|
||||
// it's used to enumerate all wifi interfaces then call scan_info on each
|
||||
if (!wlan_info(nl, wlan_family_id, &wc_all, false)) return false;
|
||||
for(int i=0;i<wc_all.count;i++)
|
||||
if (!netlink_genl_simple_transact(nl, wlan_family_id, NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP, NL80211_CMD_GET_SCAN, 0, scan_prepare, (void*)&wc_all.wlan[i].ifindex, scan_info_cb, w))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool wlan_init80211(struct mnl_socket** nl)
|
||||
{
|
||||
if (!(*nl = mnl_socket_open(NETLINK_GENERIC)))
|
||||
@@ -2028,7 +2135,7 @@ static bool wlan_info_rate_limited(struct mnl_socket* nl, uint16_t wlan_family_i
|
||||
// do not purge too often to save resources
|
||||
if (wlan_info_last != now)
|
||||
{
|
||||
bres = wlan_info(nl,wlan_family_id,w);
|
||||
bres = scan_info(nl,wlan_family_id,w);
|
||||
wlan_info_last = now;
|
||||
}
|
||||
return bres;
|
||||
@@ -2054,10 +2161,6 @@ bool wlan_info_init(void)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool wlan_info_get(void)
|
||||
{
|
||||
return wlan_info(nl_wifi, id_nl80211, &wlans);
|
||||
}
|
||||
bool wlan_info_get_rate_limited(void)
|
||||
{
|
||||
return wlan_info_rate_limited(nl_wifi, id_nl80211, &wlans);
|
||||
|
||||
@@ -69,7 +69,7 @@ uint32_t net16_add(uint16_t netorder_value, uint16_t cpuorder_increment);
|
||||
// seq and wsize have network byte order
|
||||
bool prepare_tcp_segment4(
|
||||
const struct sockaddr_in *src, const struct sockaddr_in *dst,
|
||||
uint8_t tcp_flags,
|
||||
uint16_t tcp_flags,
|
||||
bool sack,
|
||||
uint16_t nmss,
|
||||
uint32_t nseq, uint32_t nack_seq,
|
||||
@@ -88,7 +88,7 @@ bool prepare_tcp_segment4(
|
||||
uint8_t *buf, size_t *buflen);
|
||||
bool prepare_tcp_segment6(
|
||||
const struct sockaddr_in6 *src, const struct sockaddr_in6 *dst,
|
||||
uint8_t tcp_flags,
|
||||
uint16_t tcp_flags,
|
||||
bool sack,
|
||||
uint16_t nmss,
|
||||
uint32_t nseq, uint32_t nack_seq,
|
||||
@@ -105,7 +105,7 @@ bool prepare_tcp_segment6(
|
||||
uint8_t *buf, size_t *buflen);
|
||||
bool prepare_tcp_segment(
|
||||
const struct sockaddr *src, const struct sockaddr *dst,
|
||||
uint8_t tcp_flags,
|
||||
uint16_t tcp_flags,
|
||||
bool sack,
|
||||
uint16_t nmss,
|
||||
uint32_t nseq, uint32_t nack_seq,
|
||||
@@ -178,6 +178,8 @@ bool ip_frag(
|
||||
uint8_t *pkt2, size_t *pkt2_size);
|
||||
|
||||
bool rewrite_ttl(struct ip *ip, struct ip6_hdr *ip6, uint8_t ttl);
|
||||
uint16_t get_tcp_flags(const struct tcphdr *tcp);
|
||||
void apply_tcp_flags(struct tcphdr *tcp, uint16_t fl);
|
||||
|
||||
void extract_ports(const struct tcphdr *tcphdr, const struct udphdr *udphdr, uint8_t *proto, uint16_t *sport, uint16_t *dport);
|
||||
void extract_endpoints(const struct ip *ip,const struct ip6_hdr *ip6hdr,const struct tcphdr *tcphdr,const struct udphdr *udphdr, struct sockaddr_storage *src, struct sockaddr_storage *dst);
|
||||
@@ -296,7 +298,6 @@ extern struct wlan_interface_collection wlans;
|
||||
|
||||
void wlan_info_deinit(void);
|
||||
bool wlan_info_init(void);
|
||||
bool wlan_info_get(void);
|
||||
bool wlan_info_get_rate_limited(void);
|
||||
const char *wlan_ssid_search_ifname(const char *ifname);
|
||||
const char *wlan_ssid_search_ifidx(int ifidx);
|
||||
|
||||
135
nfq/desync.c
135
nfq/desync.c
@@ -841,11 +841,13 @@ static uint16_t IP4_IP_ID_FIX(const struct ip *ip, t_ip_id_mode mode)
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
case IPID_RND:
|
||||
return (uint16_t)(random()%0xFFFF + 1);
|
||||
case IPID_SEQ:
|
||||
case IPID_SEQ_GROUP:
|
||||
return ip->ip_id ? ip->ip_id : (uint16_t)random();
|
||||
case IPID_SAME:
|
||||
return ip->ip_id;
|
||||
case IPID_RND:
|
||||
return (uint16_t)(random()%0xFFFF + 1);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -856,8 +858,6 @@ static uint16_t IP4_IP_ID_ADD(uint16_t ip_id, uint16_t inc, t_ip_id_mode mode)
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
case IPID_RND:
|
||||
return (uint16_t)(random()%0xFFFF + 1);;
|
||||
case IPID_SEQ_GROUP:
|
||||
case IPID_SEQ:
|
||||
if (ip_id)
|
||||
@@ -865,7 +865,10 @@ static uint16_t IP4_IP_ID_ADD(uint16_t ip_id, uint16_t inc, t_ip_id_mode mode)
|
||||
ip_id = net16_add(ip_id, inc);
|
||||
if (!ip_id) ip_id = net16_add(ip_id, ((int16_t)inc) < 0 ? -1 : 1); // do not allow zero
|
||||
}
|
||||
case IPID_SAME:
|
||||
return ip_id;
|
||||
case IPID_RND:
|
||||
return (uint16_t)(random()%0xFFFF + 1);;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -929,24 +932,52 @@ static bool runtime_tls_mod(int fake_n, const struct fake_tls_mod_cache *modcach
|
||||
return b;
|
||||
}
|
||||
|
||||
uint8_t orig_mod(const struct desync_profile *dp, const t_ctrack *ctrack, struct dissect *dis)
|
||||
static bool rewrite_tcp_flags(uint16_t *flags, uint16_t unset, uint16_t set, const char *what)
|
||||
{
|
||||
uint8_t ttl, ttl_orig;
|
||||
|
||||
ttl = (ctrack && ctrack->orig_autottl) ? ctrack->orig_autottl : dis->ip6 ? dp->orig_mod_ttl6 : dp->orig_mod_ttl;
|
||||
if (ttl && check_orig_mod_interval(dp, ctrack))
|
||||
if (set || unset)
|
||||
{
|
||||
ttl_orig = dis->ip ? dis->ip->ip_ttl : dis->ip6->ip6_ctlun.ip6_un1.ip6_un1_hlim;
|
||||
if (ttl_orig != ttl)
|
||||
uint16_t fl_new = *flags & ~unset | set;
|
||||
if (fl_new!=*flags)
|
||||
{
|
||||
DLOG("rewrite original packet ttl %u => %u\n", ttl_orig, ttl);
|
||||
rewrite_ttl(dis->ip, dis->ip6, ttl);
|
||||
DLOG("rewrite %s tcp flags 0x%03X => 0x%03X\n", what, *flags, fl_new);
|
||||
*flags = fl_new;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static uint8_t orig_mod(const struct desync_profile *dp, const t_ctrack *ctrack, struct dissect *dis)
|
||||
{
|
||||
uint8_t ttl, ttl_orig;
|
||||
bool bModded = false;
|
||||
|
||||
if (check_orig_mod_interval(dp, ctrack))
|
||||
{
|
||||
ttl = (ctrack && ctrack->orig_autottl) ? ctrack->orig_autottl : dis->ip6 ? dp->orig_mod_ttl6 : dp->orig_mod_ttl;
|
||||
if (ttl)
|
||||
{
|
||||
ttl_orig = dis->ip ? dis->ip->ip_ttl : dis->ip6->ip6_ctlun.ip6_un1.ip6_un1_hlim;
|
||||
if (ttl_orig != ttl)
|
||||
{
|
||||
DLOG("rewrite original packet ttl %u => %u\n", ttl_orig, ttl);
|
||||
rewrite_ttl(dis->ip, dis->ip6, ttl);
|
||||
bModded = true;
|
||||
}
|
||||
}
|
||||
if (dis->tcp)
|
||||
{
|
||||
uint16_t flags = get_tcp_flags(dis->tcp);
|
||||
if (rewrite_tcp_flags(&flags, dp->orig_tcp_flags_unset, dp->orig_tcp_flags_set, "original"))
|
||||
{
|
||||
apply_tcp_flags(dis->tcp,flags);
|
||||
bModded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return bModded;
|
||||
}
|
||||
|
||||
static bool orig_send_rewrite(
|
||||
uint32_t fwmark, const char *ifout, const struct sockaddr *dst,
|
||||
uint8_t ttl_orig, uint8_t ttl_fake, const struct desync_profile *dp, const struct dissect *dis)
|
||||
@@ -960,6 +991,7 @@ static bool orig_send_rewrite(
|
||||
else
|
||||
DLOG("sending %u dups with ttl rewrite %u => %u\n", dp->dup_repeats, ttl_orig, ttl_fake);
|
||||
rewrite_ttl(dis->ip, dis->ip6, ttl_fake);
|
||||
|
||||
// send dups
|
||||
for (k = 0; k < dp->dup_repeats; k++)
|
||||
{
|
||||
@@ -983,9 +1015,10 @@ static bool tcp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c
|
||||
size_t len;
|
||||
uint16_t ip_id, nmss;
|
||||
struct sockaddr_storage src, dst;
|
||||
uint8_t ttl_orig, ttl_fake, flags_orig, scale_factor;
|
||||
uint8_t ttl_orig, ttl_dup, scale_factor;
|
||||
uint16_t flags_dup;
|
||||
uint32_t *timestamps;
|
||||
bool sack, DF;
|
||||
bool sack, DF, bTF;
|
||||
|
||||
extract_endpoints(dis->ip, dis->ip6, dis->tcp, NULL, &src, &dst);
|
||||
ttl_orig = dis->ip ? dis->ip->ip_ttl : dis->ip6->ip6_ctlun.ip6_un1.ip6_un1_hlim;
|
||||
@@ -994,11 +1027,12 @@ static bool tcp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c
|
||||
|
||||
if (dp->dup_repeats && check_dup_interval(dp, ctrack))
|
||||
{
|
||||
ttl_fake = (ctrack && ctrack->dup_autottl) ? ctrack->dup_autottl : (dis->ip6 ? (dp->dup_ttl6 ? dp->dup_ttl6 : ttl_orig) : (dp->dup_ttl ? dp->dup_ttl : ttl_orig));
|
||||
ttl_dup = (ctrack && ctrack->dup_autottl) ? ctrack->dup_autottl : (dis->ip6 ? (dp->dup_ttl6 ? dp->dup_ttl6 : ttl_orig) : (dp->dup_ttl ? dp->dup_ttl : ttl_orig));
|
||||
|
||||
if (dp->dup_fooling_mode)
|
||||
flags_dup = dis->tcp->th_flags;
|
||||
bTF = rewrite_tcp_flags(&flags_dup, dp->dup_tcp_flags_unset, dp->dup_tcp_flags_set, "dup");
|
||||
if (bTF || dp->dup_fooling_mode || (dis->ip && dp->dup_ip_id_mode!=IPID_SAME))
|
||||
{
|
||||
flags_orig = *((uint8_t*)dis->tcp + 13);
|
||||
scale_factor = tcp_find_scale_factor(dis->tcp);
|
||||
timestamps = tcp_find_timestamps(dis->tcp);
|
||||
sack = tcp_has_sack(dis->tcp);
|
||||
@@ -1007,27 +1041,29 @@ static bool tcp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c
|
||||
|
||||
len = sizeof(pkt);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst,
|
||||
flags_orig, sack, nmss,
|
||||
flags_dup, sack, nmss,
|
||||
dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||
ip_has_df(dis->ip), ttl_fake, IP4_TOS(dis->ip), ip_id, IP6_FLOW(dis->ip6),
|
||||
ip_has_df(dis->ip), ttl_dup, IP4_TOS(dis->ip), ip_id, IP6_FLOW(dis->ip6),
|
||||
dp->dup_fooling_mode, dp->dup_ts_increment, dp->dup_badseq_increment, dp->dup_badseq_ack_increment,
|
||||
dis->data_payload, dis->len_payload, pkt, &len))
|
||||
{
|
||||
DLOG_ERR("dup: packet reconstruct failed\n");
|
||||
return false;
|
||||
}
|
||||
DLOG("sending %u dups with packet reconstruct. ttl %u => %u\n", dp->dup_repeats, ttl_orig, ttl_fake);
|
||||
DLOG("sending %u dups with packet reconstruct. ttl %u => %u\n", dp->dup_repeats, ttl_orig, ttl_dup);
|
||||
|
||||
// send dups
|
||||
for (k = 0; k < dp->dup_repeats; k++)
|
||||
{
|
||||
if (!rawsend((struct sockaddr *)&dst, fwmark, ifout, pkt, len))
|
||||
return false;
|
||||
ip_id = IP4_IP_ID_NEXT(ip_id,dp->dup_ip_id_mode);
|
||||
if (dis->ip) ((struct ip*)pkt)->ip_id = ip_id;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!orig_send_rewrite(fwmark, ifout, (struct sockaddr *)&dst, ttl_orig, ttl_fake, dp, dis))
|
||||
if (!orig_send_rewrite(fwmark, ifout, (struct sockaddr *)&dst, ttl_orig, ttl_dup, dp, dis))
|
||||
return false;
|
||||
}
|
||||
if (dp->dup_replace)
|
||||
@@ -1071,7 +1107,7 @@ static bool udp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c
|
||||
{
|
||||
ttl_fake = (ctrack && ctrack->dup_autottl) ? ctrack->dup_autottl : (dis->ip6 ? (dp->dup_ttl6 ? dp->dup_ttl6 : ttl_orig) : (dp->dup_ttl ? dp->dup_ttl : ttl_orig));
|
||||
|
||||
if (dp->dup_fooling_mode)
|
||||
if (dp->dup_fooling_mode || (dis->ip && dp->dup_ip_id_mode!=IPID_SAME))
|
||||
{
|
||||
ip_id = IP4_IP_ID_FIX(dis->ip,dp->ip_id_mode);
|
||||
|
||||
@@ -1092,6 +1128,8 @@ static bool udp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c
|
||||
{
|
||||
if (!rawsend((struct sockaddr *)&dst, fwmark, ifout, pkt, len))
|
||||
return false;
|
||||
ip_id = IP4_IP_ID_NEXT(ip_id,dp->dup_ip_id_mode);
|
||||
if (dis->ip) ((struct ip*)pkt)->ip_id = ip_id;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1136,7 +1174,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
struct sockaddr_storage src, dst;
|
||||
uint8_t pkt1[DPI_DESYNC_MAX_FAKE_LEN + 100], pkt2[DPI_DESYNC_MAX_FAKE_LEN + 100], pkt3[DPI_DESYNC_MAX_FAKE_LEN + 100];
|
||||
size_t pkt1_len, pkt2_len, pkt3_len;
|
||||
uint8_t ttl_orig, ttl_fake, flags_orig, scale_factor;
|
||||
uint8_t ttl_orig, ttl_fake, scale_factor;
|
||||
uint32_t *timestamps;
|
||||
bool bSack, DF;
|
||||
uint16_t nmss;
|
||||
@@ -1167,12 +1205,6 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
DLOG("using cached desync profile %d\n", dp->n);
|
||||
else if (!ctrack_replay->dp_search_complete)
|
||||
{
|
||||
if (!ctrack_replay->hostname && !bReverse)
|
||||
{
|
||||
if (ipcache_get_hostname(dis->ip ? &dis->ip->ip_dst : NULL, dis->ip6 ? &dis->ip6->ip6_dst : NULL, host, sizeof(host), &ctrack_replay->hostname_is_ip) && *host)
|
||||
if (!(ctrack_replay->hostname = strdup(host)))
|
||||
DLOG_ERR("strdup(host): out of memory\n");
|
||||
}
|
||||
dp = ctrack_replay->dp = dp_find(¶ms.desync_profiles, IPPROTO_TCP, (struct sockaddr *)&dst, ctrack_replay->hostname, ctrack_replay->hostname_is_ip, ctrack_replay->l7proto, ssid, NULL, NULL, NULL);
|
||||
ctrack_replay->dp_search_complete = true;
|
||||
}
|
||||
@@ -1387,7 +1419,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
|
||||
ttl_orig = dis->ip ? dis->ip->ip_ttl : dis->ip6->ip6_ctlun.ip6_un1.ip6_un1_hlim;
|
||||
ttl_fake = (ctrack_replay && ctrack_replay->desync_autottl) ? ctrack_replay->desync_autottl : (dis->ip6 ? (dp->desync_ttl6 ? dp->desync_ttl6 : ttl_orig) : (dp->desync_ttl ? dp->desync_ttl : ttl_orig));
|
||||
flags_orig = *((uint8_t*)dis->tcp + 13);
|
||||
uint16_t flags_orig = get_tcp_flags(dis->tcp);
|
||||
scale_factor = tcp_find_scale_factor(dis->tcp);
|
||||
bSack = tcp_has_sack(dis->tcp);
|
||||
nmss = tcp_find_mss(dis->tcp);
|
||||
@@ -1486,7 +1518,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
|
||||
// we do not reassemble http
|
||||
reasm_orig_cancel(ctrack);
|
||||
forced_wssize_cutoff(ctrack);
|
||||
if (!dp->wssize_no_forced_cutoff) forced_wssize_cutoff(ctrack);
|
||||
|
||||
bHaveHost = HttpExtractHost(rdata_payload, rlen_payload, host, sizeof(host));
|
||||
if (!bHaveHost)
|
||||
@@ -1544,7 +1576,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
DLOG("req retrans : seq interval %u-%u\n", ctrack->req_seq_start, ctrack->req_seq_end);
|
||||
ctrack->req_seq_finalized |= bReqFull;
|
||||
}
|
||||
if (bReqFull || ReasmIsEmpty(&ctrack->reasm_orig)) forced_wssize_cutoff(ctrack);
|
||||
if (!dp->wssize_no_forced_cutoff && (bReqFull || ReasmIsEmpty(&ctrack->reasm_orig))) forced_wssize_cutoff(ctrack);
|
||||
|
||||
if (!ReasmIsEmpty(&ctrack->reasm_orig))
|
||||
{
|
||||
@@ -1592,8 +1624,8 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
bool bDiscoveredL7;
|
||||
if (ctrack_replay)
|
||||
{
|
||||
bDiscoveredL7 = !ctrack_replay->l7proto_discovered && ctrack_replay->l7proto != UNKNOWN;
|
||||
ctrack_replay->l7proto_discovered = true;
|
||||
if ((bDiscoveredL7 = !ctrack_replay->l7proto_discovered && ctrack_replay->l7proto != UNKNOWN))
|
||||
ctrack_replay->l7proto_discovered = true;
|
||||
}
|
||||
else
|
||||
bDiscoveredL7 = !ctrack_replay && l7proto != UNKNOWN;
|
||||
@@ -1669,6 +1701,8 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
goto send_orig;
|
||||
}
|
||||
}
|
||||
ttl_orig = dis->ip ? dis->ip->ip_ttl : dis->ip6->ip6_ctlun.ip6_un1.ip6_un1_hlim;
|
||||
ttl_fake = (ctrack_replay && ctrack_replay->desync_autottl) ? ctrack_replay->desync_autottl : (dis->ip6 ? (dp->desync_ttl6 ? dp->desync_ttl6 : ttl_orig) : (dp->desync_ttl ? dp->desync_ttl : ttl_orig));
|
||||
}
|
||||
}
|
||||
else if (ctrack_replay)
|
||||
@@ -1709,7 +1743,6 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
DLOG("applying tampering to unknown protocol\n");
|
||||
}
|
||||
|
||||
ttl_fake = (ctrack_replay && ctrack_replay->desync_autottl) ? ctrack_replay->desync_autottl : (dis->ip6 ? (dp->desync_ttl6 ? dp->desync_ttl6 : ttl_orig) : (dp->desync_ttl ? dp->desync_ttl : ttl_orig));
|
||||
if ((l7proto == HTTP) && (dp->hostcase || dp->hostnospace || dp->domcase || dp->methodeol) && HttpFindHost(&phost, dis->data_payload, dis->len_payload))
|
||||
{
|
||||
if (dp->hostcase)
|
||||
@@ -1912,6 +1945,10 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
seqovl_pos = 0;
|
||||
|
||||
uint32_t fooling_orig = FOOL_NONE;
|
||||
|
||||
uint16_t flags_fake = flags_orig;
|
||||
rewrite_tcp_flags(&flags_fake, dp->desync_tcp_flags_unset, dp->desync_tcp_flags_set, "desync");
|
||||
|
||||
switch (dp->desync_mode)
|
||||
{
|
||||
case DESYNC_FAKE_KNOWN:
|
||||
@@ -1952,7 +1989,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
fake_size = fake_item->size - fake_item->offset;
|
||||
|
||||
pkt1_len = sizeof(pkt1);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, false, 0, htonl(sequence), dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_fake, false, 0, htonl(sequence), dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||
DF, ttl_fake, IP4_TOS(dis->ip), ip_id, IP6_FLOW(dis->ip6),
|
||||
dp->desync_fooling_mode, dp->desync_ts_increment, dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
|
||||
fake_data, fake_size, pkt1, &pkt1_len))
|
||||
@@ -2110,7 +2147,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
|
||||
// pkt2: fake_host segment
|
||||
pkt2_len = sizeof(pkt2);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, false, 0,
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_fake, false, 0,
|
||||
net32_add(dis->tcp->th_seq, pos_host), dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||
DF, ttl_fake, IP4_TOS(dis->ip), ip_id, IP6_FLOW(dis->ip6),
|
||||
dp->desync_fooling_mode, dp->desync_ts_increment, dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
|
||||
@@ -2405,7 +2442,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
}
|
||||
|
||||
fakeseg2_len = sizeof(fakeseg2);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, false, 0, 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_fake, false, 0, net32_add(dis->tcp->th_seq, split_pos), dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||
DF, ttl_fake, IP4_TOS(dis->ip), ip_id, IP6_FLOW(dis->ip6),
|
||||
dp->desync_fooling_mode, dp->desync_ts_increment, dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
|
||||
pat + split_pos, dis->len_payload - split_pos, fakeseg2, &fakeseg2_len))
|
||||
@@ -2448,7 +2485,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
if (split_pos)
|
||||
{
|
||||
seg_len = sizeof(fakeseg);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, false, 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, flags_fake, false, 0, dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||
DF, ttl_fake, IP4_TOS(dis->ip), ip_id, IP6_FLOW(dis->ip6),
|
||||
dp->desync_fooling_mode, dp->desync_ts_increment, dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
|
||||
pat, split_pos, fakeseg, &seg_len))
|
||||
@@ -2517,7 +2554,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
}
|
||||
|
||||
fakeseg_len = sizeof(fakeseg);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, false, 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, flags_fake, false, 0, dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||
DF, ttl_fake, IP4_TOS(dis->ip), ip_id, IP6_FLOW(dis->ip6),
|
||||
dp->desync_fooling_mode, dp->desync_ts_increment, dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
|
||||
pat, split_pos, fakeseg, &fakeseg_len))
|
||||
@@ -2596,7 +2633,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
if (split_pos < dis->len_payload)
|
||||
{
|
||||
fakeseg_len = sizeof(fakeseg);
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, false, 0, 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_fake, false, 0, net32_add(dis->tcp->th_seq, split_pos), dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||
DF, ttl_fake, IP4_TOS(dis->ip), ip_id, IP6_FLOW(dis->ip6),
|
||||
dp->desync_fooling_mode, dp->desync_ts_increment, dp->desync_badseq_increment, dp->desync_badseq_ack_increment,
|
||||
pat + split_pos, dis->len_payload - split_pos, fakeseg, &fakeseg_len))
|
||||
@@ -2768,12 +2805,6 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
DLOG("using cached desync profile %d\n", dp->n);
|
||||
else if (!ctrack_replay->dp_search_complete)
|
||||
{
|
||||
if (!ctrack_replay->hostname && !bReverse)
|
||||
{
|
||||
if (ipcache_get_hostname(dis->ip ? &dis->ip->ip_dst : NULL, dis->ip6 ? &dis->ip6->ip6_dst : NULL, host, sizeof(host), &ctrack_replay->hostname_is_ip) && *host)
|
||||
if (!(ctrack_replay->hostname = strdup(host)))
|
||||
DLOG_ERR("strdup(host): out of memory\n");
|
||||
}
|
||||
dp = ctrack_replay->dp = dp_find(¶ms.desync_profiles, IPPROTO_UDP, (struct sockaddr *)&dst, ctrack_replay->hostname, ctrack_replay->hostname_is_ip, ctrack_replay->l7proto, ssid, NULL, NULL, NULL);
|
||||
ctrack_replay->dp_search_complete = true;
|
||||
}
|
||||
@@ -2860,7 +2891,6 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
}
|
||||
|
||||
uint32_t desync_fwmark = fwmark | params.desync_fwmark;
|
||||
ttl_orig = dis->ip ? dis->ip->ip_ttl : dis->ip6->ip6_ctlun.ip6_un1.ip6_un1_hlim;
|
||||
DF = ip_has_df(dis->ip);
|
||||
|
||||
if (dis->len_payload)
|
||||
@@ -3065,8 +3095,8 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
bool bDiscoveredL7;
|
||||
if (ctrack_replay)
|
||||
{
|
||||
bDiscoveredL7 = !ctrack_replay->l7proto_discovered && ctrack_replay->l7proto != UNKNOWN;
|
||||
ctrack_replay->l7proto_discovered = true;
|
||||
if ((bDiscoveredL7 = !ctrack_replay->l7proto_discovered && ctrack_replay->l7proto != UNKNOWN))
|
||||
ctrack_replay->l7proto_discovered = true;
|
||||
}
|
||||
else
|
||||
bDiscoveredL7 = !ctrack_replay && l7proto != UNKNOWN;
|
||||
@@ -3156,7 +3186,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
if (ctrack_replay->hostname_ah_check)
|
||||
{
|
||||
// first request is not retrans
|
||||
if (!bDiscoveredHostname)
|
||||
if (!bDiscoveredHostname && !reasm_offset)
|
||||
process_retrans_fail(ctrack_replay, IPPROTO_UDP, (struct sockaddr*)&src);
|
||||
}
|
||||
}
|
||||
@@ -3188,6 +3218,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
||||
break;
|
||||
}
|
||||
|
||||
ttl_orig = dis->ip ? dis->ip->ip_ttl : dis->ip6->ip6_ctlun.ip6_un1.ip6_un1_hlim;
|
||||
ttl_fake = (ctrack_replay && ctrack_replay->desync_autottl) ? ctrack_replay->desync_autottl : (dis->ip6 ? (dp->desync_ttl6 ? dp->desync_ttl6 : ttl_orig) : (dp->desync_ttl ? dp->desync_ttl : ttl_orig));
|
||||
|
||||
uint32_t fooling_orig = FOOL_NONE;
|
||||
|
||||
148
nfq/nfqws.c
148
nfq/nfqws.c
@@ -1303,6 +1303,63 @@ static bool parse_strlist(char *opt, struct str_list_head *list)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parse_tcpflags(char *opt, uint16_t *fl)
|
||||
{
|
||||
unsigned int u;
|
||||
char *e, *p, c;
|
||||
|
||||
if (sscanf(optarg, "0x%X", &u)<=0 && sscanf(optarg, "%u", &u)<=0)
|
||||
{
|
||||
*fl=0;
|
||||
for (p = opt; p; )
|
||||
{
|
||||
if ((e = strchr(p, ',')))
|
||||
{
|
||||
c = *e;
|
||||
*e = 0;
|
||||
}
|
||||
|
||||
if (!strcasecmp(p, "FIN"))
|
||||
*fl |= TH_FIN;
|
||||
else if (!strcasecmp(p, "SYN"))
|
||||
*fl |= TH_SYN;
|
||||
else if (!strcasecmp(p, "RST"))
|
||||
*fl |= TH_RST;
|
||||
else if (!strcasecmp(p, "PSH") || !strcasecmp(p, "PUSH"))
|
||||
*fl |= TH_PUSH;
|
||||
else if (!strcasecmp(p, "ACK"))
|
||||
*fl |= TH_ACK;
|
||||
else if (!strcasecmp(p, "URG"))
|
||||
*fl |= TH_URG;
|
||||
else if (!strcasecmp(p, "ECE"))
|
||||
*fl |= 0x40;
|
||||
else if (!strcasecmp(p, "CWR"))
|
||||
*fl |= 0x80;
|
||||
else if (!strcasecmp(p, "AE") || !strcasecmp(p, "AECN") || !strcasecmp(p, "ACCECN"))
|
||||
*fl |= 0x100;
|
||||
else if (!strcasecmp(p, "R1"))
|
||||
*fl |= 0x200;
|
||||
else if (!strcasecmp(p, "R2"))
|
||||
*fl |= 0x400;
|
||||
else if (!strcasecmp(p, "R3"))
|
||||
*fl |= 0x800;
|
||||
else
|
||||
return false;
|
||||
if (e) *e++ = c;
|
||||
p = e;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
*fl = u & 0xFFF;
|
||||
return *fl==u;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void split_compat(struct desync_profile *dp)
|
||||
{
|
||||
if (!dp->split_count)
|
||||
@@ -1768,11 +1825,14 @@ static void exithelp(void)
|
||||
" --wsize=<window_size>[:<scale_factor>]\t\t\t; set window size. 0 = do not modify. OBSOLETE !\n"
|
||||
" --wssize=<window_size>[:<scale_factor>]\t\t; set window size for server. 0 = do not modify. default scale_factor = 0.\n"
|
||||
" --wssize-cutoff=[n|d|s]N\t\t\t\t; apply server wsize only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N\n"
|
||||
" --wssize-forced-cutoff=0|1\t\t\t\t; 1(default)=auto cutoff wssize on known protocol\n"
|
||||
" --synack-split=[syn|synack|acksyn]\t\t\t; perform TCP split handshake : send SYN only, SYN+ACK or ACK+SYN\n"
|
||||
" --orig-ttl=<int>\t\t\t\t\t; set TTL for original packets\n"
|
||||
" --orig-ttl6=<int>\t\t\t\t\t; set ipv6 hop limit for original packets. by default ttl value is used\n"
|
||||
" --orig-autottl=[<delta>[:<min>[-<max>]]|-]\t\t; auto ttl mode for both ipv4 and ipv6. default: +%d:%u-%u\n"
|
||||
" --orig-autottl6=[<delta>[:<min>[-<max>]]|-]\t\t; overrides --orig-autottl for ipv6 only\n"
|
||||
" --orig-tcp-flags-set=<int|0xHEX|flaglist>\t\t; set these tcp flags (flags |= value). value can be int, hex or comma separated list : FIN,SYN,RST,PSH,ACK,URG,ECE,CWR,AE,R1,R2,R3\n"
|
||||
" --orig-tcp-flags-unset=<int|0xHEX|flaglist>\t\t; unset these tcp flags (flags &= ~value)\n"
|
||||
" --orig-mod-start=[n|d|s]N\t\t\t\t; apply orig TTL mod to packet numbers (n, default), data packet numbers (d), relative sequence (s) greater or equal than N\n"
|
||||
" --orig-mod-cutoff=[n|d|s]N\t\t\t\t; apply orig TTL mod to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N\n"
|
||||
" --dup=<int>\t\t\t\t\t\t; duplicate original packets. send N dups before original.\n"
|
||||
@@ -1781,10 +1841,13 @@ static void exithelp(void)
|
||||
" --dup-ttl6=<int>\t\t\t\t\t; set ipv6 hop limit for dups. by default ttl value is used\n"
|
||||
" --dup-autottl=[<delta>[:<min>[-<max>]]|-]\t\t; auto ttl mode for both ipv4 and ipv6. default: %d:%u-%u\n"
|
||||
" --dup-autottl6=[<delta>[:<min>[-<max>]]|-]\t\t; overrides --dup-autottl for ipv6 only\n"
|
||||
" --dup-tcp-flags-set=<int|0xHEX|flaglist>\t\t; set these tcp flags (flags |= value). value can be int, hex or comma separated list : FIN,SYN,RST,PSH,ACK,URG,ECE,CWR,AE,R1,R2,R3\n"
|
||||
" --dup-tcp-flags-unset=<int|0xHEX|flaglist>\t\t; unset these tcp flags (flags &= ~value)\n"
|
||||
" --dup-fooling=<mode>[,<mode>]\t\t\t\t; can use multiple comma separated values. modes : none md5sig badseq badsum datanoack ts hopbyhop hopbyhop2\n"
|
||||
" --dup-ts-increment=<int|0xHEX>\t\t\t\t; ts fooling TSval signed increment for dup. default %d\n"
|
||||
" --dup-badseq-increment=<int|0xHEX>\t\t\t; badseq fooling seq signed increment for dup. default %d\n"
|
||||
" --dup-badack-increment=<int|0xHEX>\t\t\t; badseq fooling ackseq signed increment for dup. default %d\n"
|
||||
" --dup-ip-id=same|zero|seq|rnd\t\t\t\t; ipv4 ip_id mode for dupped packets\n"
|
||||
" --dup-start=[n|d|s]N\t\t\t\t\t; apply dup to packet numbers (n, default), data packet numbers (d), relative sequence (s) greater or equal than N\n"
|
||||
" --dup-cutoff=[n|d|s]N\t\t\t\t\t; apply dup to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N\n"
|
||||
" --hostcase\t\t\t\t\t\t; change Host: => host:\n"
|
||||
@@ -1805,6 +1868,8 @@ static void exithelp(void)
|
||||
" --dpi-desync-ttl6=<int>\t\t\t\t; set ipv6 hop limit for fake packet. by default --dpi-desync-ttl value is used.\n"
|
||||
" --dpi-desync-autottl=[<delta>[:<min>[-<max>]]|-]\t; auto ttl mode for both ipv4 and ipv6. default: %d:%u-%u\n"
|
||||
" --dpi-desync-autottl6=[<delta>[:<min>[-<max>]]|-]\t; overrides --dpi-desync-autottl for ipv6 only\n"
|
||||
" --dpi-desync-tcp-flags-set=<int|0xHEX|flaglist>\t; set these tcp flags (flags |= value). value can be int, hex or comma separated list : FIN,SYN,RST,PSH,ACK,URG,ECE,CWR,AE,R1,R2,R3\n"
|
||||
" --dpi-desync-tcp-flags-unset=<int|0xHEX|flaglist>\t; unset these tcp flags (flags &= ~value)\n"
|
||||
" --dpi-desync-fooling=<mode>[,<mode>]\t\t\t; can use multiple comma separated values. modes : none md5sig badseq badsum datanoack ts hopbyhop hopbyhop2\n"
|
||||
" --dpi-desync-repeats=<N>\t\t\t\t; send every desync packet N times\n"
|
||||
" --dpi-desync-skip-nosni=0|1\t\t\t\t; 1(default)=do not act on ClientHello without SNI\n"
|
||||
@@ -1816,7 +1881,7 @@ static void exithelp(void)
|
||||
" --dpi-desync-split-seqovl-pattern=[+ofs]@<filename>|0xHEX ; pattern for the fake part of overlap\n"
|
||||
" --dpi-desync-fakedsplit-pattern=[+ofs]@<filename>|0xHEX ; fake pattern for fakedsplit/fakeddisorder\n"
|
||||
" --dpi-desync-fakedsplit-mod=mod[,mod]\t\t\t; mods can be none,altorder=0|1|2|3 + 0|8|16\n"
|
||||
" --dpi-desync-hostfakesplit-midhost=marker+N|marker-N ; additionally split real hostname at specified marker. must be within host..endhost or won't be splitted.\n"
|
||||
" --dpi-desync-hostfakesplit-midhost=marker+N|marker-N\t; additionally split real hostname at specified marker. must be within host..endhost or won't be splitted.\n"
|
||||
" --dpi-desync-hostfakesplit-mod=mod[,mod]\t\t; mods can be none,host=<hostname>,altorder=0|1\n"
|
||||
" --dpi-desync-ipfrag-pos-tcp=<8..%u>\t\t\t; ip frag position starting from the transport header. multiple of 8, default %u.\n"
|
||||
" --dpi-desync-ipfrag-pos-udp=<8..%u>\t\t\t; ip frag position starting from the transport header. multiple of 8, default %u.\n"
|
||||
@@ -1950,6 +2015,7 @@ enum opt_indices {
|
||||
IDX_WSIZE,
|
||||
IDX_WSSIZE,
|
||||
IDX_WSSIZE_CUTOFF,
|
||||
IDX_WSSIZE_FORCED_CUTOFF,
|
||||
IDX_SYNACK_SPLIT,
|
||||
IDX_CTRACK_TIMEOUTS,
|
||||
IDX_CTRACK_DISABLE,
|
||||
@@ -1972,23 +2038,30 @@ enum opt_indices {
|
||||
IDX_DUP_TTL6,
|
||||
IDX_DUP_AUTOTTL,
|
||||
IDX_DUP_AUTOTTL6,
|
||||
IDX_DUP_TCP_FLAGS_SET,
|
||||
IDX_DUP_TCP_FLAGS_UNSET,
|
||||
IDX_DUP_FOOLING,
|
||||
IDX_DUP_TS_INCREMENT,
|
||||
IDX_DUP_BADSEQ_INCREMENT,
|
||||
IDX_DUP_BADACK_INCREMENT,
|
||||
IDX_DUP_REPLACE,
|
||||
IDX_DUP_IP_ID,
|
||||
IDX_DUP_START,
|
||||
IDX_DUP_CUTOFF,
|
||||
IDX_ORIG_TTL,
|
||||
IDX_ORIG_TTL6,
|
||||
IDX_ORIG_AUTOTTL,
|
||||
IDX_ORIG_AUTOTTL6,
|
||||
IDX_ORIG_TCP_FLAGS_SET,
|
||||
IDX_ORIG_TCP_FLAGS_UNSET,
|
||||
IDX_ORIG_MOD_START,
|
||||
IDX_ORIG_MOD_CUTOFF,
|
||||
IDX_DPI_DESYNC_TTL,
|
||||
IDX_DPI_DESYNC_TTL6,
|
||||
IDX_DPI_DESYNC_AUTOTTL,
|
||||
IDX_DPI_DESYNC_AUTOTTL6,
|
||||
IDX_DPI_DESYNC_TCP_FLAGS_SET,
|
||||
IDX_DPI_DESYNC_TCP_FLAGS_UNSET,
|
||||
IDX_DPI_DESYNC_FOOLING,
|
||||
IDX_DPI_DESYNC_REPEATS,
|
||||
IDX_DPI_DESYNC_SKIP_NOSNI,
|
||||
@@ -2083,6 +2156,7 @@ static const struct option long_options[] = {
|
||||
[IDX_WSIZE] = {"wsize", required_argument, 0, 0},
|
||||
[IDX_WSSIZE] = {"wssize", required_argument, 0, 0},
|
||||
[IDX_WSSIZE_CUTOFF] = {"wssize-cutoff", required_argument, 0, 0},
|
||||
[IDX_WSSIZE_FORCED_CUTOFF] = {"wssize-forced-cutoff", required_argument, 0, 0},
|
||||
[IDX_SYNACK_SPLIT] = {"synack-split", optional_argument, 0, 0},
|
||||
[IDX_CTRACK_TIMEOUTS] = {"ctrack-timeouts", required_argument, 0, 0},
|
||||
[IDX_CTRACK_DISABLE] = {"ctrack-disable", optional_argument, 0, 0},
|
||||
@@ -2105,23 +2179,30 @@ static const struct option long_options[] = {
|
||||
[IDX_DUP_TTL6] = {"dup-ttl6", required_argument, 0, 0},
|
||||
[IDX_DUP_AUTOTTL] = {"dup-autottl", optional_argument, 0, 0},
|
||||
[IDX_DUP_AUTOTTL6] = {"dup-autottl6", optional_argument, 0, 0},
|
||||
[IDX_DUP_TCP_FLAGS_SET] = {"dup-tcp-flags-set", optional_argument, 0, 0},
|
||||
[IDX_DUP_TCP_FLAGS_UNSET] = {"dup-tcp-flags-unset", optional_argument, 0, 0},
|
||||
[IDX_DUP_FOOLING] = {"dup-fooling", required_argument, 0, 0},
|
||||
[IDX_DUP_TS_INCREMENT] = {"dup-ts-increment", required_argument, 0, 0},
|
||||
[IDX_DUP_BADSEQ_INCREMENT] = {"dup-badseq-increment", required_argument, 0, 0},
|
||||
[IDX_DUP_BADACK_INCREMENT] = {"dup-badack-increment", required_argument, 0, 0},
|
||||
[IDX_DUP_REPLACE] = {"dup-replace", optional_argument, 0, 0},
|
||||
[IDX_DUP_IP_ID] = {"dup-ip-id", required_argument, 0, 0},
|
||||
[IDX_DUP_START] = {"dup-start", required_argument, 0, 0},
|
||||
[IDX_DUP_CUTOFF] = {"dup-cutoff", required_argument, 0, 0},
|
||||
[IDX_ORIG_TTL] = {"orig-ttl", required_argument, 0, 0},
|
||||
[IDX_ORIG_TTL6] = {"orig-ttl6", required_argument, 0, 0},
|
||||
[IDX_ORIG_AUTOTTL] = {"orig-autottl", optional_argument, 0, 0},
|
||||
[IDX_ORIG_AUTOTTL6] = {"orig-autottl6", optional_argument, 0, 0},
|
||||
[IDX_ORIG_TCP_FLAGS_SET] = {"orig-tcp-flags-set", optional_argument, 0, 0},
|
||||
[IDX_ORIG_TCP_FLAGS_UNSET] = {"orig-tcp-flags-unset", optional_argument, 0, 0},
|
||||
[IDX_ORIG_MOD_START] = {"orig-mod-start", required_argument, 0, 0},
|
||||
[IDX_ORIG_MOD_CUTOFF] = {"orig-mod-cutoff", required_argument, 0, 0},
|
||||
[IDX_DPI_DESYNC_TTL] = {"dpi-desync-ttl", required_argument, 0, 0},
|
||||
[IDX_DPI_DESYNC_TTL6] = {"dpi-desync-ttl6", required_argument, 0, 0},
|
||||
[IDX_DPI_DESYNC_AUTOTTL] = {"dpi-desync-autottl", optional_argument, 0, 0},
|
||||
[IDX_DPI_DESYNC_AUTOTTL6] = {"dpi-desync-autottl6", optional_argument, 0, 0},
|
||||
[IDX_DPI_DESYNC_TCP_FLAGS_SET] = {"dpi-desync-tcp-flags-set", optional_argument, 0, 0},
|
||||
[IDX_DPI_DESYNC_TCP_FLAGS_UNSET] = {"dpi-desync-tcp-flags-unset", optional_argument, 0, 0},
|
||||
[IDX_DPI_DESYNC_FOOLING] = {"dpi-desync-fooling", required_argument, 0, 0},
|
||||
[IDX_DPI_DESYNC_REPEATS] = {"dpi-desync-repeats", required_argument, 0, 0},
|
||||
[IDX_DPI_DESYNC_SKIP_NOSNI] = {"dpi-desync-skip-nosni", optional_argument, 0, 0},
|
||||
@@ -2303,6 +2384,7 @@ int main(int argc, char **argv)
|
||||
fprintf(stderr, "cannot create %s\n", params.debug_logfile);
|
||||
exit_clean(1);
|
||||
}
|
||||
fclose(F);
|
||||
params.debug = true;
|
||||
params.debug_target = LOG_TARGET_FILE;
|
||||
}
|
||||
@@ -2423,6 +2505,9 @@ int main(int argc, char **argv)
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case IDX_WSSIZE_FORCED_CUTOFF:
|
||||
dp->wssize_no_forced_cutoff = !atoi(optarg);
|
||||
break;
|
||||
case IDX_SYNACK_SPLIT:
|
||||
dp->synack_split = SS_SYN;
|
||||
if (optarg)
|
||||
@@ -2594,6 +2679,20 @@ int main(int argc, char **argv)
|
||||
}
|
||||
params.autottl_present = true;
|
||||
break;
|
||||
case IDX_DUP_TCP_FLAGS_SET:
|
||||
if (!parse_tcpflags(optarg, &dp->dup_tcp_flags_set))
|
||||
{
|
||||
DLOG_ERR("invalid tcp flags\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case IDX_DUP_TCP_FLAGS_UNSET:
|
||||
if (!parse_tcpflags(optarg, &dp->dup_tcp_flags_unset))
|
||||
{
|
||||
DLOG_ERR("invalid tcp flags\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case IDX_DUP_REPLACE:
|
||||
dp->dup_replace = !optarg || atoi(optarg);
|
||||
break;
|
||||
@@ -2639,6 +2738,21 @@ int main(int argc, char **argv)
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case IDX_DUP_IP_ID:
|
||||
if (!strcmp(optarg,"zero"))
|
||||
dp->dup_ip_id_mode = IPID_ZERO;
|
||||
else if (!strcmp(optarg,"same"))
|
||||
dp->dup_ip_id_mode = IPID_SAME;
|
||||
else if (!strcmp(optarg,"seq"))
|
||||
dp->dup_ip_id_mode = IPID_SEQ;
|
||||
else if (!strcmp(optarg,"rnd"))
|
||||
dp->dup_ip_id_mode = IPID_RND;
|
||||
else
|
||||
{
|
||||
DLOG_ERR("invalid dup ip_id mode : %s\n",optarg);
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
|
||||
case IDX_ORIG_TTL:
|
||||
dp->orig_mod_ttl = (uint8_t)atoi(optarg);
|
||||
@@ -2662,6 +2776,20 @@ int main(int argc, char **argv)
|
||||
}
|
||||
params.autottl_present = true;
|
||||
break;
|
||||
case IDX_ORIG_TCP_FLAGS_SET:
|
||||
if (!parse_tcpflags(optarg, &dp->orig_tcp_flags_set))
|
||||
{
|
||||
DLOG_ERR("invalid tcp flags\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case IDX_ORIG_TCP_FLAGS_UNSET:
|
||||
if (!parse_tcpflags(optarg, &dp->orig_tcp_flags_unset))
|
||||
{
|
||||
DLOG_ERR("invalid tcp flags\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case IDX_ORIG_MOD_CUTOFF:
|
||||
if (!parse_cutoff(optarg, &dp->orig_mod_cutoff, &dp->orig_mod_cutoff_mode))
|
||||
{
|
||||
@@ -2699,6 +2827,20 @@ int main(int argc, char **argv)
|
||||
}
|
||||
params.autottl_present = true;
|
||||
break;
|
||||
case IDX_DPI_DESYNC_TCP_FLAGS_SET:
|
||||
if (!parse_tcpflags(optarg, &dp->desync_tcp_flags_set))
|
||||
{
|
||||
DLOG_ERR("invalid tcp flags\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case IDX_DPI_DESYNC_TCP_FLAGS_UNSET:
|
||||
if (!parse_tcpflags(optarg, &dp->desync_tcp_flags_unset))
|
||||
{
|
||||
DLOG_ERR("invalid tcp flags\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case IDX_DPI_DESYNC_FOOLING:
|
||||
if (!parse_fooling(optarg, &dp->desync_fooling_mode))
|
||||
{
|
||||
@@ -2776,8 +2918,8 @@ int main(int argc, char **argv)
|
||||
size_t sz = sizeof(buf);
|
||||
load_file_or_exit(optarg, buf, &sz, NULL);
|
||||
fill_pattern(dp->seqovl_pattern, sizeof(dp->seqovl_pattern), buf, sz, 0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case IDX_DPI_DESYNC_FAKEDSPLIT_PATTERN:
|
||||
{
|
||||
free(dp->fsplit_pattern);
|
||||
@@ -2788,8 +2930,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
load_file_or_exit(optarg, dp->fsplit_pattern, &dp->fsplit_pattern_size, NULL);
|
||||
dp->fsplit_pattern = realloc(dp->fsplit_pattern, dp->fsplit_pattern_size);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case IDX_DPI_DESYNC_FAKEDSPLIT_MOD:
|
||||
if (!parse_fakedsplit_mod(optarg, &dp->fs_mod))
|
||||
{
|
||||
|
||||
@@ -219,6 +219,9 @@ void dp_init(struct desync_profile *dp)
|
||||
LIST_INIT(&dp->ips_collection_exclude);
|
||||
LIST_INIT(&dp->pf_tcp);
|
||||
LIST_INIT(&dp->pf_udp);
|
||||
#ifdef HAS_FILTER_SSID
|
||||
LIST_INIT(&dp->filter_ssid);
|
||||
#endif
|
||||
|
||||
memcpy(dp->hostspell, "host", 4); // default hostspell
|
||||
dp->desync_skip_nosni = true;
|
||||
@@ -237,6 +240,7 @@ void dp_init(struct desync_profile *dp)
|
||||
dp->hostlist_auto_fail_time = HOSTLIST_AUTO_FAIL_TIME_DEFAULT;
|
||||
dp->hostlist_auto_retrans_threshold = HOSTLIST_AUTO_RETRANS_THRESHOLD_DEFAULT;
|
||||
dp->filter_ipv4 = dp->filter_ipv6 = true;
|
||||
dp->dup_ip_id_mode = IPID_SAME;
|
||||
}
|
||||
bool dp_fake_defaults(struct desync_profile *dp)
|
||||
{
|
||||
|
||||
@@ -97,7 +97,7 @@ struct tcp_mod
|
||||
};
|
||||
|
||||
typedef enum {SS_NONE=0,SS_SYN,SS_SYNACK,SS_ACKSYN} t_synack_split;
|
||||
typedef enum {IPID_SEQ=0,IPID_SEQ_GROUP,IPID_RND,IPID_ZERO} t_ip_id_mode;
|
||||
typedef enum {IPID_SEQ=0,IPID_SEQ_GROUP,IPID_RND,IPID_ZERO,IPID_SAME} t_ip_id_mode;
|
||||
|
||||
struct desync_profile
|
||||
{
|
||||
@@ -106,6 +106,7 @@ struct desync_profile
|
||||
uint16_t wsize,wssize;
|
||||
uint8_t wscale,wsscale;
|
||||
char wssize_cutoff_mode; // n - packets, d - data packets, s - relative sequence
|
||||
bool wssize_no_forced_cutoff;
|
||||
unsigned int wssize_cutoff;
|
||||
|
||||
t_synack_split synack_split;
|
||||
@@ -131,11 +132,14 @@ struct desync_profile
|
||||
uint32_t dup_fooling_mode;
|
||||
uint32_t dup_ts_increment, dup_badseq_increment, dup_badseq_ack_increment;
|
||||
autottl dup_autottl, dup_autottl6;
|
||||
uint16_t dup_tcp_flags_set, dup_tcp_flags_unset;
|
||||
t_ip_id_mode dup_ip_id_mode;
|
||||
|
||||
char orig_mod_start_mode, orig_mod_cutoff_mode; // n - packets, d - data packets, s - relative sequence
|
||||
unsigned int orig_mod_start, orig_mod_cutoff;
|
||||
uint8_t orig_mod_ttl, orig_mod_ttl6;
|
||||
autottl orig_autottl, orig_autottl6;
|
||||
uint16_t orig_tcp_flags_set, orig_tcp_flags_unset;
|
||||
|
||||
char desync_start_mode, desync_cutoff_mode; // n - packets, d - data packets, s - relative sequence
|
||||
unsigned int desync_start, desync_cutoff;
|
||||
@@ -143,6 +147,7 @@ struct desync_profile
|
||||
autottl desync_autottl, desync_autottl6;
|
||||
uint32_t desync_fooling_mode;
|
||||
uint32_t desync_ts_increment, desync_badseq_increment, desync_badseq_ack_increment;
|
||||
uint16_t desync_tcp_flags_set, desync_tcp_flags_unset;
|
||||
|
||||
struct blob_collection_head fake_http,fake_tls,fake_unknown,fake_unknown_udp,fake_quic,fake_wg,fake_dht,fake_discord,fake_stun;
|
||||
uint8_t fake_syndata[FAKE_MAX_TCP],seqovl_pattern[FAKE_MAX_TCP],udplen_pattern[FAKE_MAX_UDP];
|
||||
@@ -184,7 +189,7 @@ struct desync_profile
|
||||
#define PROFILE_IPSETS_ABSENT(dp) (!LIST_FIRST(&(dp)->ips_collection) && !LIST_FIRST(&(dp)->ips_collection_exclude))
|
||||
#define PROFILE_IPSETS_EMPTY(dp) (ipset_collection_is_empty(&(dp)->ips_collection) && ipset_collection_is_empty(&(dp)->ips_collection_exclude))
|
||||
#define PROFILE_HOSTLISTS_EMPTY(dp) (hostlist_collection_is_empty(&(dp)->hl_collection) && hostlist_collection_is_empty(&(dp)->hl_collection_exclude))
|
||||
#define PROFILE_HAS_ORIG_MOD(dp) ((dp)->orig_mod_ttl || (dp)->orig_mod_ttl6)
|
||||
#define PROFILE_HAS_ORIG_MOD(dp) ((dp)->orig_mod_ttl || (dp)->orig_mod_ttl6 || (dp)->orig_tcp_flags_set || (dp)->orig_tcp_flags_unset)
|
||||
|
||||
struct desync_profile_list {
|
||||
struct desync_profile dp;
|
||||
|
||||
@@ -52,14 +52,6 @@ bool l7_proto_match(t_l7proto l7proto, uint32_t filter_l7)
|
||||
(l7proto==STUN && (filter_l7 & L7_PROTO_STUN));
|
||||
}
|
||||
|
||||
#define PM_ABS 0
|
||||
#define PM_HOST 1
|
||||
#define PM_HOST_END 2
|
||||
#define PM_HOST_SLD 3
|
||||
#define PM_HOST_MIDSLD 4
|
||||
#define PM_HOST_ENDSLD 5
|
||||
#define PM_HTTP_METHOD 6
|
||||
#define PM_SNI_EXT 7
|
||||
bool IsHostMarker(uint8_t posmarker)
|
||||
{
|
||||
switch(posmarker)
|
||||
|
||||
Reference in New Issue
Block a user