Это была быстрая и забавная коробка, которая была одной из первых машин 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 и существуют во многих других языках. Общие векторы десериализации на других языках включают

Использовать эту уязвимость десериализации в 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 прослушивателем!