Это была быстрая и забавная коробка, которая была одной из первых машин HackTheBox, которые я завершил. Теперь, когда он был выведен из эксплуатации на выходных, я подумал, что расскажу, как я внедрил эту машину!
Резюме
Celestial - это Linux-машина, на которой размещена веб-служба Node.js Express, которая небезопасно оценивает параметры файлов cookie, предоставляемые клиентом. Эта уязвимость была использована для получения обратной оболочки в системе. Записываемый файл, который был запущен root
через задание cron, использовался для повышения привилегий.
Разведка
Я начал это, как обычно, с nmap -sV -sC
сканирования, чтобы перечислить версии служб и запустить сценарии по умолчанию:
Я последовал за этим с помощью вторичного полного сканирования портов, чтобы увидеть, открыты ли какие-либо другие порты. Однако был возвращен только порт 3000. На этом этапе, поскольку других служб для доступа не было, я запустил браузер, чтобы посмотреть, что хранится у веб-сервера.
Самый первый запрос вернул ошибку 404 Not Found… поэтому я обновил страницу, чтобы посмотреть, не произойдет ли что-нибудь. Конечно же!
Я хотел понять, почему это могло произойти, поэтому я проксировал свои запросы на этот сервер и обнаружил, что на сервер с именем profile
передается файл cookie, который, похоже, был закодирован. Поскольку я уже был в Burp Suite, я отправил файл cookie в Decoder и преобразовал его в открытый текст:
Теперь я смог прочитать значения файлов cookie:
{“username”:”Dummy”,”country”:”Idk Probably Somewhere Dumb”,”city”:”Lametown”,”num”:”2"}
Это объясняет веб-ответ «Эй, манекен 2 + 2 = 22». Если я изменил значения username
или num
в этом файле cookie, веб-страница напечатала бы имя и дважды объединила числа.
Использовать
В этот момент я знал, что именно здесь должен быть мой исходный плацдарм. Я начал искать способы использования этого файла cookie в веб-службе Node.js. Мне удалось найти это сообщение в блоге, в котором объясняется, как можно использовать ненадежные данные, переданные в функцию unserialize()
в модуле сериализации узлов, для выполнения произвольного кода путем передачи сериализованного объекта JavaScript с выражением функции с немедленным вызовом.
Уязвимости десериализации не являются эксклюзивными для Node.js и существуют во многих других языках. Общие векторы десериализации на других языках включают
- Внедрение объекта PHP
- Десериализация Java
- Rails RCE Vulnerability (XML & YAML)
- Десериализация рассола в Python
Использовать эту уязвимость десериализации в Node.js для получения обратной оболочки очень просто благодаря nodeshell.py на GitHub. Полезную нагрузку можно очень легко сгенерировать, запустив скрипт с IP-адресом злоумышленника и локальным портом для обратного подключения:
Закодированную полезную нагрузку в String.fromCharCode()
можно легко перевернуть, чтобы вернуть фактические инструкции (или вы можете просто прочитать код на GitHub!):
Это возвращает:
Поскольку этот код выполняется внутри eval()
, он будет выполнен на сервере и порождает процесс /bin/sh
и отправляет его на порт прослушивания злоумышленника.
Чтобы отправить эту eval()
функцию обратно на сервер в виде файла cookie, она должна быть упакована в переменную с синтаксисом {"name":value}
как таковой:
{“rce”:”_$$ND_FUNC$$_function (){ eval(String.fromCharCode(…))}()"}
После того, как этот файл cookie закодирован в формате base64, он готов к отправке обратно на сервер, чтобы получить обратную оболочку! Злоумышленнику остается только запустить прослушиватель netcat:
nc -lvnp 1337
-l
- слушать-v
- подробно-n
- IP-адреса только числовые, без DNS-p
- порт (в данном случае 1337)
Прежде чем двигаться дальше, стоит отметить, что сервер разрешил получение и выполнение этого вредоносного файла cookie, даже если в файле cookie не было никаких исходных параметров!
Однако полезные данные также могут быть помещены в другие значения файла cookie. Например, в username
:
{“username”:”_$$ND_FUNC$$_function (){ eval(String.fromCharCode(…))}()”,”country”:”Idk Probably Somewhere Dumb”,”city”:”Lametown”,”num”:”2"}
В любом случае строка в кодировке base64 переходит в значение profile
запроса GET к серверу, и слушатель поймает обратную оболочку.
Повышение привилегий
Оказавшись на сервере, я смог выполнить быстрое перечисление и обнаружил, что мой пользователь находится в группе adm
, что означает, что пользователь может читать журналы с сервера. В домашнем каталоге моего пользователя я заметил два файла: ~/output.txt
и ~/Documents/script.py
.
Содержимое script.py
было просто оператором печати, в котором говорилось: «Сценарий выполняется…», а output.txt
содержало то же самое. Мой пользователь владел script.py
с доступом для чтения и записи - без прав на выполнение. Однако output.txt
принадлежал root
. Это дало мне указание на то, что может быть какое-то задание cron, запущенное для root
, чтобы выполнить script.py
с регулярным интервалом и, возможно, записать его в output.txt
.
У моего пользователя не было разрешений на запуск crontab -u root
и просмотр заданий cron, запланированных в root
. Однако этот пользователь был членом группы adm
, поэтому он мог просматривать журналы в каталоге /var/log/
. Мы видим, что каждые 5 минут root
выполняет script.py
и записывает результат в output.txt
.
tail -10 /var/log/syslog | grep root
Выводит следующее:
Отсюда просто переписал script.py
как обратную оболочку python из Шпаргалки по обратной оболочке Pentestmonkey, установил IP и порт и подождал 5 минут, чтобы поймать мою корневую оболочку с другим netcat
прослушивателем!