HTB Lantern
Ломаем сайт на CMS Blazor
Наша цель — получение прав суперпользователя на машине Lantern с учебной площадки Hack The Box. Уровень задания — сложный.
warning
Подключаться к машинам с HTB рекомендуется с применением средств анонимизации и виртуализации. Не делай этого с компьютеров, где есть важные для тебя данные, так как ты окажешься в общей сети с другими участниками.
Разведка
Сканирование портов
Добавляем IP-адрес машины в /
:
10.10.11.29 lantern.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.9p1;
- 80 — веб‑сервер Skipper Proxy;
- 3000 — веб‑сервер Kestrel.
Сразу видим, что на сервере установлен Skipper Proxy — прокси‑сервер и HTTP-роутер, написанный на Go. Он маршрутизирует HTTP-запросы на основе разных правил и настроек.

Точка входа
На сайте на 80-м порте находим интересную информацию о команде разработчиков. Можно сделать выводы об используемых технологиях.

Также находим форму отправки резюме.

На порте 3000 нас встречает форма авторизации.

Если просмотреть историю запросов в Burp History, заметим много запросов, типичных для CMS Blazor. С этой системой я уже сталкивался, когда писал райтап по HTB Blazorized.

Осмотрев сайты, углубимся в изучение найденных продуктов. У нас есть Skipper Proxy и Blazor, начнем с первого. Сначала стоит проверить, есть ли для обнаруженной версии CMS актуальные эксплоиты.

Из Google узнаём, что Skipper Proxy 0.13.237 уязвим к CVE-2022-38580. Как сказано в описании эксплоита, можно эксплуатировать SSRF для доступа к внутренним ресурсам, просто указав адрес ресурса в заголовке X-Skipper-Proxy
.

Перейдем в Burp Repeater и добавим заголовок X-Skipper-Proxy:
.

Сервер отдаст нам содержимое сайта на порте 3000, что подтверждает наличие уязвимости.
Точка опоры
Перенаправляем запрос в Burp Repeater для перебора портов через SSRF. Так мы сможем узнать о работающих внутренних сервисах.


Сортируем результаты сканирования по коду ответа и получаем четыре открытых порта для адреса 127.0.0.1.

Порт 5000 отвечает за технологию Blazor, а значит, через SSRF мы можем получить доступ к файлу /
, который содержит информацию обо всех загружаемых сборках.

Из всех сборок наиболее интересна кастомная библиотека InternaLantern.
, в которой, видимо, и реализованы основные возможности. Нам нужно ее скачать, и для этого обратимся к файлу через специальный прокси. Для этого в контекстном меню переходим к Request in browser → In current browser session.

Получаем ссылку, по которой нужно перейти в браузере Burp. В результате получаем скачанную библиотеку.


Так как библиотека написана на C#, мы можем декомпилировать исходный код для анализа. В этом нам поможет бесплатная утилита dotPeek. В исходном коде среди перечисления данных о пользователях находим длинные строки в Base64.

При декодировании первой строки получаем данные пользователя, в том числе и описание.

Декодируем все строки из файла и получаем пароль пользователя admin.

С этими учетными данными заходим на основной сайт.

Продвижение
Можно загружать на сайт файлы, а также смотреть содержимое каталогов и файлов.


Просмотрим основной файл app.
. Мое внимание привлек эндпоинт /
, который принимает параметры lang
и ext
и использует их в формировании пути без какой‑либо фильтрации (строки 38–45).

То есть на сервере есть уязвимость, позволяющая получить содержимое произвольного файла. Для проверки получим содержимое файла /
.
http://lantern.htb/PrivacyAndPolicy?lang=../../../../&ext=./etc/passwd

Раскрутить эту уязвимость не вышло, поэтому я обратил внимание на функцию использования модулей. Если изменить стандартный модуль Logs на любой произвольный, то получим ошибку, раскрывающую путь к компонентам.

Получается, что, если загрузить в каталог свой модуль, его можно будет подключить в программу. Отловим запрос на загрузку файла evil.
в Burp Proxy.

Данные передаются в сериализованном виде, поэтому просто изменить их не получится. Для десериализации и сериализации данных будем использовать расширение Blazor Traffic Processor.


Имя загружаемого файла передается в параметре name
. Сделаем свой компонент и повторим загрузку. Для этого сперва создадим проект.
mkdir evil
cd evil
dotnet new classlib -n exploit

Теперь перейдем к файлу Class1.
внутри проекта и изменим код. Наш модуль будет считывать и выводить на страницу приватный ключ пользователя tomas
(о нем узнали из файла /
).
using Microsoft.AspNetCore.Components;using Microsoft.AspNetCore.Components.Rendering;using System.IO;namespace exploit;public class Component : ComponentBase{ protected override void BuildRenderTree(RenderTreeBuilder builder) { base.BuildRenderTree(builder); string file = File.ReadAllText("/home/tomas/.ssh/id_rsa"); builder.AddContent(0, file); }}
Осталось добавить необходимые компоненты AspNetCore и собрать нашу DLL.
cd exploit
dotnet add package Microsoft.AspNetCore.Components --version 6.0.0
dotnet add package Microsoft.AspNetCore.Components.Web --version 6.0.0
dotnet build -c release

Повторяем загрузку файла, на моменте десериализации данных изменяем путь загрузки файла и выполняем повторную сериализацию.

Применяем сериализованные данные в Burp Proxy и отправляем остановленный ранее запрос. Файл успешно загружен по указанному пути.

Переходим к панели администратора и указываем имя модуля. В ответе сервера получаем приватный SSH-ключ пользователя.

С этим ключом авторизуемся по SSH и читаем первый флаг.

Локальное повышение привилегий
Первое, что мы проверяем на машине с Linux, — есть ли у нас возможность выполнить команды через sudo
.
sudo -l

Справка: sudoers
Файл /
в Linux содержит списки команд, которые разные группы пользователей могут выполнять от имени администратора системы. Можно просмотреть его как напрямую, так и при помощи команды sudo
.
Судя по содержимому файла sudoers, мы можем выполнить команду /
в привилегированном контексте без ввода пароля. Проверим тип файла /
и узнаем, что это исполняемый ELF.
file /usr/bin/procmon

Справка дает понять, что это аналог Process Monitor для Windows, только в Linux.

Таким образом, запуская приложение через sudo
, мы можем просматривать системные вызовы (параметр -e
) для любого процесса на хосте. Давай выберем процесс для отслеживания. Меня заинтересовал nano /
.

Процесс постоянно завершается и запускается заново, поэтому его PID меняется. Запустим procmon и укажем ему, что нужно собирать системный вызов write
у процесса с PID 909 и сохранять лог в базу данных db.
.
sudo /usr/bin/procmon -e write -p 909 -c db.db

Минуты через две завершаем программу и забираем базу данных на свой хост для анализа.

Сразу обращаем внимание, что встречаются вызовы с большой задержкой (duration
) и перехваченные данные немного отличаются.


Я написал SQL-запрос, который извлекает из каждого вызова с большой задержкой (duration >
) девятый символ. Позже запрос подкорректировал, так как девятым может идти пробел, в этом случае будем брать десятый.
SELECT GROUP_CONCAT( CASE WHEN hex(substr(arguments, 9, 1)) = '20' THEN substr(arguments, 10, 1) ELSE substr(arguments, 9, 1) END,'') as dataFROM ebpf where duration > 100000000;

И получаем введенный в nano текст: echo
. У нас есть пароль рута, и ничто не мешает забрать последний флаг.

Машина захвачена!