Се­год­ня я покажу, как рас­кру­тить SQL-инъ­екцию в фор­ме сбро­са пароля и получить учет­ные дан­ные. Затем про­экс­плу­ати­руем уяз­вимость RCE через заг­рузку веб‑шел­ла в фрей­мворк Laravel. Для повыше­ния при­виле­гий исполь­зуем уяз­вимость в при­ложе­нии для бэкапов.

На­ша цель — получе­ние прав супер­поль­зовате­ля на машине Usage с учеб­ной пло­щад­ки Hack The Box. Уро­вень задания — лег­кий.

warning

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

Разведка

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

Сна­чала добавим IP-адрес машины в файл /etc/hosts:

10.10.11.18 usage.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).

Результат работы скрипта
Ре­зуль­тат работы скрип­та

Ска­нер нашел два откры­тых пор­та:

На SSH, не имея учет­ных дан­ных, нам пока делать нечего, поэто­му сос­редото­чим­ся на веб‑сер­вере. Для начала выяс­ним, какие на сай­те исполь­зуют­ся тех­нологии. Это удоб­но делать с помощью сер­виса WhatWeb. Он ана­лизи­рует веб‑стра­ницу и пыта­ется опре­делить, какие CMS, веб‑сер­веры, язы­ки прог­рамми­рова­ния, фрей­мвор­ки и дру­гие тех­нологии исполь­зуют­ся на сай­те.

За­пус­тим WhatWeb и переда­дим ему IP-адрес целево­го сер­вера:

whatweb http://10.10.11.18
Результат работы скрипта
Ре­зуль­тат работы скрип­та

Ре­зуль­таты ска­ниро­вания показы­вают, что веб‑сайт исполь­зует Laravel — популяр­ный PHP-фрей­мворк, который широко при­меня­ется для раз­работ­ки веб‑при­ложе­ний. Это важ­ная информа­ция, так как в слу­чае уяз­вимос­тей в Laravel мы смо­жем их исполь­зовать для даль­нейшей ата­ки.

Кро­ме того, на сай­те нас­тро­ен редирект на домен usage.htb.

На сай­те мы видим стан­дар­тную фор­му авто­риза­ции с воз­можностью регис­тра­ции новых поль­зовате­лей.

Форма авторизации
Фор­ма авто­риза­ции

Точка входа

При попыт­ке перей­ти на стра­ницу Admin (/admin) мы стал­кива­емся с ошиб­кой Unknown host.

Ошибка Unknown host
Ошиб­ка Unknown host

Это про­исхо­дит из‑за того, что наш локаль­ный DNS не зна­ет о сущес­тво­вании под­домена admin.usage.htb. Что­бы испра­вить это, нуж­но обно­вить запись в фай­ле /etc/hosts:

10.10.11.18 usage.htb admin.usage.htb

Пос­ле это­го перезаг­ружа­ем стра­ницу, и перед нами откры­вает­ся глав­ная стра­ница адми­нис­тра­тор­ской панели.

Главная страница admin.usage.htb
Глав­ная стра­ница admin.usage.htb

В поис­ках точ­ки вхо­да перехо­дим к тес­тирова­нию фун­кции вос­ста­нов­ления пароля на стра­нице /forget-password. Это потен­циаль­ная точ­ка для про­веде­ния SQL-инъ­екции.

Справка: SQL-инъекции и sqlmap

SQL-инъ­екция — это тип уяз­вимос­ти, при котором зло­умыш­ленник может внед­рить про­изволь­ный SQL-код в зап­рос к базе дан­ных через поль­зователь­ский ввод. Это может поз­волить прос­матри­вать, изме­нять или уда­лять дан­ные из базы дан­ных, а так­же иног­да получать дос­туп к опе­раци­онной сис­теме. Что­бы най­ти воз­можность про­вес­ти SQL-инъ­екцию, при тес­тирова­нии при­ложе­ний отправ­ляют спе­циаль­ные сим­волы и пос­ледова­тель­нос­ти через про­веря­емое поле и смот­рят реак­цию сер­вера. Если сер­вер отве­чает ина­че на опре­делен­ные сим­волы, это может сви­детель­ство­вать о наличии уяз­вимос­ти.

Sqlmap — это мощ­ный инс­тру­мент для авто­мати­зации про­цес­са экс­плу­ата­ции SQL-инъ­екций. Он поз­воля­ет авто­мати­чес­ки обна­ружи­вать и исполь­зовать уяз­вимос­ти, под­бирать пароли, извле­кать дан­ные и выпол­нять коман­ды на сер­вере.

Под­робнее читай в статье «SQL-инъ­екции. Раз­бира­ем на паль­цах одну из самых популяр­ных хакер­ских тех­ник».

Прос­мотрим зап­рос на сер­вер в Burp History.

Запрос на восстановление пароля
Зап­рос на вос­ста­нов­ление пароля

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

Для перебо­ра перенап­равим зап­рос ком­бинаци­ей кла­виш Ctrl-I в Burp Intruder.

Burp Intruder — вкладка Positions
Burp Intruder — вклад­ка Positions
Burp Intruder — результат атаки
Burp Intruder — резуль­тат ата­ки

В ито­ге получа­ем нес­коль­ко типич­ных для SQL injection наг­рузок. Про­дол­жаем про­вер­ку SQL-инъ­екции, и сре­ди UNION-наг­рузок, опре­деля­ющих количес­тво стол­бцов в таб­лице, все­го одна дает отличный от осталь­ных наг­рузок резуль­тат. Так мы понима­ем, что в таб­лице семь стол­бцов, а уяз­вимость на сай­те при­сутс­тву­ет.

Проверка нагрузок для SQL-инъекции
Про­вер­ка наг­рузок для SQL-инъ­екции

Поп­робу­ем авто­мати­зиро­вать экс­плу­ата­цию уяз­вимос­ти.

SQL-инъекция

Сох­раним зап­рос из Burp History в файл r.txt, пос­ле чего переда­дим файл прог­рамме sqlmap в парамет­ре -r. Так­же в парамет­ре -p ука­жем уяз­вимый POST-параметр email и зап­росим базы дан­ных на сер­вере (--dbs). Спус­тя пол­часа sqlmap опре­делил уяз­вимость, подоб­рал наг­рузку и нашел сущес­тву­ющие базы дан­ных.

sqlmap -r r.txt -p email --batch --level 5 --thread=10 --dbs
Нагрузка sqlmap
Наг­рузка sqlmap
Список баз данных
Спи­сок баз дан­ных

Сре­ди пред­став­ленных баз дан­ных нам нуж­на поль­зователь­ская usage_blog. Получим таб­лицы (--tables) из этой базы (-D).

sqlmap -r r.txt -p email --batch --level 5 --thread=10 -D usage_blog --tables
Таблицы в базе usage_blog
Таб­лицы в базе usage_blog

На­иболь­ший инте­рес пред­став­ляет таб­лица admin_users. Выг­рузим из этой таб­лицы (-T) все дан­ные (--dump).

sqlmap -r r.txt -p email --batch --level 5 --thread=10 -D usage_blog -T admin_users --dump
Содержимое таблицы admin_users
Со­дер­жимое таб­лицы admin_users

Так мы получа­ем все­го один хеш пароля адми­нис­тра­тора. Судя по виду, исполь­зован алго­ритм хеширо­вания bcrypt. Опре­делить соот­ветс­тву­ющий режим hashcat мож­но, поис­кав сло­во bcrypt в справ­ке ути­литы.

hashcat -h | grep bcrypt
Режимы для алгоритмов hashcat
Ре­жимы для алго­рит­мов hashcat

Те­перь мы зна­ем, что нам нужен режим 3200, и мы можем запус­тить под­бор пароля. Для это­го будем исполь­зовать популяр­ный сло­варь rockyou.txt. Перебор зай­мет все­го пару минут.

hashcat -m 3200 hash rockyou.txt
Результат подбора пароля
Ре­зуль­тат под­бора пароля

С получен­ными логином и паролем авто­ризу­емся в админке сай­та.

Главная страница админа сайта
Глав­ная стра­ница адми­на сай­та

На стра­нице Dashboard мож­но уви­деть спи­сок исполь­зуемых тех­нологий.

Точка опоры

Те­перь нам извес­тна точ­ная вер­сия фрей­мвор­ка Laravel и мы можем про­верить, сущес­тву­ют ли для нее уяз­вимос­ти. Про­ще все­го для это­го поис­кать в Google.

Поиск эксплоита в Google
По­иск экс­пло­ита в Google

Эта вер­сия фрей­мвор­ка уяз­вима к выпол­нению про­изволь­ного кода через некон­тро­лиру­емую заг­рузку фай­лов на стра­нице парамет­ров поль­зовате­ля (CVE-2023-24249). Это поз­волит нам заг­рузить PHP-шелл.

Справка: реверс-шелл

Об­ратный шелл — это под­клю­чение, которое акти­виру­ет ата­куемая машина, а мы при­нима­ем и таким обра­зом под­клю­чаем­ся к ней, что­бы выпол­нять коман­ды от лица поль­зовате­ля, запус­тивше­го шелл. Для при­ема соеди­нения необ­ходимо соз­дать на локаль­ной машине listener, то есть «слу­шатель».

За­пус­каем лис­тенер:

pwncat-cs -lp 4321

И заг­ружа­ем php-reverse-shell в фор­мате JPG, пред­варитель­но уста­новив свои дан­ные для под­клю­чения к лис­тенеру.

Загрузка PHP-шелла
Заг­рузка PHP-шел­ла

От­лавли­ваем зап­рос в Burp Proxy и добав­ляем к име­ни заг­ружа­емо­го фай­ла еще одно рас­ширение .php.

Изменение запроса в Burp Proxy
Из­менение зап­роса в Burp Proxy
Страница с загруженным шеллом
Стра­ница с заг­ружен­ным шел­лом

Те­перь перехо­дим к заг­ружен­ному фай­лу и в логах лис­тенера видим кон­нект от реверс‑шел­ла. Таким обра­зом получа­ем сес­сию на хос­те и забира­ем пер­вый флаг.

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

Продвижение

В домаш­нем катало­ге поль­зовате­ля есть файл .monitrc, в котором находим учет­ные дан­ные поль­зовате­ля admin.

Содержимое домашнего каталога пользователя
Со­дер­жимое домаш­него катало­га поль­зовате­ля
Содержимое файла .monitrc
Со­дер­жимое фай­ла .monitrc

Эти учет­ные дан­ные могут быть полез­ны для даль­нейше­го прод­вижения. Про­верим, к каким поль­зовате­лям они подой­дут. Получим спи­сок поль­зовате­лей с активной коман­дной обо­лоч­кой из фай­ла /etc/passwd.

cat /etc/passwd | grep bash
Активные пользователи
Ак­тивные поль­зовате­ли

Поль­зователь dash у нас уже есть, поэто­му про­буем под­клю­чить­ся как поль­зователь xander.

Сессия пользователя xander
Сес­сия поль­зовате­ля xander

Локальное повышение привилегий

Те­перь нам необ­ходимо соб­рать информа­цию. Я буду исполь­зовать для это­го скрип­ты PEASS.

Справка: скрипты PEASS

Что делать пос­ле того, как мы получи­ли дос­туп в сис­тему от име­ни поль­зовате­ля? Вари­антов даль­нейшей экс­плу­ата­ции и повыше­ния при­виле­гий может быть очень мно­го, как в Linux, так и в Windows. Что­бы соб­рать информа­цию и наметить цели, мож­но исполь­зовать Privilege Escalation Awesome Scripts SUITE (PEASS) — набор скрип­тов, которые про­веря­ют сис­тему на авто­мате и выда­ют под­робный отчет о потен­циаль­но инте­рес­ных фай­лах, про­цес­сах и нас­трой­ках.

Заг­рузим на хост скрипт для Linux, дадим пра­во на выпол­нение и запус­тим ска­ниро­вание. В выводе будет мно­го информа­ции, но нам здесь инте­рес­ны толь­ко нас­трой­ки sudoers.

Настройки sudoers
Нас­трой­ки sudoers

Ви­дим, что мы можем запус­тить файл /usr/bin/usage_management от име­ни поль­зовате­ля root без вво­да пароля. Ско­рее все­го, это мож­но будет исполь­зовать. Давай пос­мотрим, что это за файл.

file /usr/bin/usage_management
Формат файла
Фор­мат фай­ла

Это ском­пилиро­ван­ная бинар­ная ути­лита, а зна­чит, ее ана­лиз будет нем­ного слож­нее, нежели скрип­та на Bash или на Python. При запус­ке прог­раммы нам пред­ложат выб­рать один из трех вари­антов.

Запуск программы
За­пуск прог­раммы

Сто­ит про­верить, что будет про­исхо­дить в сис­теме при работе этой прог­раммы. Для отсле­жива­ния вновь запус­каемых про­цес­сов будем исполь­зовать ути­литу pspy64. Логиним­ся по SSH в новой кон­соли, запус­каем pspy64, а затем выбира­ем пер­вую фун­кцию в иссле­дуемом при­ложе­нии. В логах pspy64 тут же отоб­разит­ся стран­ный про­цесс.

Логи pspy64
Ло­ги pspy64

Ути­лита вызыва­ет через коман­дную обо­лоч­ку архи­ватор 7za. Исполь­зуем ути­литу strings для получе­ния всех строк из фай­ла.

Строки из файла usage_management
Стро­ки из фай­ла usage_management

Ви­димо, перед выпол­нени­ем коман­ды 7za рабочий каталог меня­ется на var/www/html/. В аргу­мен­тах 7za инте­рес­на пос­ледова­тель­ность парамет­ров -- *. Параметр -- озна­чает, что все пос­леду­ющие «сло­ва» будут вос­при­нимать­ся не как парамет­ры, а толь­ко как пути к фай­лам.

По­луча­ется, что если мы соз­дадим в катало­ге /var/www/html/ файл @id_rsa и сим­линк id_rsa на ключ /root/.ssh/id_rsa, то 7za будет вос­при­нимать id_rsa как спи­сок фай­лов. А при попыт­ке про­читать каж­дую стро­ку из id_rsa как файл архи­ватор будет выводить сооб­щение об ошиб­ке, содер­жащее эту стро­ку. Таким обра­зом мы получим все содер­жимое при­ват­ного клю­ча поль­зовате­ля root.

cd /var/www/html/
touch @id_rsa
ln -s /root/.ssh/id_rsa id_rsa
sudo /usr/bin/usage_management
Запуск приложения
За­пуск при­ложе­ния
Ошибка чтения файлов
Ошиб­ка чте­ния фай­лов

Как и пред­полага­лось, мы получа­ем все содер­жимое фай­ла по ссыл­ке. Перепе­чаты­ваем ключ и заходим по SSH как поль­зователь root.

Флаг рута
Флаг рута

Ма­шина зах­вачена!