Приветствую!
В новой статье мы рассмотрим финальное задание в модуле Command Injection с платформы HTB и обсудим различные техники обхода фильтрации запросов. Приступим к разбору!
Немного теории
Command injection — это вид атаки, целью которой является выполнение произвольных команд в операционной системе хоста через запущенное на нем уязвимое приложение.
Если веб-приложение использует непроверенные пользовательские данные для формирования и выполнения системных команд на сервере, и злоумышленник может внедрить в эти данные произвольные команды, то это явно намекает на уязвимость Command Injection.
Суть атаки заключается в том, что специальные символы или конструкции, добавленные злоумышленником в пользовательский ввод (такие как ;, |, &&, ||), некорректно интерпретируются командной оболочкой сервера не как данные, а как часть исполняемой команды. Это позволяет нарушить первоначальную логику приложения, изменить ожидаемый поток выполнения и заставить сервер исполнить произвольные, часто вредоносные команды от имени веб-сервиса. В результате злоумышленник может получить несанкционированный доступ к данным, повысить привилегии или получить контроль над серверной инфраструктурой.
Простой и наглядный пример с сайтами для выполнения команды ping:
ping 127.0.0.1 | whoami
Командная оболочка интерпретирует символ "|" как оператор конвейера и запускает обе команды. Хотя whoami игнорирует данные, которые получает от ping, она успешно выполняется и выводит имя пользователя, под которым работает веб-сервер. Это происходит исключительно из-за отсутствия фильтрации специальных символов в пользовательском вводе, что позволяет злоумышленнику произвольно расширять исходную команду, предназначенную только для ping.
Решаем Skills Assessment
Сначала нам предоставляют учётные данные для входа в систему: guest:guest
При входе видим интерфейс Tiny File Manager. При изучении уязвимостей файлового менеджера Tiny никаких PoC с Command Injection я не нашёл. Будем искать руками!
Тут я остановился чтобы просто изучить функционал сайта и посмотреть историю запросов Burp Suite. Чуть позже обнаружил кнопку, которая управляет перемещением файлов.
Для начала попробуем скопировать файл в директорию /tmp.
Всё корректно отработало!
Однако эта фича файлового менеджера походу неуязвима к Command Injection. Что бы я ни пробовал внедрить — сервер на вредоносные запросы не ругается, но и команды не выполняются.
Поэтому далее моё внимание перешло на функционал Move.
И этот запрос выполнился корректно! Заглянем в Burp, чтобы изучить его подробнее:
В случае, если бы запрос выполнился с ошибкой, то мы бы получили следующее сообщение, что и намекает на прямое выполнение команды mv:
Error while moving: mv: '/var/www/html/files/51459716.txt' and '/var/www/html/files/51459716.txt' are the same file
Далее в Intruder я перебрал различные спец. символы, которые применимы для Command Injection и посмотрел на какие сервер отреагирует без фырканья:
На символы, заблокированы WAF сервер отвечал "Malicious request denied". По этому ответу как раз и удалось найти обход фильтра:
Сервер не ругался на большинство спец. символов. Для разделения валидной команды нам вполне хватит "&".
По сути, нам нужно ввести команду & cat /flag.txt и дело в шляпе, но хоть сервер не ругается на символ в начале инъекции, команда всё ещё не выполняется.
В итоге наша инъекция приобрела следующий вид для срабатывания:
- %26c"a"t$IFS${PATH:0:1}flag.txt
- $IFS%26c"a"t$IFS${PATH:0:1}flag.txt
- %26b"a"sh<<<$(base64%09-d<<<Y2F0IC9mbGFnLnR4dA==)
- $IFS%26b"a"sh<<<$(base64%09-d<<<Y2F0IC9mbGFnLnR4dA==)
Все эти варианты сработают и дадут флаг. Разберём как нам удалось обойти фильтры и что мы применяли в этой сложной инъекции:
$IFS
Использование переменной среды Linux ($IFS) по умолчанию она содержит пробел и табуляцию, которые можно использовать между аргументами команды. Таким образом, если мы используем ${IFS} там, где должны быть пробелы, переменная будет автоматически заменена на пробел, и наша команда заработает.
%26
%26 - это URL-кодировка символа &
c"a"t
Один из самых распространённых и простых способов обфускации — вставка в команду определённых символов, которые обычно игнорируются командными оболочками, например Bash или PowerShell, и команда выполняется так, как будто этих символов нет. К таким символам относятся одинарные кавычки ' и двойные кавычки ", а также некоторые другие.
Проще всего использовать кавычки, они работают как на серверах Linux, так и на серверах Windows. Например, если мы хотим запутать команду whoami, мы можем вставить одинарные кавычки между её символами следующим образом: w'h'o'am'i --> root
То же самое работает и с двойными кавычками: w"h"o"am"i --> root
${PATH:0:1}
PATH — переменная окружения, содержащая пути поиска исполняемых файлов (например: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin)
Если вбить в терминале команду echo ${PATH}, то получим /usr/local/bin:/usr/bin:/bin:/usr/games
Если мы начнём с символа 0 и возьмём строку длиной 1, то в итоге у нас останется только символ /, который мы можем использовать в полезной нагрузке:
echo ${PATH:0:1} --> /
Y2F0IC9mbGFnLnR4dA==
Y2F0IC9mbGFnLnR4dA== это кодирванная в base64 команда cat /flag.txt:
echo "Y2F0IC9mbGFnLnR4dA==" | base64 -d --> cat /flag.txt
%09-d
%09 - табуляция в URL-кодировке
-d - ключ для команды base64 (декодирование)
<<<
<<< — это оператор here-string в bash и других современных shell (zsh, ksh). Это способ передать строку как входные данные (stdin) команде без использования pipe (|) или временного файла.
$()
$() — это синтаксис в bash и других командных строках. Он выполняет команду внутри скобок и подставляет результат ее выполнения вместо всего выражения.
Выводы
Данный модуль с Hack The Box намного интереснее ранее решённых кейсов с PortSwigger. Тут больше упор на обход фильтрации и детектирование уязвимости.
В данном кейсе уязвимость стала возможной за счёт прямого выполнения Linux-команды mv в PHP-коде. Второй фактор, который тоже повлиял на захват учебной машины, — слабая фильтрация запросов на перемещение файлов в менеджере.
За счёт ответов сервера мы смогли выявить, какие символы не фильтруются WAF-ом, и смогли внедрить инъекцию. Именно поэтому ответы об ошибках лучше скрывать. Это исключит возможность фаззинга.
Спасибо за внимание! Не забывайте оценивать моё творчество лайком. Всех благ!