В запрет 2 (потому что он крутой) добавлена маскировка UDP‑трафика под ICMP‑пинги, чтобы WireGuard (который обычно ходит по UDP) продолжал работать там, где UDP режут/ломают, но ICMP ещё проходит
WireGuard думает, что шлёт/получает обычные UDP пакеты на 1.2.3.4:5555.
Но специальная программа перехватывает эти UDP пакеты до выхода в сеть и упаковывает их внутрь ICMP Echo (ping) пакетов.
На другой стороне другая программа делает обратное: из ICMP достаёт исходный UDP и “скармливает” его WireGuard’у.
В сети видно сплошные пинги, а внутри них на самом деле едет WG‑трафик.
WireGuard думает, что шлёт/получает обычные UDP пакеты на 1.2.3.4:5555.
Но специальная программа перехватывает эти UDP пакеты до выхода в сеть и упаковывает их внутрь ICMP Echo (ping) пакетов.
На другой стороне другая программа делает обратное: из ICMP достаёт исходный UDP и “скармливает” его WireGuard’у.
В сети видно сплошные пинги, а внутри них на самом деле едет WG‑трафик.
❤5🔥2
🧻 @loop_uh | Канал для умных манулов
В запрет 2 (потому что он крутой) добавлена маскировка UDP‑трафика под ICMP‑пинги, чтобы WireGuard (который обычно ходит по UDP) продолжал работать там, где UDP режут/ломают, но ICMP ещё проходит WireGuard думает, что шлёт/получает обычные UDP пакеты на 1.2.3.4:5555.…
У ICMP Echo есть поля type и code
type 8 = echo request (обычный ping запрос)
type 0 = echo reply (ответ)
code 199 в коде выбран как метка, чтобы:
— отличать эти служебные пинги с данными от обычных пингов
— можно было фильтровать в ядре и не грузить обработкой всё подряд.
Пример
type 8 = echo request (обычный ping запрос)
type 0 = echo reply (ответ)
code 199 в коде выбран как метка, чтобы:
— отличать эти служебные пинги с данными от обычных пингов
— можно было фильтровать в ядре и не грузить обработкой всё подряд.
Пример
--wf-raw-filter="ip.SrcAddr=1.2.3.4 or ip.DstAddr=1.2.3.4" = не трогать вообще весь интернет, а только пакеты, связанные с IP VPS (экономит CPU).
--wf-udp-out=11 = перехватывать исходящий UDP (конкретный смысл “11” зависит от реализации фильтра winws2, но по сути это “включи перехват UDP out”).
--wf-icmp-in=0:199 = перехватывать входящий ICMP type 0 (echo reply) с code 199.
❤1
🧻 @loop_uh | Канал для умных манулов
У ICMP Echo есть поля type и code type 8 = echo request (обычный ping запрос) type 0 = echo reply (ответ) code 199 в коде выбран как метка, чтобы: — отличать эти служебные пинги с данными от обычных пингов — можно было фильтровать в ядре и не грузить обработкой…
Из плюсов — нативно в конфигах менять ничего не надо - wireguard будет думать, что он работает по udp, но на самом деле он преобразуется в пинги icmp, которые могут проходить NAT. Размер пакетов не изменяется, потому проблемы MTU нет.
🧻 @loop_uh | Канал для умных манулов
У ICMP Echo есть поля type и code type 8 = echo request (обычный ping запрос) type 0 = echo reply (ответ) code 199 в коде выбран как метка, чтобы: — отличать эти служебные пинги с данными от обычных пингов — можно было фильтровать в ядре и не грузить обработкой…
Полный пример
table ip ztest {
chain post {
type filter hook output priority mangle; policy accept;
meta mark & 0x40000000 == 0x00000000 udp sport 5555 queue flags bypass to 200
}
chain pre {
type filter hook input priority mangle; policy accept;
meta mark & 0x40000000 == 0x00000000 icmp type echo-request icmp code 199 queue flags bypass to 200
}
}nfqws2 --qnum 200 --server
--lua-init=@/opt/zapret2/lua/zapret-lib.lua
--lua-init=@/opt/zapret2/lua/zapret-obfs.lua
--in-range=a
--lua-desync=udp2icmp:ccode=199:scode=199
winws2
--wf-icmp-in=0:199 --wf-udp-out=5555
--wf-raw-filter="ip.SrcAddr=1.2.3.4 or ip.DstAddr=1.2.3.4"
--lua-init=@lua/zapret-lib.lua
--lua-init=@lua/zapret-obfs.lua
--in-range=a
--lua-desync=udp2icmp:ccode=199:scode=199
--dpi-desync-fake-tls-mod недописана до конца, из-за этого многие alt не работали так как в zapret1
❤4
18 января у запрета было ДР но я его не отметил(
💔19🎉2🥰1
Forwarded from Censorliber (⛔️ личку не читаю не пишите, отмечайте в чате!)
Делаю сто тыщ режимов
Forwarded from Censorliber (⛔️ личку не читаю не пишите, отмечайте в чате!)
Пусть каждый выбирает в меру своец испорченности
😁4
Развиваем обходы дальше
Идея сделать TCP‑соединение так, чтобы DPI не увидел классический SYN→SYN/ACK→ACK хэндшейк, потому что многие DPI начинают вести сессию именно с SYN. Если SYN не было — DPI может не привязать дальнейшие пакеты к TCP‑сеансу (или будет хуже распознавать протокол).
🔓 Пробить дырку в NAT SYN’ом с low TTL
- Домашний/локальный NAT (роутер) обычно создаёт состояние/маппинг, когда видит исходящий SYN.
- Если поставить маленький TTL, SYN:
- успеет выйти через NAT и создать запись,
- но умрёт по TTL раньше, чем дойдёт до DPI (если DPI дальше по трассе).
- В итоге NAT “готов”, но DPI SYN не видел.
Важно: это зависит от топологии. Если DPI стоит сразу за NAT (первый хоп у провайдера), TTL‑трюк может не помочь.
🔓 Убираем SYN, ставим магию
Следующий реальный “первый пакет” к серверу отправляется без флага SYN, но в нём прячется маркер (“магия”), чтобы удалённая сторона поняла: “это на самом деле замаскированный SYN”.
Варианты “магии”, которые перечислены:
- urgent pointer / флаг URG,
- reserved TCP flags (нестандартные биты),
- “левый” TCP option,
- tsecr (поле TCP timestamp echo reply).
Зачем: DPI часто смотрит на флаги/опции и решает, это SYN/хэндшейк или уже “данные в установленном соединении”.
🔓 Почему на Linux+NAT проблема: conntrack
Linux conntrack (stateful tracking в ядре) считает пакеты без SYN в начале потока “invalid” и может их выкинуть/не натить нормально.
И вот трюк, который описан:
- Если такой “инвалидный” пакет прогнать через NFQUEUE в postrouting/postnat (после NAT‑решений), и user-space вернёт VERDICT_PASS/ACCEPT, то дальше пакет часто проходит, потому что после verdict ядро уже не делает ту же строгую “проверку валидности” conntrack’ом. Это особенность/побочный эффект пайплайна.
Именно поэтому нужен любой хэндлер, лишь бы выдал VERDICT_PASS (можно даже nfqws2 без обфускации).
🔓 Что делает сервер
Сервер получает изуродованный пакет (без SYN, но с магией):
- перехватывает его до TCP‑стека (через NFQUEUE/WinDivert/и т.п.),
- узнаёт магию,
Аналогично в обратную сторону:
- SYN/ACK от сервера тоже маскируется магией и отправляется клиенту без SYN,
- клиент снимает магию и восстанавливает SYN/ACK (или эквивалентно инициирует нужную реакцию).
🔓 cutoff — mission complete
Как только реальный TCP сеанс в ядрах обеих сторон поднят (хэндшейк завершён), обфускатор больше не нужен:
- он перестаёт трогать этот поток (cutoff), чтобы не тащить весь TCP через user-space.
🔓 Почему не использует conntrack и почему это больно с правилами
На сервере обычный conntrack может не сработать, потому что классического SYN он не видел (вы сами его спрятали). Поэтому:
- нельзя удобно использовать connbytes/ct state для “первых N пакетов”;
- приходится матчить по признакам самого пакета (флаги/опции/маркер), по 5‑tuple (src/dst ip+port) и/или вести учёт в user-space.
Идея сделать TCP‑соединение так, чтобы DPI не увидел классический SYN→SYN/ACK→ACK хэндшейк, потому что многие DPI начинают вести сессию именно с SYN. Если SYN не было — DPI может не привязать дальнейшие пакеты к TCP‑сеансу (или будет хуже распознавать протокол).
- Домашний/локальный NAT (роутер) обычно создаёт состояние/маппинг, когда видит исходящий SYN.
- Если поставить маленький TTL, SYN:
- успеет выйти через NAT и создать запись,
- но умрёт по TTL раньше, чем дойдёт до DPI (если DPI дальше по трассе).
- В итоге NAT “готов”, но DPI SYN не видел.
Важно: это зависит от топологии. Если DPI стоит сразу за NAT (первый хоп у провайдера), TTL‑трюк может не помочь.
Следующий реальный “первый пакет” к серверу отправляется без флага SYN, но в нём прячется маркер (“магия”), чтобы удалённая сторона поняла: “это на самом деле замаскированный SYN”.
Варианты “магии”, которые перечислены:
- urgent pointer / флаг URG,
- reserved TCP flags (нестандартные биты),
- “левый” TCP option,
- tsecr (поле TCP timestamp echo reply).
Зачем: DPI часто смотрит на флаги/опции и решает, это SYN/хэндшейк или уже “данные в установленном соединении”.
Linux conntrack (stateful tracking в ядре) считает пакеты без SYN в начале потока “invalid” и может их выкинуть/не натить нормально.
И вот трюк, который описан:
- Если такой “инвалидный” пакет прогнать через NFQUEUE в postrouting/postnat (после NAT‑решений), и user-space вернёт VERDICT_PASS/ACCEPT, то дальше пакет часто проходит, потому что после verdict ядро уже не делает ту же строгую “проверку валидности” conntrack’ом. Это особенность/побочный эффект пайплайна.
Именно поэтому нужен любой хэндлер, лишь бы выдал VERDICT_PASS (можно даже nfqws2 без обфускации).
Сервер получает изуродованный пакет (без SYN, но с магией):
- перехватывает его до TCP‑стека (через NFQUEUE/WinDivert/и т.п.),
- узнаёт магию,
Аналогично в обратную сторону:
- SYN/ACK от сервера тоже маскируется магией и отправляется клиенту без SYN,
- клиент снимает магию и восстанавливает SYN/ACK (или эквивалентно инициирует нужную реакцию).
Как только реальный TCP сеанс в ядрах обеих сторон поднят (хэндшейк завершён), обфускатор больше не нужен:
- он перестаёт трогать этот поток (cutoff), чтобы не тащить весь TCP через user-space.
На сервере обычный conntrack может не сработать, потому что классического SYN он не видел (вы сами его спрятали). Поэтому:
- нельзя удобно использовать connbytes/ct state для “первых N пакетов”;
- приходится матчить по признакам самого пакета (флаги/опции/маркер), по 5‑tuple (src/dst ip+port) и/или вести учёт в user-space.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
🧻 @loop_uh | Канал для умных манулов
Развиваем обходы дальше Идея сделать TCP‑соединение так, чтобы DPI не увидел классический SYN→SYN/ACK→ACK хэндшейк, потому что многие DPI начинают вести сессию именно с SYN. Если SYN не было — DPI может не привязать дальнейшие пакеты к TCP‑сеансу (или будет…
Практический вывод про правила перехвата (самая важная мысль):
- В ядре отбирать только:
- SYN с low TTL (один пакет),
- магические пакеты (первые 1–3 пакета),
- ответы с магией,
- а остальное пропускать мимо NFQUEUE.
- В ядре отбирать только:
- SYN с low TTL (один пакет),
- магические пакеты (первые 1–3 пакета),
- ответы с магией,
- а остальное пропускать мимо NFQUEUE.
Сейчас возникает несколько вопросов:
Внутренний conntrack (и логика вокруг него) стартует только от SYN/SYN‑ACK. Если начинать поток без SYN, то запрет этот пакет сейчас не увидит.
Многие серверные TCP не принимают магические пакеты как handshake и толку это дурить тогда.
А DPI попросту могут резать странные флаги/опции.
К тому же это получается вместо ОС сам запрет должен быть TCP стеком.
Внутренний conntrack (и логика вокруг него) стартует только от SYN/SYN‑ACK. Если начинать поток без SYN, то запрет этот пакет сейчас не увидит.
Многие серверные TCP не принимают магические пакеты как handshake и толку это дурить тогда.
А DPI попросту могут резать странные флаги/опции.
К тому же это получается вместо ОС сам запрет должен быть TCP стеком.
👍2❤1
Оказывается данный механизм уже реализован в synhide в zapret-obfs.lua
Немного удалось ускорить обработку большого потока пакетов на windivert за счет bulk mode.
В bulk mode windivert может выдать за 1 обращение в ядро сразу множество пакетов, если они идут пачкой. Буфер выставлен в 192K при макс количестве пакетов 128. Как раз по 1500.
Тестировалось через iperf на loopback. Без bulk - 17.4G, c bulk - 18.6G
Проц не требует митигации от meltdown, выигрыш 7%., учитывая, что по лупбэку идут пакеты 64K, их помещается только 3.
На виртуалке linux через host only network прирост около 30-40%. Там идут стандартные мелкие пакеты.
Если включена митигация от meltdown, скорее всего выигрыш будет еще больше, тк syscall-ы дороже.
Если все упирается не в процессор, а в скорость сети, то профит будет не в возрастании скорости, а в уменьшении cpu usage
Потенциально может быть минорное замедление на arm64 при процессинге пакетов за счет отсутствия alignment в буфере windivert - он не выравнивает, сует как есть пакет за пакетом. На x86 должно быть побоку, а на других процах, где без alignment беда, винды и нет
В bulk mode windivert может выдать за 1 обращение в ядро сразу множество пакетов, если они идут пачкой. Буфер выставлен в 192K при макс количестве пакетов 128. Как раз по 1500.
Тестировалось через iperf на loopback. Без bulk - 17.4G, c bulk - 18.6G
Проц не требует митигации от meltdown, выигрыш 7%., учитывая, что по лупбэку идут пакеты 64K, их помещается только 3.
На виртуалке linux через host only network прирост около 30-40%. Там идут стандартные мелкие пакеты.
Если включена митигация от meltdown, скорее всего выигрыш будет еще больше, тк syscall-ы дороже.
Если все упирается не в процессор, а в скорость сети, то профит будет не в возрастании скорости, а в уменьшении cpu usage
Потенциально может быть минорное замедление на arm64 при процессинге пакетов за счет отсутствия alignment в буфере windivert - он не выравнивает, сует как есть пакет за пакетом. На x86 должно быть побоку, а на других процах, где без alignment беда, винды и нет
❤4
Появилась идея аналогичным образом расширить оркестраторный запрет 2 через пресеты
И сразу запихнуть пресет с несколькими стратегиями для пущей убедительности
И сразу запихнуть пресет с несколькими стратегиями для пущей убедительности
👍9
Вышло обновление ядра программы zapret2 v0.9.0 (предпоследнее бета обновление скорее всего до 1.0.0)
nfqws2: в детекторе http протокола убрана проверка на наличие хедера Host:
nfqws2: при обновлении листа проверка на возможность открытия нового файла. отказ от удаления старой копии из памяти при невозможности
github actions: в платформах без LuaJIT используется Lua 5.5 вместо 5.4
nfqws2: отключение reasm, если сервер выставил window size = 0 (специфические и редкие anti-ddos защиты)
nfqws2: возможность отключения перехвата через --intercept=0. запускаются --lua-init, затем процесс завершается
nfqws2: поддержка icmp и raw ip протоколов
nfqws2: возможность при сборке desync.dis по VERDICT_MODIFY использовать next поля ipv6 - VERDICT_PRESERVE_NEXT
nfqws2: опция реконструкции keepsum - не вычислять и не портить чексуммы tcp,udp,icmp, а использовать указанные значения из полей в заголовках
nfqws2: новые C функции : bor,bxor,band,reconstruct_icmphdr,dissect_icmphdr,csum_icmp_fix,get_source_ip,get_ifaddrs,conntrack_feed
zapret-obfs: обфускаторы ippxor, udp2icmp, synhide
nfqws2: новая версия C-Lua интерфейса LUA_COMPAT_VER=5
winws2: windivert фильтр, обьединяемый по AND : --wf-raw-filter
winws2: использование windivert bulk mode для приема пачки пакетов за 1 вызов. значительное ускорение на сплошном потоке
winws2: заменена иконка на другую с png и большими разрешениями. в коде - явная установка иконки консольного окна, чтобы система не ресайзила в 16x16
nfqws2: свободное и можественное использование --import - без затирания профиля/шаблона назначения копируются только установленные простые значения, а списочные добавляются к списку
множественные AI фиксы
nfqws2: в детекторе http протокола убрана проверка на наличие хедера Host:
nfqws2: при обновлении листа проверка на возможность открытия нового файла. отказ от удаления старой копии из памяти при невозможности
github actions: в платформах без LuaJIT используется Lua 5.5 вместо 5.4
nfqws2: отключение reasm, если сервер выставил window size = 0 (специфические и редкие anti-ddos защиты)
nfqws2: возможность отключения перехвата через --intercept=0. запускаются --lua-init, затем процесс завершается
nfqws2: поддержка icmp и raw ip протоколов
nfqws2: возможность при сборке desync.dis по VERDICT_MODIFY использовать next поля ipv6 - VERDICT_PRESERVE_NEXT
nfqws2: опция реконструкции keepsum - не вычислять и не портить чексуммы tcp,udp,icmp, а использовать указанные значения из полей в заголовках
nfqws2: новые C функции : bor,bxor,band,reconstruct_icmphdr,dissect_icmphdr,csum_icmp_fix,get_source_ip,get_ifaddrs,conntrack_feed
zapret-obfs: обфускаторы ippxor, udp2icmp, synhide
nfqws2: новая версия C-Lua интерфейса LUA_COMPAT_VER=5
winws2: windivert фильтр, обьединяемый по AND : --wf-raw-filter
winws2: использование windivert bulk mode для приема пачки пакетов за 1 вызов. значительное ускорение на сплошном потоке
winws2: заменена иконка на другую с png и большими разрешениями. в коде - явная установка иконки консольного окна, чтобы система не ресайзила в 16x16
nfqws2: свободное и можественное использование --import - без затирания профиля/шаблона назначения копируются только установленные простые значения, а списочные добавляются к списку
множественные AI фиксы
❤7🤔1