Автор: @cherepawwka
Источник: RCE via PHP with WAF bypass
Ссылка на таск Codeby
https://codeby.games/categories/web/77ba004a-f986-47ad-86d7-f9bc6bbe1f34
Описание задания
Мой друг говорит, что разработал абсолютно неуязвимое веб-приложение. Звучит как вызов…
IP: 62.173.140.174:16019
Решение
Всем привет!
Сегодня мы решим таск средней сложности “Обходной путь” с платформы CodeBy Games, получив RCE из уязвимого PHP скрипта, осуществляющего некоторую проверку входных данных.
Поиск уязвимости
Перейдем по предложенному URL (http://62.173.140.174:16019/):
Нас встречает форма ввода, где сразу же показан пример рабочей нагрузки. При вводе строки echo 'hello';
на экране появится слово “hello”:
Вероятнее всего, перед нами PHP (echo
, точка с запятой после команды). Следовательно, нужно попытаться эксплуатировать это знание. Из описания и тэга title мы понимаем, что приложение реализует какие-то методы защиты (скорее всего “кастомный WAF”, фильтрующий некоторые входные данные). Зная, что в PHP могут быть отключены некоторые функции (об этом я писал в своей прошлой статье), тут может использоваться схожий механизм защиты. В первую очередь попробуем собрать информацию и вручную пофаззить приложение, чтобы понять, что именно и как фильтруется.
Для начала на дурака попробуем исполнить какой-нибудь код. Гуглим, получаем информацию о том, как это возможно сделать:
Пробуем:
Не прокатило. Оно и неудивительно, иначе бы всё было слишком просто.
В PHP есть замечательная функция phpinfo()
, позволяющая получить максимум информации о конфигурации PHP на сервере. Попробуем внедрить её:
Результат
Отлично! В первую очередь узнаем имя скрипта:
и также посмотрим информацию в поле disable_functions:
Отлично, здесь опасные функции не отключены, следовательно, они фильтруются. Раз мы знаем имя скрипта, попробуем получить его содержимое. Сделать это можно следующим образом:
Попробуем осуществить этот запрос:
Ответ
Посмотрим его в Burp Proxy:
Бинго! Теперь мы знаем, как именно фильтруется вводимое нами содержимое. Мы видим, что запрещённый контент перечислен в массиве $bad_words
:
$bad_words = array('system', 'exec', 'passthru', 'shell_exec', 'ls', 'wget', 'nc', 'passwd');
Вводимый же код исполняется благодаря функции eval():
<?php if (isset($code)) echo eval($code); ?>
Обладая этими знаниями, начнем байпассить фильтры, чтобы получить RCE!
Эксплуатация
Да, конечно, фильтруется немало полезных слов и функций. Однако, это далеко не полный список, и у нас остаётся козырь в кармане.
Так, запрос echo `whoami`;
должен вернуть нам имя пользователя, под которым работает веб-приложение. Попробуем внедрить код таким образом:
Ответ
Отлично, мы обошли обнаруженные фильтры и исполнили код на стороне сервера. Осталось лишь погулять по файловой системе и получить флаг. Но команда ls
нам недоступна, так как она фильтруется. Казалось бы, придётся снова фаззить… Но нет, есть способ обойти это ограничение. Фильтруется именно вхождение символов ls
, но это обходится благодаря добавлению слэша — l\s
:
Возьмем прошлый запрос с whoami из истории Burp Proxy, поместим его в Repeater и начнем инжектить код:
Мы получили содержимое каталога, но флага тут нет. Поищем дальше. Вспомним, что таск называется “Обходной путь”, следовательно, попробуем погулять по директориям:
Проверка содержимого директории выше
Находим интересный файл .secret, доступный на чтение всем пользователям. Прочитаем его содержимое (можно двумя способами: echo `cat ../.secret`;
и readfile('../.secret');
). Я покажу оба.
Запрос через функцию readfile()
:
Ответ
Запрос через command injection:
Получаем заветный флаг и 350 очков в копилку!
На этом разбор подошёл к концу. Уверен, что это не единственный способ обхода фильтров и решения задания, так что любое другое решение только приветствуется.
До новых встреч!
Tags: