D2
Администратор
- Регистрация
- 19 Фев 2025
- Сообщения
- 4,380
- Реакции
- 0
Как‑то раз мы проводили разведку по пулу из ~9000 IP-адресов крупной российской IT-компании и нашли заброшенный домен и работающий на нем сервис. Он оказался уязвимым, и вскоре мы смогли захватить веб‑сервер и проникнуть во внутреннюю сеть предприятия. Как это было сделано, я расскажу в этой статье.
Для поиска старых и забытых ресурсов мы использовали технику Passive DNS. Данные мы взяли из VirusTotal: написали небольшой скрипт, который отправлял запросы к API с IP-адресами из нашего пула. Это позволило собрать множество интересных доменов, большинство из которых входили в наш скоуп. Так и нашелся тот самый «забытый» веб‑сервис, который впоследствии оказался уязвимым.
Домен был непростой, что‑то вроде web1.smth.smth.companyname.com. Там был развернут самописный сервис мониторинга веб‑приложений, на который, судя по логам, последний раз заходили около месяца назад. Доступ к нему мы получили с помощью дефолтных учетных данных (admin:admin), создали отдельную учетку администратора для дальнейшего тестирования и, конечно же, как настоящие этичные хакеры, оповестили отдел ИБ заказчика об уязвимости.
На следующий день ИБ‑отдел закрыл ресурс, хотя мы просили дать возможность продолжать тестирование. Ребята из отдела ИБ объяснили решение тем, что «там нет ничего интересного».
Однако я опустил один момент: перед тем как сообщать об уязвимости, мы спарсили все учетные данные пользователей (для проектных целей и дальнейшего тестирования), которые хранились в открытом виде прямо в разметке HTML. Естественно, среди них были и учетки администраторов.
оль
Полученные учетки мы применили на других ресурсах компании, половина пользователей действительно существовала, но пароли давным‑давно сменены.
Спустя две недели работы над остальным скоупом я параллельно занимался разведкой и работой с вебом. В какой‑то момент я взял наш прошлый хост — *.smth.smth.companyname.com, закинул на перебор в gobuster и... вуаля! Нашелся тот же самый ресурс, но уже с другим алиасом — пусть он будет называться vulnerable.smth.smth.companyname.com.
Здесь уже не было дефолтных учетных данных админа, как раньше, поэтому нам и пригодилась учетка администратора из дампа ресурса web1.smth.smth.companyname.com.
Получаем доступ, ковыряем приложение и находим возможности для самых разных SQL-инъекций. Нам удалось реализовать error-based SQLi, blind (time-based) SQLi, а также мы могли читать локальные файлы с помощью встроенной функции MS SQL — OpenRowset (она позволяет обращаться к локальным файлам).
Это было вечером, а к поздней ночи я докрутил инъекцию в MS SQL до Out-of-Band.
В принципе, ничего сверхъестественного: в одну строчку назначаем произвольную переменную, присваиваем переменной hostname удаленного сервера, с помощью функции exec отправляем на исполнение. Пришлось немного пошаманить с hostname, скорее всего, WAF блокировал запросы к **.oastify.com. Но с помощью нехитрых манипуляций — разделения FQDN на части и конкатенации строк — мне удалось получить отстук на удаленный сервер.
Но из‑за этого возникло несколько проблем:
Код: Скопировать в буфер обмена
Реконфиг прошел успешно, теперь мы можем удаленно исполнять код.
1
Теперь осталось решить вопрос с получением сессии и закреплением. Динамический реверс‑шелл, к сожалению, получить не удалось из‑за отсутствия обратной связи по TCP. Поэтому мы обратились за помощью к нашему небезызвестному коллеге и товарищу s0i37. Очень пригодилась его статья про способы передачи файлов через DNS, а также сами клиент и сервер для DNS-шелла.
Осталось понять, каким образом мы можем передать VBS-клиент на веб‑сервер. Поразмыслив, мы нашли только один вариант — закодировать скрипт в Base64 и построчно передать в файл через Burp Intruder, а потом с помощью certutil декодировать файл и получить рабочий DNS-клиент.
Мы получили сессию с помощью DNS-шелла и по наводке наших инфраструктурщиков проверили сетевой доступ со скомпрометированной машины до дата‑центра. Взаимодействие по SMB открыто.
Дело за малым — осталось локально повысить привилегии и передать машину коллегам — специалистам по тестированию внутренней инфраструктуры.
В локальном повышении нам поможет включенная SeImpersonatePrivilege. Берем эксплоит из семейства «картошек» или PrintSpoofer, повышаем привилегии и передаем машинку коллегам.
Для поиска старых и забытых ресурсов мы использовали технику Passive DNS. Данные мы взяли из VirusTotal: написали небольшой скрипт, который отправлял запросы к API с IP-адресами из нашего пула. Это позволило собрать множество интересных доменов, большинство из которых входили в наш скоуп. Так и нашелся тот самый «забытый» веб‑сервис, который впоследствии оказался уязвимым.
Домен был непростой, что‑то вроде web1.smth.smth.companyname.com. Там был развернут самописный сервис мониторинга веб‑приложений, на который, судя по логам, последний раз заходили около месяца назад. Доступ к нему мы получили с помощью дефолтных учетных данных (admin:admin), создали отдельную учетку администратора для дальнейшего тестирования и, конечно же, как настоящие этичные хакеры, оповестили отдел ИБ заказчика об уязвимости.
На следующий день ИБ‑отдел закрыл ресурс, хотя мы просили дать возможность продолжать тестирование. Ребята из отдела ИБ объяснили решение тем, что «там нет ничего интересного».
Однако я опустил один момент: перед тем как сообщать об уязвимости, мы спарсили все учетные данные пользователей (для проектных целей и дальнейшего тестирования), которые хранились в открытом виде прямо в разметке HTML. Естественно, среди них были и учетки администраторов.


оль
Полученные учетки мы применили на других ресурсах компании, половина пользователей действительно существовала, но пароли давным‑давно сменены.
Спустя две недели работы над остальным скоупом я параллельно занимался разведкой и работой с вебом. В какой‑то момент я взял наш прошлый хост — *.smth.smth.companyname.com, закинул на перебор в gobuster и... вуаля! Нашелся тот же самый ресурс, но уже с другим алиасом — пусть он будет называться vulnerable.smth.smth.companyname.com.
Здесь уже не было дефолтных учетных данных админа, как раньше, поэтому нам и пригодилась учетка администратора из дампа ресурса web1.smth.smth.companyname.com.
Получаем доступ, ковыряем приложение и находим возможности для самых разных SQL-инъекций. Нам удалось реализовать error-based SQLi, blind (time-based) SQLi, а также мы могли читать локальные файлы с помощью встроенной функции MS SQL — OpenRowset (она позволяет обращаться к локальным файлам).



Это было вечером, а к поздней ночи я докрутил инъекцию в MS SQL до Out-of-Band.

В принципе, ничего сверхъестественного: в одну строчку назначаем произвольную переменную, присваиваем переменной hostname удаленного сервера, с помощью функции exec отправляем на исполнение. Пришлось немного пошаманить с hostname, скорее всего, WAF блокировал запросы к **.oastify.com. Но с помощью нехитрых манипуляций — разделения FQDN на части и конкатенации строк — мне удалось получить отстук на удаленный сервер.

Но из‑за этого возникло несколько проблем:
- нужно было каким‑то образом дать права на использование функции xp_cmdshell (RCE by design);
- весь TCP-трафик урезался, и приходили только DNS-запросы, которые, соответственно, используют UDP.
Код: Скопировать в буфер обмена
use master; sp_configure 'xp_cmdshell', '1'; RECONFIGURE


Реконфиг прошел успешно, теперь мы можем удаленно исполнять код.


1
Теперь осталось решить вопрос с получением сессии и закреплением. Динамический реверс‑шелл, к сожалению, получить не удалось из‑за отсутствия обратной связи по TCP. Поэтому мы обратились за помощью к нашему небезызвестному коллеге и товарищу s0i37. Очень пригодилась его статья про способы передачи файлов через DNS, а также сами клиент и сервер для DNS-шелла.
Осталось понять, каким образом мы можем передать VBS-клиент на веб‑сервер. Поразмыслив, мы нашли только один вариант — закодировать скрипт в Base64 и построчно передать в файл через Burp Intruder, а потом с помощью certutil декодировать файл и получить рабочий DNS-клиент.



Мы получили сессию с помощью DNS-шелла и по наводке наших инфраструктурщиков проверили сетевой доступ со скомпрометированной машины до дата‑центра. Взаимодействие по SMB открыто.

Дело за малым — осталось локально повысить привилегии и передать машину коллегам — специалистам по тестированию внутренней инфраструктуры.
В локальном повышении нам поможет включенная SeImpersonatePrivilege. Берем эксплоит из семейства «картошек» или PrintSpoofer, повышаем привилегии и передаем машинку коллегам.


Выводы
Вот как в итоге выглядит цепочка уязвимостей:- Использование словарных паролей.
- Небезопасное хранение паролей.
- Error-based SQL-инъекция.
- Включенная привилегия SeImpersonatePrivilege у сервисной учетной записи.
- Настроить парольную политику. Например, использовать сгенерированные случайным образом пароли, состоящие из 12 или более символов и содержащие цифры, буквы разных регистров и спецсимволы.
- Отказаться от хранения паролей сотрудников в разметке HTML, использовать менеджеры паролей.
- Использовать параметризованные запросы к СУБД и экранировать пользовательский ввод данных.
- Отключить привилегию SeImpersonatePrivilege у сервисных учетных записей.