Взлом Nginx с помощью уяз­вимости в скрип­те

Взлом уязвимость

В сегодняшней статье будем заниматься экс­плу­ата­цией неп­равиль­но нас­тро­енных али­асов nginx, знакомиться с методом получе­ния RCE через локаль­ное вклю­чение фай­лов, порабо­таем с LDAP в Linux и будем искать уяз­вимость в поль­зователь­ском скрип­те. Все это позволяет сделать задание Pikaboo с пло­щад­ки Hack The Box.

Еще по теме: Взлом веб-сервера на Windows и Apache через SSRF

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

Начнем со сканирования портов. Это стан­дар­тная операция при любом пентесте. Сканирование портов позволит определить, какие служ­бы на машине при­нима­ют соеди­нение.

Самый популярный сканер — это Nmap. Следующий скрипт улучшит резуль­таты сканирования:

Он дей­ству­ет в два эта­па. На пер­вом про­изво­дит­ся обыч­ное быс­трое ска­ниро­вание, на вто­ром — более тща­тель­ное ска­ниро­вание, с исполь­зовани­ем име­ющих­ся скрип­тов (опция -A).

Результат скрипта Nmap
Результат скрипта Nmap

Мы наш­ли три откры­тых пор­та:

  • 21 (служ­ба VSFTPD 3.0.3),
  • 22 (служ­ба SSH)
  • 80 (веб‑сер­вер nginx 1.14.2).

На SSH без учет­ных дан­ных сту­чать­ся бес­полез­но, но и на FTP нам делать нечего: Nmap уже про­верил воз­можность ано­ним­ного вхо­да и не обна­ружил ее.

Брутфорс FTP

В начале попробуем переб­рать популяр­ные логины для FTP. Вы запросто най­дете готовые используя поисковой запрос:

Для это­го будем исполь­зовать hydra (не путать с Ghidra). Опци­ей -t уста­новим 32 потока.

Ре­зуль­тат перебо­ра учет­ных дан­ных
Ре­зуль­тат перебо­ра учет­ных дан­ных

Результата положительного это не принесло, поэто­му переходим к вебу.

Сканирование веб-контента

Быстрый осмотр сайта говорит о том, что он еще в раз­работ­ке, об этом говорит сооб­щение «PokeAPI Integration — Coming soon!».

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

А вот стра­ница адми­нис­тра­тора нас встречает HTTP-аутен­тифика­цией. Отказ от про­вер­ки учет­ных дан­ных, приведет к ошиб­ке дос­тупа.

Ошиб­ка дос­тупа
Ошиб­ка дос­тупа

Ошиб­ка инте­рес­на сооб­щением об исполь­зовании веб‑сер­вера Apache на пор­те 81. При том, что обра­щение было к пор­ту 80, на котором работа­ет веб‑сер­вер nginx (по результату сканирования Nmap). Видимо, во время обра­щения к катало­гу адми­нис­тра­тора срабатывает внут­ренняя пере­адре­сация меж­ду сер­верами.

Точка входа

Уязвимость nginx path traversal

Ес­ли столкнетесь с nginx, то первым делом надо искать уяз­вимость обхо­да путей. Уязвимость появ­ляет­ся при неп­равиль­ной конфигурации али­асов. Nginx alias — это некий псев­доним, который может скрыть настоящее мес­тополо­жение объ­екта. Он определяется в дирек­тиве location. На пример, данная кон­фигура­ция уста­новит замену /img/ на /web/data/images/:

Во время обращения к /img/test.png веб‑сер­вер вер­нет файл /web/data/images/test.png. Уяз­вимость прояв­ляет­ся при неп­равиль­ном ука­зании location, как в этом конфиге:

В данном слу­чае, если обра­титься к /img../test.png, сер­вер вмес­то того, что­бы вер­нуть файл /web/data/images/test.png, выпол­нит пря­мую замену али­аса и попыта­ется вер­нуть /web/data/test.png, тем самым обхо­дя каталог images.

Да­вайте вос­поль­зуем­ся обхо­дом через каталог admin и попробуем прос­канировать сай­т. Для это­го ска­нируем адрес /admin../. Так как при обра­щении к стра­нице /admin про­исхо­дит переадресация на дру­гой сер­вер, мы увидим веб‑кон­тент внут­ренне­го сер­виса на пор­те 81.

Справка:

Что­бы отыскать скры­тое содер­жимое на сай­те, сканируем методом перебо­ра катало­гов. Лучше всего для этого подходят инструменты типа DIRB и Dirsearch.

Мне нравится маленький и шустрый ffuf. При запус­ке ука­зываем эти парамет­ры:

  • -w — сло­варь (отлично подойдет directory-list-2.3-medium);
  • -t — количес­тво потоков;
  • -u — адрес;
  • -fc — исклю­чение из резуль­тата отве­тов с кодом 403.

На выходе получаем сле­дующую команду:

Ре­зуль­тат ска­ниро­вания катало­гов с помощью ffuf
Ре­зуль­тат ска­ниро­вания катало­гов с помощью ffuf

В резуль­тате находим инте­рес­ные фай­лы. Сре­ди них попался очень важ­ный файл server-status, в нем отра­жают­ся все зап­росы к Apache. Он и рас­кры­вает нам при обра­щении до сих пор нез­накомые катало­ги:

В том чис­ле:

Со­дер­жимое фай­ла server-status
Со­дер­жимое фай­ла server-status

 

Стра­ница admin_staging
Стра­ница admin_staging

Мы смогли найти стра­ницы, на которые можно перей­ти. Если открыть Burp History, то можно увидеть, что жела­емая стра­ница переда­ется в качес­тве зна­чения парамет­ра page. А это нужно проверить, так как может быть веро­ятной уяз­вимостью вклю­чения фай­лов.

Зап­рос в Burp History
Зап­рос в Burp History

Точка опоры

Уязвимость LFI

При тес­те Local File Inclusion мож­но прос­то отдать одно­му из ска­неров дирек­торий спи­сок с соот­ветс­тву­ющи­ми наг­рузка­ми. Я для перебо­ра буду использовать Burp Intruder со сво­ими сло­варя­ми (есть готовые на GitHub).

Для начала определим наг­рузку, с помощью которой мож­но будет прос­мотреть дос­тупный для всех сис­темных юзеров файл на уда­лен­ном хос­те. В резуль­тате перебо­ра мы смогли про­читать файл /var/log/lastlog через обход дирек­торий пос­ледова­тель­ностью ../../../../../.

Ре­зуль­тат ата­ки через Burp Intruder
Ре­зуль­тат ата­ки через Burp Intruder

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

Ре­зуль­тат перебо­ра важ­ных фай­лов через LFI
Ре­зуль­тат перебо­ра важ­ных фай­лов через LFI

В резуль­тате ата­ки мы получим все­го 5 дос­тупных для прос­мотра фай­лов. Информа­ция из них нам не очень важна, но лог служ­бы FTP vsftpd.log на пригодится.

От LFI к RCE

Есть нес­коль­ко спо­собов получить уда­лен­ное выпол­нение кода (RCE), имея LFI, и один из них я сей­час покажу. Дело в том, что мы можем зас­тавить веб‑сер­вер обра­тить­ся к фай­лу логов служ­бы FTP и таким обра­зом кос­венно выпол­нить туда запись.

Нап­ример, если мы попыта­емся авто­ризо­вать­ся от лица поль­зовате­ля test_test_test, то эта стро­ка попадет в этот лог. Таким обра­зом, мы можем записать в файл код на PHP и, обра­тив­шись к это­му фай­лу через веб‑сер­вер, выпол­нить его!

Да­вайте авто­ризу­емся в служ­бе FTP, передав в качес­тве логина код, который даст нам реверс‑шелл:

За­пись шел­ла через FTP-авто­риза­цию
За­пись шел­ла через FTP-авто­риза­цию

 

Справка:

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

В таких слу­чаях при­годит­ся rlwrap — readline-обо­лоч­ка, которая в чис­ле про­чего поз­воля­ет поль­зовать­ся исто­рией команд. Она обыч­но дос­тупна в репози­тории дис­три­бути­ва.

В качес­тве самого лис­тенера при этом мож­но исполь­зовать широко извес­тный netcat.

Ос­талось толь­ко обра­тить­ся к нашему фай­лу логов, и мы тут же получим управле­ние над хос­том.

Ок­но лис­тенера netcat
Ок­но лис­тенера netcat

Продвижение

Ис­кать пути для даль­нейше­го прод­вижения мы будем с помощью скрип­тов PEASS.

Справка:

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

Что­бы вос­поль­зовать­ся скрип­том, его нуж­но сна­чала заг­рузить на локаль­ный хост.

Те­перь надо заг­рузить его на уда­лен­ный хост. В дирек­тории со скрип­том на локаль­ной машине запус­тим с помощью Python прос­той веб‑сер­вер. Пос­ле выпол­нения этой коман­ды веб‑сер­вер будет прос­лушивать порт 8000.

А теперь с помощью того же wget на целевой машине заг­рузим скрипт с локаль­ного хос­та на уда­лен­ный. Пос­ле заг­рузки необ­ходимо дать фай­лу пра­во на выпол­нение и выпол­нить скрипт.

Скрипт выводит огромное количес­тво информа­ции, сре­ди которой мне уда­лось обна­ружить сле­дующее:

  • в пла­ниров­щике задач cron от име­ни root запус­кает­ся какой‑то скрипт;
  • для локаль­ного хос­та прос­лушива­ется порт служ­бы LDAP — 389;
  • в дирек­тории opt находим какой‑то про­ект, име­ющий репози­торий Git;
  • а так­же находим хеш пароля для дос­тупа к стра­ницам Apache.
Пла­ниров­щик задач cron
Пла­ниров­щик задач cron

 

От­кры­тые пор­ты
От­кры­тые пор­ты

 

Об­наружен­ные репози­тории Git
Об­наружен­ные репози­тории Git

 

Най­ден­ные хеши
Най­ден­ные хеши

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

Со­дер­жимое фай­ла /usr/loca/bin/csvupdate_cron
Со­дер­жимое фай­ла /usr/loca/bin/csvupdate_cron

Этот скрипт обра­баты­вает фай­лы CSV во всех вло­жен­ных катало­гах дирек­тории /srv/ftp/ с помощью при­ложе­ния csvupdate. Я сра­зу уви­дел воз­можность манипу­лиро­вать парамет­ром, но, так как у нас пока нет воз­можнос­ти работать с этим катало­гом, вер­немся к нему поз­же.

Со­дер­жимое катало­га /srv/ftp/
Со­дер­жимое катало­га /srv/ftp/

Груп­па и вла­делец содер­жимого намека­ют на то, что с этим катало­гом мож­но работать, если авто­ризо­вать­ся по FTP. Зна­чит, нам нуж­ны учет­ные дан­ные поль­зовате­ля.

Поиск учетных данных

Пер­вым делом я поп­робовал переб­рать хеш в надеж­де, что пароль подой­дет и для поль­зовате­ля. Но толь­ко хеш переб­рать не уда­лось. Одна­ко у нас еще остался репози­торий Git! Как извес­тно, исходни­ки — отличное мес­то, что­бы выудить важ­ные дан­ные.

Я прос­то поис­кал все подс­тро­ки вро­де passw и secret, и это дало резуль­тат.

Ис­комые подс­тро­ки из репози­тория
Ис­комые подс­тро­ки из репози­тория

Ви­дим мно­го строк‑паролей в фай­ле /opt/pokeapi/config/settings.py. Если открыть и прос­мотреть его, то мы най­дем учет­ные дан­ные для служ­бы LDAP. А это путь для даль­нейше­го прод­вижения!

Со­дер­жимое фай­ла settings.py
Со­дер­жимое фай­ла settings.py

LDAP

LDAP (Lightweight Directory Access Protocol) — это про­токол, который исполь­зует­ся для хра­нения и получе­ния дан­ных из катало­га с иерар­хичес­кой струк­турой. Обыч­но к нему при­бега­ют для хра­нения информа­ции об орга­низа­ции, ее акти­вах и поль­зовате­лях. LDAP — это гиб­кое решение, которое мож­но при­менять для пред­став­ления раз­ных сущ­ностей и их свой­ств.

Под­клю­чим­ся и взгля­нем на всю информа­цию, которую нам вер­нет базовый каталог. Для под­клю­чения ука­жем ldapsearch сле­дующие парамет­ры:

  • -x — исполь­зовать прос­тую аутен­тифика­цию;
  • -D — путь навига­ции для под­клю­чения;
  • -w — пароль;
  • -h — хост;
  • -b — базовый путь, по которо­му выпол­няет­ся поиск.

Свой­ства поль­зовате­ля pwnmeow
Свой­ства поль­зовате­ля pwnmeow

Мы получи­ли все свой­ства поль­зовате­ля pwnmeow, сре­ди которых есть закоди­рован­ный пароль.

Па­роль поль­зовате­ля pwnmeow
Па­роль поль­зовате­ля pwnmeow

Но под­клю­чить­ся по SSH с этим паролем не выш­ло. Ока­зыва­ется, флаг мож­но было заб­рать сра­зу, так как его груп­па‑вла­делец — www-data.

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

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

За­то получен­ный пароль поз­воля­ет авто­ризо­вать­ся на FTP. При­чем мы ока­зыва­емся имен­но в нуж­ной дирек­тории, с пра­вом записи.

Под­клю­чение к служ­бе FTP
Под­клю­чение к служ­бе FTP

Те­перь вер­немся к экс­плу­ата­ции уяз­вимос­ти, а имен­но к фай­лу:

Со­дер­жимое фай­ла /usr/loca/bin/csvupdate_cron
Со­дер­жимое фай­ла /usr/loca/bin/csvupdate_cron

В цик­ле вмес­то перемен­ной $d будут пооче­ред­но встав­лять­ся име­на катало­гов из дирек­тории:

Так­же сто­ит обра­тить вни­мание на фун­кцию basename, которая вер­нет стро­ку пос­ле пос­ледне­го сле­ша, нап­ример:

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

Слож­ность здесь в том, что нуж­но при­думать такой спо­соб повыше­ния при­виле­гий, что­бы в коман­де не встре­чались сле­ши. И я нашел спо­соб — соз­дать нового поль­зовате­ля‑адми­нис­тра­тора вот такой коман­дой:

Тут мы соз­даем поль­зовате­ля с UID и GID, рав­ными нулю (поль­зователь root), с паролем ralf8888 и име­нем ralf. Тог­да имя фай­ла дол­жно быть таким:

Соз­дание фай­ла через FTP
Соз­дание фай­ла через FTP

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

Со­дер­жимое фай­ла /etc/passwd
Со­дер­жимое фай­ла /etc/passwd

 

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

Ма­шина Hack The Box Pikaboo прой­дена. Мы взломали nginx. Спасибо ralf!

Еще по теме: Взлом сайта на PHP с помощью уязвимости XXE

Дима (Kozhuh)

Эксперт в кибербезопасности. Работал в ведущих компаниях занимающихся аналитикой компьютерных угроз. Анонсы новых статей в Телеграме.

Добавить комментарий