В этой статье мы прой­дем машину Sink с пло­щад­ки HackTheBox. Для это­го нам понадо­бит­ся про­экс­плу­ати­ровать уяз­вимость HTTP Request Smuggling, а получив точ­ку опо­ры, будем раз­бирать­ся с тех­нологи­ей AWS Secrets Manager. Ску­чать точ­но не при­дет­ся!

warning

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

 

Разведка

 

Сканирование портов

Ад­рес машины — 10.10.10.225, добав­ляем его в /etc/hosts как sink.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 (служ­ба SSH), 3000 (Gitea) и 5000 (Gunicorn). Нач­нем с Git.

Обнаруженные имена пользователей
Об­наружен­ные име­на поль­зовате­лей

Мы видим какие‑то име­на поль­зовате­лей (запишем их, могут при­годить­ся!), но боль­ше ничего инте­рес­ного нет. Поэто­му перехо­дим к Gunicorn. На сай­те, который он отда­ет, нуж­но регис­три­ровать­ся. Сде­лаем это, авто­ризу­емся и пос­мотрим, что нам ста­нет дос­тупно.

Ос­мотр сай­тов я рекомен­дую про­водить через Burp, что­бы мож­но было прос­мотреть все отправ­ляемые и получа­емые дан­ные. Так пос­ле отправ­ки ком­мента­рия в отве­те замеча­ем заголо­вок Via. Это заголо­вок для прок­си, в котором ука­зано haproxy.

Запрос в истории Burp
Зап­рос в исто­рии Burp
Ответ сервера в истории Burp
От­вет сер­вера в исто­рии Burp

HAProxy — это сер­верное при­ложе­ние, которое обес­печива­ет высокую дос­тупность сай­та и балан­сиру­ет наг­рузку TCP и HTTP-при­ложе­ний меж­ду нес­коль­кими сер­верами.

Даль­ше я попытал­ся пос­каниро­вать дирек­тории. У меня ничего не выш­ло, зато сооб­щение об ошиб­ке помог­ло выяс­нить исполь­зуемую вер­сию HAProxy — 1.9.10.

Ошибка, полученная при сканировании директорий
Ошиб­ка, получен­ная при ска­ниро­вании дирек­торий

По­гуг­лив, узна­ем, что эта вер­сия уяз­вима к ата­ке HTTP Request Smuggling.

 

Точка входа

 

HTTP Request Smuggling

HTTP Request Smuggling — это метод вме­шатель­ства в про­цесс обра­бот­ки сай­том HTTP-зап­росов, получен­ных от одно­го или нес­коль­ких поль­зовате­лей. Уяз­вимость час­то име­ет кри­тичес­кий харак­тер и поз­воля­ет зло­умыш­ленни­ку обой­ти меры безопас­ности, получить несан­кци­они­рован­ный дос­туп к кон­фиден­циаль­ным дан­ным и нап­рямую пос­тавить под угро­зу дру­гих поль­зовате­лей при­ложе­ния. Уяз­вимость воз­ника­ет из‑за того, что спе­цифи­кация HTTP пре­дос­тавля­ет два раз­ных спо­соба ука­зать, где закан­чива­ется зап­рос: заголо­вок Content-Length и заголо­вок Transfer-Encoding.

За­голо­вок Content-Length прост: он опре­деля­ет дли­ну тела сооб­щения в бай­тах. Нап­ример:

POST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 6
p=test

За­голо­вок Transfer-Encoding может при­менять­ся для ука­зания того, что исполь­зует­ся тело сооб­щения с фраг­менти­рован­ным кодиро­вани­ем. Это зна­чит, что тело сооб­щения содер­жит один или нес­коль­ко бло­ков дан­ных. Бло­ки устро­ены так. Сна­чала идет раз­мер бло­ка в бай­тах (в hex), затем знак новой стро­ки, а даль­ше — содер­жимое бло­ка. Сооб­щение закан­чива­ется бло­ком нулево­го раз­мера. Нап­ример:

POST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Transfer-Encoding: chunked
a
param=test
0

Так мы можем исполь­зовать одновре­мен­но два заголов­ка. Пер­вый сер­вер будет раз­делять зап­росы по пер­вому заголов­ку, а вто­рой — по вто­рому, тем самым встра­ивая свои зап­росы и про­пус­кая их даль­ше.

Прис­тупим к реали­зации. Отпра­вим ком­мента­рий и перех­ватим зап­рос в Burp Proxy.

Запрос на сервер
Зап­рос на сер­вер

Его сто­ит пре­обра­зовать сле­дующим обра­зом: ука­жем заголо­вок Transfer-Encodeing:[\x0b]chunked и поменя­ем зна­чение Connection на keep-alive. Пос­ле чего дуб­лиру­ем заголов­ки зап­роса в тело зап­роса.

Измененный запрос
Из­менен­ный зап­рос

Пос­ле редирек­та видим явно не тот ком­мента­рий, который отправ­ляли.

Ответ в Burp
От­вет в Burp
Комментарии на странице сайта
Ком­мента­рии на стра­нице сай­та

Де­ло в том, что внут­ренний сер­вер неп­равиль­но интер­пре­тиро­вал раз­мер передан­ных дан­ных из‑за путани­цы в опре­деля­ющих его HTTP заголов­ках, поэто­му отоб­разил боль­ше информа­ции, чем дол­жен был. Блок допол­нитель­ной информа­ции, отоб­ражен­ной в ком­мента­рии, был взят из сле­дующе­го зап­роса дру­гого поль­зовате­ля. В этом зап­росе переда­вались cookie дру­гого поль­зовате­ля, которые мы сра­зу под­став­ляем себе и перезаг­ружа­ем стра­ницу. Как мож­но заметить, в дан­ный момент мы име­ем сес­сию адми­нис­тра­тора сай­та.

Шапка сайта
Шап­ка сай­та

Так как это сер­вис хра­нения заметок, сра­зу прос­мотрим, что может хра­нить админ. Находим три замет­ки.

Записи администратора
За­писи адми­нис­тра­тора

Каж­дая из них содер­жит учет­ные дан­ные.

Содержимое заметок администратора
Со­дер­жимое заметок адми­нис­тра­тора
 

Точка опоры

С най­ден­ными учет­ными дан­ными получа­ется авто­ризо­вать­ся в Git от име­ни root. Находим очень мно­го ком­митов, которые сто­ит прос­мотреть. Отту­да мы можем получить еще какие‑нибудь учет­ные дан­ные, сек­реты, токены или прос­то узнать исполь­зуемые тех­нологии.

Страница Git пользователя root
Стра­ница Git поль­зовате­ля root

Я начал прос­мотр с кон­ца. Важ­ные дан­ные наш­лись в ком­мите вот по этой ссыл­ке:

http://sink.htb:3000/root/Log_Management/commit/e8d68917f2570f3695030d0ded25dc95738fb1baa
Исходный код logs.php
Ис­ходный код logs.php

А в этом ком­мите нашел­ся при­ват­ный ключ:

http://sink.htb:3000/root/Key_Management/commit/b01a6b7ed372d154ed0bc43a342a5e1203d07b1e
Исходный код dev_keys
Ис­ходный код dev_keys

Не­обхо­димо про­верить этот ключ. Для это­го сфор­миру­ем спи­сок поль­зовате­лей и попыта­емся под­клю­чить­ся по SSH. Для авто­мати­зации я исполь­зовал Metasploit Framework.

msfconsole
use auxiliary/scanner/ssh/ssh_login_pub
set RHOSTS sink.htb
set USER_FILE users.txt
set KEY_PATH root.key
run
Настройка Metasploit для перебора пользователей
Нас­трой­ка Metasploit для перебо­ра поль­зовате­лей
Результат перебора пользователей
Ре­зуль­тат перебо­ра поль­зовате­лей

В ито­ге находим поль­зовате­ля, к учет­ке которо­го под­ходит ключ. Так мы получа­ем ста­биль­ную точ­ку опо­ры в виде дос­тупа по SSH.

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

Продолжение доступно только участникам

Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».

Присоединяйся к сообществу «Xakep.ru»!

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

Подписаться
Уведомить о
0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии