Ты нашёл свежий CVE на периметре клиента. GitHub выдаёт три PoC: две - форки одного Python-скрипта, третий - на Go. Запускаешь первый против лабораторного стенда - сервис уходит в crash loop. Второй не отрабатывает check и молча завершается. Третий собирается, но рассчитан на другую минорную версию. Три PoC, ноль шеллов. Если ты занимался эксплуатацией CVE в пентесте хотя бы полгода - ты знаешь это чувство.
По данным Arctic Wolf, в 2024 году опубликовано 40 289 CVE - рост на 72% относительно 2023-го. Критических и высокоприоритетных стало больше на 13,46%. Среди них - цепочки в Ivanti Connect Secure, Palo Alto PAN-OS и ConnectWise ScreenConnect, которые эксплуатировались задолго до выхода патчей. Для Red Team оператора это непрерывный поток точек входа (T1190, Initial Access) - но только если умеешь превратить сырой PoC в рабочий инструмент, а не просто ронять сервис.
Здесь разбираю полный цикл weaponization: от оценки публичных PoC эксплойтов до интеграции в Metasploit и Sliver C2 фреймворк, стабилизации шелла и обхода EDR после первоначального доступа.
Почему три PoC из четырёх роняют процесс вместо шелла
Публичные PoC эксплойты решают одну задачу - доказать, что уязвимость существует. Не дать стабильный шелл. Не обойти EDR. Не сохранить работоспособность сервиса. Между «уязвимость подтверждена» и «есть контролируемое выполнение кода» - часы, а иногда дни адаптации. И это нормально.Возьмём CVE-2024-3400 - command injection в GlobalProtect компоненте PAN-OS. По NVD: CVSS 10.0 (CRITICAL), вектор AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H. CWE-20 (Improper Input Validation) и CWE-77 (Command Injection). Неаутентифицированный атакующий выполняет произвольный код с root-привилегиями на файрволле. Казалось бы - идеальный кандидат для первоначального доступа Red Team. Бери и заходи.
Но Unit 42 в расследовании Operation MidnightEclipse задокументировало четыре уровня реальной эксплуатации - и картина куда менее радужная:
- Level 0 - проба: попытка не удалась, никакого воздействия на устройство
- Level 1 - тест: создан файл нулевого размера, но команды не выполнены
- Level 2 - потенциальная эксфильтрация:
running_config.xmlскопирован в web-доступную директорию - Level 3 - интерактивный доступ: полноценный шелл с бэкдором
Я сталкивался с похожей ситуацией на нескольких проектах: PoC с GitHub красиво отрабатывает на стенде с точной версией из advisory, а на боевом таргете - тишина или crash. Причины типичные, и стоит разобрать их по отдельности.
Типичные причины, по которым PoC не работает
Жёсткая привязка к версии. Автор PoC проверил эксплойт на одном конкретном билде. Смещения в памяти, адреса гаджетов для ROP-цепочки, размеры структур - всё это плывёт между минорными версиями. PoC для PAN-OS 11.1.2-h1 может молча падать на 11.1.2-h3, потому что Palo Alto перекомпилировала один бинарник с другими флагами оптимизации.Отсутствие стабилизации. Большинство публичных PoC эксплойтов - это proof of concept в буквальном смысле. Автор доказал возможность выполнения кода и на этом остановился. Никакого восстановления потока выполнения после перехвата управления, никакой очистки за собой. Сервис падает - а тебе ещё работать на этом периметре.
Среда выполнения. PoC написан под чистую систему без EDR, без сетевых фильтров, без WAF. На боевом таргете между тобой и уязвимым сервисом может стоять reverse proxy, который режет нестандартные заголовки, или EDR, который убивает
cmd.exe при подозрительном parent process.Неполная эксплуатация. Многие PoC демонстрируют только часть цепочки. Например, для CVE-2024-3400 ранние PoC показывали запись файла (Level 1-2), но не давали выполнение команд (Level 3). Между «записать файл» и «получить шелл» - ещё один этап работы, который автор PoC оставил читателю в качестве домашнего задания.
Оценка PoC: что проверять перед запуском
Прежде чем тянуть PoC с GitHub и запускать его даже на стенде, стоит потратить 15-20 минут на оценку. У меня сложился простой чеклист, который экономит часы отладки.Репутация источника
Первое - кто автор. PoC от исследователя с историей публикаций (Project Zero, ZDI, или хотя бы профиль с другими рабочими эксплойтами) - это одно. Форк форка с двумя звёздами и коммитом «fix typo» - совсем другое. На одном проекте коллега запустил такой «PoC» и получил reverse shell к автору скрипта вместо таргета. Классика supply chain в мире эксплойтов.Проверяй исходник глазами. Если PoC обфусцирован или тянет зависимости с левых URL - это не PoC, это малварь.
Соответствие версии
Смотри, для какой точной версии написан эксплойт. Не «PAN-OS 11.x», а конкретный билд. Сравни с тем, что торчит на таргете. Если версии расходятся - готовься адаптировать. Иногда достаточно поменять offset, иногда нужно переписывать всю цепочку.Тип уязвимости vs. тип PoC
Command injection - одно. Memory corruption - другое. Для command injection PoC обычно переносится между версиями легче (если точка инъекции не изменилась). Для heap overflow или use-after-free - каждый билд может требовать пересчёта heap layout.Что PoC реально делает
Читай код, не только README. Многие PoC заявляют «RCE», а по факту делаютtouch /tmp/pwned. Между записью файла и выполнением произвольного кода - пропасть. Определи, на каком уровне (вспоминаем Level 0-3 от Unit 42) находится конкретный PoC, и сколько работы нужно, чтобы довести его до шелла.Weaponization: от сырого PoC к стабильному эксплойту
Допустим, PoC прошёл оценку и на стенде хотя бы частично отрабатывает. Дальше начинается собственно weaponization - превращение proof of concept в инструмент, которым можно пользоваться в бою.Стабилизация эксплойта
Первый шаг - сделать так, чтобы эксплойт не ронял сервис. Для memory corruption уязвимостей это означает восстановление потока выполнения после перехвата управления. Для command injection - использование техник, которые не оставляют процесс в не согласованном виде.На практике это часто означает замену грубого
system("bash -i >& /dev/tcp/...") на что-то более аккуратное. Например, запись шелл-кода в файл через уязвимость и его выполнение через легитимный механизм (cron, systemd timer, at job). Да, медленнее. Зато сервис продолжает работать, а у тебя есть стабильный callback.Обход EDR на этапе первоначального доступа
EDR на периметре - уже не редкость. CrowdStrike, SentinelOne, Defender for Endpoint - всё это может стоять на хосте за уязвимым сервисом. И если твой эксплойт порождаетcmd.exe от имени httpd - алерт прилетит раньше, чем ты увидишь шелл.Несколько приёмов, которые работают (на момент написания - EDR тоже не стоят на месте):
Вместо порождения нового процесса - инъекция в существующий. Если уязвимость даёт запись в память или выполнение кода в контексте процесса, используй это. Shellcode, который живёт в памяти уязвимого процесса и не порождает дочерних - сложнее для детекта.
Для command injection - избегай очевидных паттернов.
bash -c, powershell -enc, certutil -urlcache - всё это давно в сигнатурах. Лучше использовать встроенные средства конкретного приложения. PAN-OS, например, содержит Python - и APT-группа за MidnightEclipse это использовала, написав бэкдор UPSTYLE именно на Python, интегрированном в PAN-OS.Интеграция в C2 фреймворк
Отдельный скрипт - это хорошо для проверки на стенде. Для реального проекта нужна интеграция в C2 фреймворк: Metasploit, Sliver, Cobalt Strike, Mythic.Для Metasploit это означает написание модуля с правильным
check методом (который верифицирует уязвимость без эксплуатации), поддержкой нескольких targets (версий), и интеграцией с payload framework. Да, это дополнительная работа. Но потом ты можешь использовать exploit/multi/handler, автоматический роутинг через pivots, и весь остальной арсенал MSF.Для Sliver - генерация implant под целевую платформу и доставка через эксплойт. Sliver даёт больше гибкости с протоколами коммуникации (mTLS, WireGuard, DNS, HTTP/S), что помогает при обходе сетевых фильтров на периметре.
Я предпочитаю Sliver для внешних операций - меньше сигнатур по сравнению с Cobalt Strike, нативная поддержка кросс-компиляции, и бесплатный. Metasploit оставляю для этапа разработки и тестирования эксплойта, а финальную доставку делаю через Sliver.
Пример: адаптация PoC для CVE-2024-3400
Вернёмся к PAN-OS. Публичные PoC для CVE-2024-3400 к моменту массовой эксплуатации делали следующее: отправляли crafted HTTP-запрос с path traversal в cookieSESSID, который создавал файл в произвольной директории. Это Level 1 по классификации Unit 42.
🔓 Эксклюзивный контент для зарегистрированных пользователей.
Чтобы довести до Level 3 (шелл), нужно:
- Через path traversal записать cron job или модифицировать существующий скрипт в
/etc/cron.d/ - Cron выполняет payload - reverse shell или загрузку implant
- Implant коннектится к C2 через HTTPS (порт 443, чтобы не выделяться в трафике файрвола)
Пост-эксплуатация: первые 60 секунд после шелла
Шелл получен. Часы тикают. EDR может среагировать на аномальное поведение процесса, SOC может заметить алерт, а сервис может перезапуститься по watchdog. Первые 60 секунд критичны.
Ситуационная осведомлённость. Прежде чем делать что-либо - пойми, где ты. ОС, привилегии, сетевое окружение, наличие EDR. На Linux:
id, uname -a, ps aux | grep -i edr, ls /opt/. На PAN-OS (или другом appliance) - набор команд будет специфичным для платформы.Персистенс. Если шелл нестабилен (а после эксплуатации CVE он часто нестабилен), первое действие - закрепиться. Не через тот же вектор (уязвимость могут пропатчить), а через независимый механизм. SSH-ключ, cron job, модификация легитимного скрипта автозапуска. На appliance типа PAN-OS вариантов меньше, но они есть - тот же UPSTYLE из Operation MidnightEclipse закреплялся через модификацию
logd.Миграция. Если начальный шелл живёт в контексте уязвимого процесса - мигрируй в другой. Процесс может быть перезапущен, обновлён, или просто нестабилен после эксплуатации. Чем быстрее переедешь в стабильный процесс - тем меньше шансов потерять доступ.
Когда НЕ стоит эксплуатировать CVE
Не каждый CVE на периметре стоит эксплуатировать. Звучит странно для статьи про weaponization, но это тот случай, когда «можно» не значит «нужно».Если уязвимость в критичном production-сервисе без возможности быстрого восстановления - подумай дважды. Crash loop на VPN-концентраторе в пятницу вечером - это не тот результат, который клиент ожидает от Red Team. Даже если в scope записано «эксплуатация разрешена».
Если есть менее рискованный вектор (слабые пароли, SSRF через внутренний сервис, фишинг) - часто разумнее зайти через него, а CVE задокументировать как подтверждённую уязвимость без эксплуатации. В отчёте это выглядит так же, а риск для инфраструктуры клиента - ниже.
На одном проекте мы нашли RCE в Exchange (ProxyNotShell, CVE-2022-41082), но рядом торчал Confluence с дефолтными кредами admin:admin. Угадай, через что мы зашли. CVE в Exchange всё равно попал в отчёт как Critical, но ронять почту 500 сотрудникам ради красивого скриншота шелла - так себе идея.
Чеклист weaponization: от PoC до операции
Для тех, кому нужна структура - вот последовательность, которой я придерживаюсь:- Найти и оценить PoC: автор, версия, что реально делает, нет ли закладок
- Развернуть стенд с точной версией таргета (Docker, VM, cloud instance)
- Воспроизвести PoC на стенде, зафиксировать поведение
- Стабилизировать: убрать crash, восстановить поток выполнения
- Заменить payload: вместо
calc.exe/touch /tmp/pwned- реальный implant - Протестировать с EDR на стенде (хотя бы Defender)
- Интегрировать в C2 фреймворк
- Задокументировать: версии, offsets, ограничения, rollback-план
- Согласовать с заказчиком окно эксплуатации
- Выполнить, закрепиться, мигрировать, продолжить операцию
Что дальше
Три PoC с GitHub и ноль шеллов - это не провал, это стартовая точка. Разница между оператором, который умеет только запускать чужие скрипты, и тем, кто стабильно получает доступ через свежие CVE - в этом цикле weaponization. Оценка, адаптация, стабилизация, интеграция в C2, обход EDR.Возьми последний CVE из своего скоупа, который ты отложил со словами «PoC не работает». Разверни стенд, открой PoC в редакторе (не в терминале), и пройди по чеклисту выше. Скорее всего, до шелла - пара часов работы, а не «нерабочий эксплойт».
Вопрос к читателям
Коллеги, кто адаптировал эксплуатацию CVE-2024-3400 до Level 3 на реальном таргете - как решали проблему задержки между записью payload в/etc/cron.d/ и его выполнением? Конкретно интересует: использовали ли вы at-джобы как альтернативу cron для сокращения окна ожидания, или шли через модификацию существующего скрипта в /etc/periodic/? И второй момент - при доставке implant через Sliver с mTLS на порту 443 через GlobalProtect: какой generate-флаг использовали для обхода TLS-инспекции на самом файрволле (--skip-symbols, кастомный C2 profile, или что-то ещё)? Поделитесь конкретной командой sliver-client generate или фрагментом Metasploit-модуля с targets-блоком под разные билды PAN-OS 11.x.
Последнее редактирование модератором: