zapret2 README

The project's README from github.com/bol-van/zapret2. As one markdown file: README.md.

English

Manual

Зачем это нужно

Автономное средство противодействия DPI, которое не требует подключения каких-либо сторонних серверов. Может помочь обойти блокировки или замедление сайтов HTTP(S), сигнатурный анализ TCP и UDP протоколов, например, с целью блокировки VPN. Может использоваться для частичной прозрачной обфускации протоколов.

Проект нацелен прежде всего на маломощные embedded устройства - роутеры, работающие под OpenWrt. Поддерживаются традиционные Linux-системы, FreeBSD, OpenBSD, Windows. MacOS не поддерживается и вряд ли будет по техническим причинам. В некоторых случаях возможна самостоятельная прикрутка решения к различным прошивкам.

Полный мануал

Поддержать разработчика. Donations

Если вы считаете проект полезным и желаете поддержать разработку, направляйте ваши пожертвования на следующие адреса криптокошельков :

If you find this project useful and wish to donate here are crypto wallets :

USDT ERC 0x3d52Ce15B7Be734c53fc9526ECbAB8267b63d66E

USDT TRC TEzAAtn4VhndqEaAyuCM78xh5W2gCjwWEo

BTC bc1qhqew3mrvp47uk2vevt5sctp7p2x9m7m5kkchve

ETH 0x3d52Ce15B7Be734c53fc9526ECbAB8267b63d66E

Чем это отличается от zapret1

zapret2 является дальнейшим развитием проекта zapret. Проблема его основной части nfqws1 в том, что он перегружен опциями и в условиях нарастающего противостояния регулятора и пользователей не обеспечивает достаточную гибкость воздействия на трафик. Обход DPI требует все более тонких и специфических воздействий, которые меняются со временем, а старые перестают работать.

Стратегии - это программы, управляющие сценарием атаки на DPI. В nfqws1 они зашиваются в C код. Написание C кода - занятие нелегкое, требующее достаточной квалификации разработчика и времени.

Цель nfqws2 - сделать так, чтобы программы стратегий мог написать любой человек, владеющий знаниями в области сетей, понимающий уязвимости DPI или хотя бы область , в которой их можно искать, плюс владеющий базовыми навыками программирования.

nfqws2 оставляет в себе практически тот же функционал - распознавание протоколов, реассемблинг, дешифровка, управление профилями, хостлисты, ipset-ы, базовая фильтрация. Но он полностью лишается возможностей самостоятельно воздействовать на трафик. Часть "дурения" переносится в скриптовой язык программирования Lua.

Lua код получает от C кода структурированное представление приходящих пакетов в виде дерева (диссекты), подобного тем, что вы видите в wireshark. Туда же приходят результаты сборки или дешифровки частей некоторых протоколов (tls, quic). С код предоставляет функции-хелперы, позволяющие отсылать пакеты, работать с двоичными данными, разбирать TLS, искать маркер-позиции и т.д. Имеется библиотека хелперов, написанных на Lua, а так же готовая библиотека программ атаки на DPI (стратегий), реализующая функции nfqws1 в расширенном варианте и с большей гибкостью.

Вы всегда сможете взять и дописать что-то свое. В этом и есть смысл, чтобы борьбой с DPI смог заняться любой, кто разбирается в пакетах. Мог "потыкать" его, проверить свои идеи. А потом поделиться с друзьями своим решением "одного клика". zapret2 - инструмент для таких энтузиастов. Но это не готовое решение для чайников. Проект не ставит себе целью сделать все простым для всех. Автор считает, что это невозможно в принципе по обьективным причинам.

Борьбой с DPI возможности zapret2 не ограничиваются. По сути это мультиплатформенный пакетный программируемый манипулятор. Вы можете использовать его для генерации произвольного IPv4/IPv6 трафика, обфускации или шифрования имеющегося, построения нестандартных протоколов обмена через IP сети, реализации собственных firewall или DPI систем.

С чего начать

Хотелось бы избежать талмуда на главной странице. Поэтому начнем со способа запуска nfqws2 и описания способов портирования стратегий nfqws1 - как в nfqws2 сделать то же самое, что можно было в nfqws1. Когда вы поймете как это работает, вы можете посмотреть Lua код, находящийся "под капотом". Разобрать как он работает, попробовать написать что-то свое, руководствуясь талмудом как справочником.

Механика обработки трафика

Изначально сетевой трафик в любой ОС появляется в ядре. Первая задача - извлечь его оттуда и перенаправить на процесс nfqws2. Эта задача решается в Linux с помощью iptables и nftables, в BSD - ipfw и pf, в Windows - windivert. Процесс перенаправления трафика из ядра отнимает достаточно много ресурсов, поэтому лучше всего отфильтровать как можно больше прямо в нем.

Для экспериментов на Linux можно начать со следующих nftables, которые перенаправят начальные пакеты соединений на порты tcp 80,443 и udp 443 в очередь NFQUEUE с номером 200.

nft delete table inet ztest
nft create table inet ztest
nft add chain inet ztest post "{type filter hook postrouting priority 101;}"
nft add rule inet ztest post meta mark and 0x40000000 == 0 tcp dport "{80,443}" ct original packets 1-12 queue num 200 bypass
nft add rule inet ztest post meta mark and 0x40000000 == 0 udp dport "{443}" ct original packets 1-12 queue num 200 bypass

sysctl net.netfilter.nf_conntrack_tcp_be_liberal=1 
nft add chain inet ztest pre "{type filter hook prerouting priority -101;}"
nft add rule inet ztest pre meta mark and 0x40000000 == 0 tcp sport "{80,443}" ct reply packets 1-12 queue num 200 bypass
nft add rule inet ztest pre meta mark and 0x40000000 == 0 udp sport "{443}" ct reply packets 1-12 queue num 200 bypass

nft add chain inet ztest predefrag "{type filter hook output priority -401;}"
nft add rule inet ztest predefrag "mark & 0x40000000 != 0x00000000 notrack"

В windows функция перехвата вшита прямо в код движка для windows, который называется winws2. Он использует драйвер windivert. Для перехвата портов целиком используются параметры --wf-tcp-in, --wf-tcp-out, --wf-udp-in, --wf-udp-out. Они относятся к протоколам tcp или udp, к входящим или исходящим пакетам. Например, --wf-tcp-out=80,443. Для более точного перехвата пишутся фильтры на языке фильтров windivert. Он похож на язык фильтров tcpdump или wireshark. Фильтры отдаются winws2 в параметрах --wf-raw-part. Конструктор фильтров обьединяет все указанные опции перехвата в единый raw фильтр и запускает перехват windivert.

К сожалению, самый болезненный недостаток windivert (а так же BSD ipfw и pf) - отсутствие ограничителя на номер пакета в соединении (connbytes в iptables, ct packets в nftables). windivert вообще не отслеживает соединения. Поэтому если перехватывать порт целиком, то все соединение по указанному направлению пойдет на перехват, что нелегко для процессора, если там передаются многие мегабайты. Поэтому по возможности пишите собственные фильтры windivert, проверяющие тип пейлоада хотя бы частично. Дофильтрацию может выполнить winws2.

Дальше под рутом нужно запустить nfqws2 с параметрами командной строки. Они строятся примерно следующим образом :

nfqws2 --qnum=200 --debug [email protected] [email protected] \
  --filter-tcp=80,443 --filter-l7=tls,http \
  --payload=tls_client_hello --lua-desync=fake:blob=fake_default_tls:tcp_md5:tls_mod=rnd,rndsni,dupsid \
  --payload=http_req --lua-desync=fake:blob=fake_default_http:tcp_md5 \
  --payload=tls_client_hello,http_req --lua-desync=multisplit:pos=1:seqovl=5:seqovl_pattern=0x1603030000

Данный пример предполагает, что в той же директории находятся файлы zapret-lib.lua - библиотека хелперов на Lua и zapret-antidpi.lua - библиотека базовых стратегий. --lua-init может содержать Lua код в виде строки. Так удобно писать простой код, например присвоить константу переменной, чтобы не создавать файлы ради этой мелочи. Либо подцепляется файл, если значение параметра начинается с @. Код из --lua-init выполняется 1 раз при старте.

Далее указаны параметры --lua-desync. Они содержат имя Lua функции, вызываемой при обработке каждого пакета, проходящего через профиль мультистратегии. После двоеточия и через двоеточия следуют параметры для данной функции в формате param[=value]. В примере реализована стратегия

nfqws --qnum=200 --debug \
--filter-tcp=80,443 --filter-l7=tls,http \
 --dpi-desync=fake,multisplit --dpi-desync-fooling=md5sig --dpi-desync-split-pos=1,midsld \
 --dpi-desync-split-seqovl=5 --dpi-desync-split-seqovl-pattern=0x1603030000 \
 --dpi-desync-fake-tls-mod=rnd,rndsni,dupsid

Что сразу заметно - это наличие понятия "payload". В nfqws1 были только протоколы соединения, которые участвовали в фильтрации профилей. Они так же остались в nfqws2, но введено другое понятие - тип пейлоада. Пейлоад - это содержание текущего пакета. Тип пейлоада - тип данных, содержащихся в пакете или группе пакетов. Например, протокол соединения может быть tls, а пейлоады - tls_client_hello, tls_server_hello, unknown.

Другое важное отличие - отсутствие жестко определенных фаз десинхронизации. То, что вы раньше писали как fake,multisplit реализуется двумя последовательно вызываемыми Lua функциями. Их может быть столько, сколько нужно, учитывая логику прохождения пакетов и операций с ними, и у каждой могут быть свои параметры. Может даже несколько раз вызываться одна и так же функция с разными параметрами. Так, например, можно послать несколько фейков, причем с разными фулингами. Конкретный вызов --lua-desync функции называется инстансом. Инстанс - это связка имени функции, номера вызова внутри профиля и номера самого профиля. Это похоже на одну программу, которую можно запустить много раз с разными параметрами.

Другое немаловажное отличие - поддержка автоматической tcp сегментации средствами zapret-lib.lua. Вам больше не нужно думать о размерах отсылаемых tcp пакетов. По каждому соединению отслеживается MSS. Если пакет не влезает в MSS, выполняется сегментация. Например, это может случиться при отправке tls фейка с kyber. Или если вы режете kyber tls так, что одна из частей получается размером 1600 байт, что, очевидно, не влезает в MTU. Или если вы задали seqovl=10000. В nfqws1 такое значение вызвало бы ошибку. Функция Lua rawsend_dissect_segmented отправит несколько tcp сегментов с начальным sequence -10000 общим размером 10000 байт, в последнем из которых будет кусок оригинального сообщения.

В nfqws2 нет жестко зашитых параметров кастомных фейков типа --dpi-desync-fake-tls, dpi-desync-fake-http и тд. Вместо них есть блобы. Блоб (blob) - это переменная Lua типа string, содержащая блок двоичных данных произвольной длины. От 1 байта до гигабайтов. nfqws2 автоматически инициализирует блобы со стандартными фейками tls, http, quic, как это и было в nfqws1. Блобы могут быть заданы как hex-строка прямо в параметре desync функции, либо пред-загружены при старте с помощью параметра --blob=name:0xHEX|[+ofs]@filename

Что касается профилей мультистратегии и хостлистов , то они остались практически в неизменном виде. За исключением одной тонкости автолиста. Теперь профиль с автолистом берет на себя только те соединения, для которых уже известен хост. Пока хоста нет - они проходят мимо. В nfqws1 они падали на профиль с автолистом.

nfqws2 --qnum=200 --debug [email protected] [email protected] \
--filter-tcp=80 --filter-l7=http --hostlist=mylist1.txt --lua-desync=multisplit --new \
--filter-tcp=80 --filter-l7=http --hostlist-exclude=mylist2.txt --lua-desync=fake:blob=0x00000000:ip_ttl=5:ip6_ttl=3 --lua-desync=multidisorder:pos=5,endhost-1 --new \
--filter-tcp=443 --filter-l7=tls --hostlist=mylist1.txt --lua-desync=multidisorder

Параметры nfqws1 start/cutoff (--dpi-desync-start, --dpi-desync-cutoff, ...) теперь называются диапазонами (ranges). Остались только 2 range : --in-range и --out-range. Они относятся к входящему и исходящему направлению соответственно. Да, теперь можно полноценно работать как с входящими пакетами, так и с исходящими. Есть и специальный режим для сервера - --server, который адаптирует интерпретацию IP адресов и портов источника/приемника, чтобы корректно работали ipset-ы и фильтры.

range задается как mX-mY, mX<mY, -mY, <mY, mX-. Буква m означает режим счетчика. n - номер пакета, d - номер пакета с данными, b - количество переданных байт, s - относительный sequence для tcp. После буквы режима пишется число. Например, n5-s10000 означает с 5-го по очереди пакета до смещения 10000 байт относительно начала tcp соединения. Есть и режимы, не требущие числа - a - всегда, x - никогда. Если разделителем указан знак '-' - конечная позиция включительна, а если '<' - не включительна.

Установка по умолчанию --in-range=x --out-range=a --payload=all. То есть отсекаются все входящие пакеты и берутся все исходящие.

--in-range, --out-range и --payload фильтры могут присутствовать множественно в �

zapret2 (bol-van/zapret2)

Searching Database…

5.7K ·GitHub
这是什么?一款自主运行的抗 DPI 工具,能够实时修改流量,让 DPI 系统无法识别或限速它。它可以帮助绕过对 HTTP(S) 网站的封锁或降速,以及用于封禁 VPN 的基于签名的 TCP/UDP 流量分析——全程不依赖任何第三方服务器。
它是一个我直接运行的程序,还是我写代码调用的库?是一个可以直接运行的程序:nfqws2 是一个命令行工具,以 root 身份带命令行参数启动,其行为由 Lua 脚本控制。Windows 引擎版本叫做 winws2。
我怎么把它跑起来?先从源码构建(仓库里有 Makefile),然后在内核层把流量重定向给它——Linux 上通过 nftables 或 iptables 的 NFQUEUE,BSD 上用 ipfw 或 pf,Windows 上用 windivert——最后以 root 身份运行 nfqws2,用 --lua-desync 参数指向自带的策略文件。
运行时它还需要搭配其他东西吗?不需要任何外部服务——它完全独立运行。不过 nfqws2 要求 Lua 文件和可执行文件放在一起:zapret-lib.lua(辅助库)和 zapret-antidpi.lua(基础策略),另外还需要操作系统层面的流量重定向(nftables、pf/ipfw 或 windivert)。
我得是网络专家才能用它吗?基本上是的:它是为懂得数据包、DPI 弱点和基础编程的爱好者打造的。作者明确表示它不是面向小白的开箱即用方案,而且做一个对所有人都简单的方案在原理上就是不可能的。
它能在哪些系统上运行?它首先面向低功耗嵌入式设备——OpenWrt 路由器——但也能在普通 Linux、FreeBSD、OpenBSD 和 Windows 上运行。由于技术原因,macOS 不受支持,将来也几乎不可能支持。
和原来的 zapret(nfqws1)相比有什么新东西?在 nfqws1 中,攻击场景是硬编码在 C 代码里的,工具被大量选项塞得臃肿不堪。nfqws2 把攻击逻辑移到了 Lua 策略中:C 核心保留协议识别、重组、解密、配置文件和 hostlist 功能,而 Lua 代码会收到类似 wireshark 的数据包解析结果——现成的策略库以更灵活的形式复现了 nfqws1 的功能。
我必须从零开始自己写 Lua 攻击策略吗?不用。nfqws2 自带 zapret-antidpi.lua,这是一套现成的 DPI 攻击策略库,以扩展且更灵活的形式实现了 nfqws1 的功能,还附带 zapret-lib.lua 辅助库。你可以从它们入手,在其基础上修改或添加自己的 Lua 代码。
除了对抗 DPI,它还能干别的吗?可以:作者把它描述为一个多平台可编程的数据包操控工具。除了对抗 DPI,你还可以生成任意的 IPv4/IPv6 流量,对现有流量进行混淆或加密,在 IP 网络上构建非标准协议,甚至实现自己的防火墙或 DPI 系统。
拦截流量的时候性能会有损失吗?在 Windows 上,windivert(以及 BSD 的 ipfw/pf)没有类似 Linux connbytes 那样的按连接数据包数限制,所以拦截整个端口会把每条连接的每个数据包都送进工具处理——当流量达到兆级别时 CPU 压力很大。可以编写 windivert 的 payload 过滤器来缩小抓包范围,winws2 会对其余流量做预过滤。
Creator
bol-van
Size
2.3 MB
Stars
5.7K
Age
10mo
Commits · 90 Days