Продвинутое
Справочник
Формат аргументов winws2: всё, что нужно, чтобы написать свою стратегию и не наткнуться на «зелено, но не работает».
Свою стратегию можно создать на вкладке «Стратегии»: продублировать встроенную и отредактировать
копию. Сохраняется она в presets.json. Проверить получившуюся командную строку целиком,
не запуская движок, помогает предпросмотр команды в интерфейсе.
Здесь собраны практические правила, проверенные на движке, который поставляется с программой. Исчерпывающий первоисточник по всем возможностям: официальный мануал zapret2, на английском.
Структура команды
Команда состоит из глобальной части и одного или нескольких профилей. Каждый
следующий профиль начинается с --new.
# глобальная часть: ширина перехвата, блобы, кэш
--wf-tcp-out=80,443-65535
--blob=tls_google:@{FILES}\fake\tls_clienthello_www_google_com.bin
# первый профиль идёт сразу, без --new
--filter-tcp=443-65535 --filter-l7=tls {HOSTLIST:discord}
--payload=tls_client_hello
--lua-desync=fake:blob=tls_google:tcp_ts=-1000:repeats=6
--new
# второй профиль
--filter-udp=443-65535 --filter-l7=quic {HOSTLIST:discord}
--payload=quic_initial
--lua-desync=fake:blob=quic_google:repeats=11
- Глобальная часть идёт до первого
--newи содержит--wf-*,--blob=,--ipcache-*,--lua-init=. Первый профиль живёт там же. - Порты перехвата перечисляются через запятую в одном флаге. Второй
--wf-tcp-outне добавит порты, а перезапишет предыдущий. - Профиль отвечает на два вопроса: к кому применяться (фильтры) и что делать
(
--lua-desync). Приёмов в профиле может быть несколько, они выполняются по порядку.
Липкие флаги
Три флага действуют с места указания и до переопределения, а не на весь профиль. Это самая частая причина стратегий, которые выглядят правильно, но ведут себя не так.
| Флаг | Что задаёт |
|---|---|
--payload= | Какой пакет считается целевым: tls_client_hello, quic_initial и другие. |
--out-range= | Диапазон исходящих пакетов, к которым применяется приём. Например -d10. |
--in-range= | То же для входящих. Нужен оркестраторам, чтобы видеть сбросы от DPI. |
Ставьте их перед тем --lua-desync, на который они влияют. Если поставить
после, приём отработает с прежними значениями. Ошибки при этом не будет: движок запустится, а
обход просто не сработает.
Флаги --filter-*, --hostlist и --ipset липкими не являются,
их порядок внутри профиля значения не имеет.
Фильтры профиля
| Флаг | Значение |
|---|---|
--filter-tcp= | Порты TCP, например 443-65535. |
--filter-udp= | Порты UDP, например 19294-19344,50000-65535. |
--filter-l7= | Протокол: tls, quic, http, discord, stun. Можно перечислить несколько через запятую. |
--hostlist= | Применять только к доменам из файла. |
--hostlist-exclude= | Не применять к доменам из файла. Так защищают банки и госуслуги от профилей, ловящих всё подряд. |
--ipset= | Применять к подсетям из файла. Для случая, когда сервис режут по адресам. |
Токены
Стратегии хранятся не с абсолютными путями, а с токенами. Программа разворачивает их при запуске, подставляя актуальные пути и текущие настройки.
| Токен | Разворачивается в |
|---|---|
{FILES} | Путь к папке engine\files, где лежат блобы. |
{WF} | Путь к папке engine\windivert.filter. |
{WF_TCP} | --wf-tcp-out=80,443-65535: ширина перехвата TCP. |
{WF_UDP} | --wf-udp-out= с 443, STUN и голосом Discord. Игровой фильтр расширяет диапазон. |
{HOSTLIST} | --hostlist= с активным списком, или пусто. |
{HOSTLIST:имя} | --hostlist=lists\имя.txt, или пусто, если файла нет. |
{EXCLUDE:имя} | --hostlist-exclude=lists\имя.txt. |
{IPSET} | --ipset= с собранным списком подсетей Discord, если он есть. |
{IPSET:имя} | --ipset=lists\ipset-имя.txt. |
Пустой токен просто выбрасывается из команды. Например, {HOSTLIST} без активного списка
не оставит после себя ничего.
Глаголы desync
Задаются как --lua-desync=глагол:параметр=значение:.... Самая
важная колонка здесь последняя: она определяет, какой fooling можно использовать, а какой сломает
соединение.
| Глагол | Что делает | Fooling применяется к |
|---|---|---|
fake |
Вставляет фейковый пакет из блоба. | только фейкам, настоящий пакет уходит чистым |
multisplit |
Разрезает настоящий пакет на сегменты. | всем сегментам, включая настоящие |
multidisorder |
Разрезает и отправляет куски в обратном порядке. | всем сегментам |
multidisorder_legacy |
Прежний вариант того же приёма. | всем сегментам |
hostfakesplit |
Режет по маркеру имени и подставляет фальшивое имя такой же длины. Подстраивается под размер пакета. | только фейкам, fooling обязателен |
fakedsplit |
Разрезка со вставкой поддельных сегментов. | только поддельным |
fakeddisorder |
То же с обратным порядком. | только поддельным |
syndata |
Кладёт данные в пакет установки соединения. | ничему разрушающему: tcp_seq, tcp_ack и badsum сломают рукопожатие |
tcpseg |
Один сегмент с перекрытием. Не убирает оригинал, добавляйте следом --lua-desync=drop. |
|
wssize, wsize |
Уменьшают TCP-окно, заставляя сервер дробить ответ. | не применяется |
drop, pass |
Отбросить или пропустить пакет. | не применяется |
Главное правило. В multisplit и multidisorder нельзя класть
tcp_ack, tcp_seq, badsum и битый TTL: они применятся к
настоящим сегментам и сломают соединение. Туда идут только pos, seqovl и
безобидные вроде ip_id. Разрушающий fooling живёт в fake и семействе
faked*.
Общие параметры: repeats=N задаёт число повторов фейка, :optional просит
тихо пропустить приём, если он не применился, вместо того чтобы прерывать обработку.
Fooling
Приёмы, заставляющие фейк не дойти до сервера. Подробнее о том, зачем это нужно: Как это работает.
| Параметр | Механизм | Оговорки |
|---|---|---|
tcp_ts=-N |
Более старая временная метка, пакет отбрасывается по PAWS. | Только отрицательное значение. Нужны включённые TCP timestamps. |
tcp_md5 |
Добавляет опцию MD5-подписи, обычный сервер такой пакет не принимает. | Безопасен за домашним NAT. Хорошая замена badsum. |
tcp_seq=-N |
Сдвигает порядковый номер за пределы окна. | Часть DPI тоже проверяет номера и перестаёт верить фейку. |
badsum |
Портит контрольную сумму. | Часто бесполезен дома: роутер за NAT выбросит пакет раньше DPI. |
ip_autottl, ip6_autottl |
Подбирает TTL так, чтобы пакет истёк между DPI и сервером. | Зависит от маршрута, при смене сети может перестать подходить. |
ip_id=zero |
Обнуляет идентификатор в заголовке IP. | Дополнительный признак, безопасен. |
tls_mod=rnd,rndsni |
Меняет содержимое фейкового приветствия, чтобы оно не повторялось. | Применяется к блобу, а не к настоящему пакету. |
Знак у tcp_ts критичен. PAWS отбрасывает пакет с меньшей меткой. Отрицательное
значение убивает фейк, положительное убивает настоящий пакет. Во втором случае соединение
ломается тихо, и выглядит это как «обход включён, но ничего не открывается».
Кроме того, ts-приёмы бессмысленны без включённых TCP timestamps. Windows держит их в состоянии
allowed, которое не гарантирует наличие метки в исходящих пакетах, поэтому Zapret2UI
переключает их в enabled на время сеанса и возвращает как было при остановке.
Позиционные маркеры
Задают, где резать пакет. Используются в pos= и допускают смещения: sld+1,
midsld-2. Несколько точек разреза перечисляются через запятую.
| Маркер | Куда указывает |
|---|---|
method | Начало метода запроса. |
host | Начало имени сайта. |
endhost | Конец имени сайта. |
sld | Начало домена второго уровня. |
midsld | Середина домена второго уровня. Самый ходовой вариант. |
endsld | Конец домена второго уровня. |
sniext | Начало расширения с именем сайта. |
extlen | Поле длины расширения. |
pos=1 сам по себе ничего не делает. Движок вырезает эту позицию, и приём
превращается в пустышку. Нужен второй, настоящий маркер: pos=1,midsld.
Про seqovl
Параметр seqovl означает разное у разных глаголов, и это регулярный источник
ошибок.
| Где | Что означает |
|---|---|
multisplit |
Число байт: сколько байт содержимого дописать внахлёст к началу настоящего пакета. Значения бывают большими, вроде 681. |
multidisorder |
Позиция-маркер, и она должна быть меньше первой точки разреза. |
Параметр seqovl_pattern= указывает, чем именно заполнять перекрытие. Осмысленно
подставлять туда настоящий ClientHello, например tls_google: правдоподобное начало
переживает проверки, которые случайный мусор не проходит.
Блобы
Блоб: файл с готовым сетевым пакетом, который используется как фейк. Сначала ему дают имя в глобальной части, потом обращаются по имени.
--blob=tls_google:@{FILES}\fake\tls_clienthello_www_google_com.bin
...
--lua-desync=fake:blob=tls_google:repeats=6
В комплекте с движком идут приветствия от www.google.com, vk.com,
sberbank.ru, gosuslugi.ru, а также их варианты для QUIC. В стратегиях они
доступны как tls_google, tls_vk, tls_sber,
tls_gos, quic_google, quic_vk.
Имена вроде tls5, tls7, tls1 здесь не существуют.
Они встречаются в чужих сборках, где блобы свои. Если переносите стратегию оттуда, замените любой
такой tlsN на tls_google. Неизвестное имя блоба даст ошибку запуска.
Оркестраторы
Отдельный класс: они не меняют пакеты, а управляют другими приёмами. Живут в библиотеке
zapret-auto.lua, которую движок подгружает автоматически.
| Оркестратор | Что делает |
|---|---|
circular | Перебирает варианты по кругу, переключаясь при провале. |
repeater | Повторяет приём. |
stopif | Прерывает цепочку по условию. |
condition | Применяет приём по условию. |
Самый полезный из них circular. Правила такие:
- Объявляется как
--lua-desync=circular:fails=N:time=T, дальше идут варианты. - Каждый приём помечается тегом
strategy=K. Нумерация начинается с единицы и идёт без пропусков. В один вариант может входить несколько приёмов. - Требует
--in-range=: без кэша входящих пакетов детектор не увидит сброс от DPI, и переключаться будет нечему. - Без пометки
finalварианты крутятся по кругу, пока не найдётся рабочий. Найденный больше не трогается, движок при этом не перезапускается.
Готовый рабочий пример разобран в разборе адаптивной стратегии.
Полный пример
Минимальная работающая стратегия под Discord: TLS с фейком и разрезкой, QUIC с фейком, голос.
{WF_TCP}
{WF_UDP}
--ipcache-hostname=1
--blob=tls_google:@{FILES}\fake\tls_clienthello_www_google_com.bin
--blob=quic_google:@{FILES}\fake\quic_initial_www_google_com.bin
--wf-raw-part=@{WF}\windivert_part.stun.txt
--wf-raw-part=@{WF}\windivert_part.quic_initial_ietf.txt
# 1. Discord по TLS
--filter-tcp=443-65535 --filter-l7=tls {HOSTLIST:discord}
--out-range=-d10 --payload=tls_client_hello
--lua-desync=fake:blob=tls_google:tcp_md5:tcp_seq=-10000:repeats=6
--lua-desync=multisplit:pos=1,midsld:seqovl=681:seqovl_pattern=tls_google:optional
--new
# 2. Discord по QUIC: вложения и CDN
--filter-udp=443-65535 --filter-l7=quic {HOSTLIST:discord}
--payload=quic_initial
--lua-desync=fake:blob=quic_google:repeats=11
--new
# 3. Голос
--filter-udp=19294-19344,50000-65535 --filter-l7=discord,stun
--lua-desync=fake:blob=quic_google:repeats=6
Движок запускается только с правами администратора, поэтому единственный настоящий способ проверить стратегию: запустить её. Предпросмотр команды в интерфейсе покажет строку целиком и поможет поймать опечатки заранее.
Частые ошибки
| Симптом | Причина |
|---|---|
| Движок падает с кодом 87 | Недопустимый параметр: опечатка в имени глагола, неизвестное имя блоба или отсутствующая библиотека. В журнале будет строка с подробностью. |
| Обход включён, но ничего не изменилось | Липкий флаг стоит после приёма. Или pos=1 без второго маркера. Или
tcp_ts без включённых timestamps. |
| Соединение полностью ломается | Разрушающий fooling попал в multisplit или multidisorder и
применился к настоящим сегментам. Либо tcp_ts задан положительным. |
| Работает вход, но не работает всё остальное | Захват слишком узкий. Медиа Discord ходит по высоким портам, ловить один 443 недостаточно. |
| Голос не работает ни при какой стратегии | Нет профиля на голосовой диапазон UDP или не подключён windivert_part.stun.txt. |
tcpseg не даёт эффекта |
Он не убирает оригинальный пакет. Нужен следующий приём drop. |