Категория > Новости > HTB Timing. Пентестим веб-сервер на PHP - «Новости»

HTB Timing. Пентестим веб-сервер на PHP - «Новости»


10-06-2022, 00:00. Автор: Радислав
Hack The Box.

warning


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



 

Разведка


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


10.10.11.135 timing.htb

И запус­каем ска­ниро­вание пор­тов.



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


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


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


ports=$(nmap -p- --min-rate=500 $1 | grep^[0-9] | cut -d '/' -f 1 | tr 'n' ',' | sed s/,$//)nmap -p$ports -A $1

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



HTB Timing. Пентестим веб-сервер на PHP - «Новости»
Ре­зуль­тат работы скрип­та

Наш­ли два откры­тых пор­та:



  • 22 — служ­ба OpenSSH 7.6p1;

  • 80 — веб‑сер­вер Apache 2.4.29.


На SSH нам ловить нечего, про­пус­каем его.



Справка: брутфорс учеток


Пос­коль­ку вна­чале у нас нет учет­ных дан­ных, нет и смыс­ла изу­чать служ­бы, которые всег­да тре­буют авто­риза­ции (нап­ример, SSH). Единс­твен­ное, что мы можем делать здесь, — это переби­рать пароли брут­форсом, но машины с HTB поч­ти всег­да мож­но прой­ти по‑дру­гому. В жиз­ни таких вари­антов может не быть, к тому же есть шан­сы подоб­рать пароль или получить его при помощи соци­аль­ной инже­нерии.



Пос­мотрим, что нам покажет веб‑сер­вер. При обра­щении к нему про­исхо­дит редирект на стра­ницу /login.php, где нас встре­чает фор­ма авто­риза­ции.


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

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



Справка: сканирование веба c ffuf


Од­но из пер­вых дей­ствий при тес­тирова­нии безопас­ности веб‑при­ложе­ния — это ска­ниро­вание методом перебо­ра катало­гов, что­бы най­ти скры­тую информа­цию и недос­тупные обыч­ным посети­телям фун­кции. Для это­го мож­но исполь­зовать прог­раммы вро­де dirsearch и DIRB.


Я пред­почитаю лег­кий и очень быс­трый ffuf. При запус­ке ука­зыва­ем сле­дующие парамет­ры:




  • -w — сло­варь (я исполь­зую сло­вари из набора SecLists);


  • -t — количес­тво потоков;


  • -u — URL;


  • -fc — исклю­чить из резуль­тата отве­ты с кодом 403.


За­пус­каем его с нуж­ными парамет­рами:


ffuf -uhttp://timing.htb/FUZZ -t 256 -wphp_files_common.txt
Ре­зуль­тат ска­ниро­вания фай­лов PHP

Наш­ли мно­го фай­лов, теперь прос­каниру­ем и скры­тые катало­ги.


ffuf -uhttp://timing.htb/FUZZ -t 256 -wdirectory_2.3_medium_lowercase.txt
Ре­зуль­тат ска­ниро­вания скры­тых катало­гов

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


ffuf -u 'http://timing.htb/image.php?FUZZ=../image.php' -t 256 -wparameters.txt -fs 0
Ре­зуль­тат ска­ниро­вания парамет­ра

Мы наш­ли один параметр — img. То есть мы можем зап­росить файл с кар­тинкой по его наз­ванию. Поп­робу­ем таким спо­собом ута­щить какой‑нибудь сис­темный файл, задав отно­ситель­ный путь.


Со­обще­ние, что обна­руже­на ата­ка

Нас пой­мали за руку!


 

Точка входа


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


/image.php?img=php://filter/convert.base64-encode/resource=index.php


Справка: LFI в PHP


Local file inclusion (LFI) — тех­ника, которая исполь­зует­ся для получе­ния дос­тупа к фай­лам в сис­теме через веб‑сер­вер. Что­бы сер­вер отоб­разил файл, а не попытал­ся его выпол­нить, ему нуж­но передать «обер­тку» — коман­ды, которые закоди­руют файл. Пос­ле его получе­ния оста­нет­ся лишь рас­кодиро­вать его обратно. Сущес­тву­ет мно­жес­тво го­товых обер­ток, которые ты можешь при­менять при пен­тесте.



Со­дер­жимое этой стра­ницы, получен­ной в ответ, будет закоди­рова­но в Base64. Декоди­ровать мож­но пря­мо Burp, нажав Ctrl-Shift-B.


По­луче­ние кода стра­ницы index.php

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


Ис­ходный код login.php

В нем ничего инте­рес­ного нет, кро­ме под­клю­чения фай­ла db_conn.php (стро­ка 10). Здесь мы находим учет­ку для под­клю­чения к базе дан­ных. Конеч­но же, прос­мотрим и его.


Ис­ходный код db_conn.php

Па­роль пока ни к чему не подошел, поэто­му копа­ем даль­ше. Перей­дем к фай­лам, о которых мы уже зна­ем. Нач­нем с upload.php.


Ис­ходный код upload.php

В самом начале под­клю­чает­ся файл admin_auth_check.php. Затем зада­ются необ­ходимые парамет­ры для заг­ружен­ного фай­ла, в том чис­ле и file_name. Имя фай­ла соз­дает­ся по сле­дующе­му алго­рит­му: берет­ся стро­ка '$file_hash', затем добав­ляет­ся текущее вре­мя (резуль­тат выпол­нения фун­кции time()), все это кон­верти­рует­ся в хеш MD5, а даль­ше добав­ляет­ся знак ниж­него под­черки­вания и имя фай­ла, которое исполь­зовалось при заг­рузке. При этом файл дол­жен иметь рас­ширение jpg. А в фай­ле admin_auth_check.php толь­ко срав­нива­ется роль поль­зовате­ля.


Ес­ли бы $file_hash кто‑то по ошиб­ке не обер­нул в кавыч­ки, то под­ста­вилось бы зна­чение перемен­ной, получен­ное от PHP-фун­кции uniqid(). Раз­гадать уни­каль­ный иден­тифика­тор у нас бы не выш­ло, а без него единс­твен­ной прег­радой будет вывод фун­кции time().


Ис­ходный код admin_auth_check.php

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


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

Перейти обратно к новости