Прошел почти год с того момента, как я написал свою первую сатью на Хабр. Начал этот путь именно с разбора задания MCTF 2021. Решил продолжить традицию в этом году и написать writeup на интересный таск с MCTF 2022.
Обзор
Для начала перейдем на сайт с заданием и посмотрим его структуру.
Из кликабельных элементов пока заметна только кнопка "Логин". Нажмем на нее и посмотрим, что будет.
Открывается страница авторизации. Можно пробовать проверить на XSS- и SQL-инъекции, но результата это не даст (еще не время для кавычек). Нужно искать другой путь.
Вспоминаем про название таска - "Dirty logs".
Попробуем перейти по адресу http://mctf.ru:7777/logs.
Странно, но это сработало, изучим логи и подумаем, что делать дальше...
Проникаем в систему
Похоже на результат журналирования событий нашей страницы авторизации. Набор данных содержит логины пользователей и пароли, при неуспешной попытки аутентификации. Мне сразу бросился в глаза товарищ "v_ozerov", по попыткам которого можно сделать предположение, что он просто не может правильно написать свою парольную фразу.
Попробуем ввести его возможный пароль и пройти аутентификацию с кредами v_ozerov/HeadOfTheCity
. Удалось попасть в "яблочко" с первого раза.
Креды для входа оказались верными - идем дальше!
А дальше мы попадаем на страницу http://mctf.ru:7777/dashboard.
Изучаем систему
Теперь, когда мы в системе, давайте посмотрим, что тут вообще происходит. Есть какие-то "События", "Аварии" и "Загрязнение".
По нажатию кнопки "Вывести данные" - выводятся данные (очень логично). Для пользовательского ввода доступно только поле "Дата" в формате даты (и снова логично). То есть ничего кроме цифр даты мы ввести туда не можем.
Обычно такие ограничения реализованы только на стороне клиента, а не сервера, если сайт написан на коленке. Чтобы это проверить, нужно как-то перехватить запрос пользователя, модифицировать его и отправить на сервер - запускаем Burp Suite!
Пробуем модифицировать запросы
Заранее оговорю тот момент, что подробно рассказывать о том, что такое Burp Suite и как им пользоваться я не буду. Это тема целой статьи, да и мануалов в Интернете достаточно. Итак, приступим...
В Burp Suite переходим в раздел "Proxy" и нажимаем "Open Browser".
Переходим в открывшемся браузере на страницу с дашбордом http://mctf.ru:7777/dashboard (перед этим необходимо пройти авторизацию или просто использовать токен из прошлой сессии).
Затем, когда мы попали на дашборд - начинается самое интересное.
Нажимаем в Burp Suite "Intercept is off", чтобы сменить режим для перехвата запросов, и в браузере жмем "Вывести данные" в любом из разделов.
Снова открываем Burp Suite и видим в главном окне содержимое нашего перехваченного, еще не отправленного на сервер, запроса.
Жмем в любой из строке тела запроса ПКМ и выбираем "Send to Repeater".
После этого переходим на вкладку "Repeater" и нажимаем "Send".
Запрос успешно выполнился, результат в правой части окна. Данная вкладка позволяет изменять содержимое запроса и отправлять его снова и снова (опять логично, это же Repeater).
Как видно из запроса, нам действительно доступен только один параметр - date (дата, которую мы можем выбрать в веб-интерфейсе). Мы можем проверить логику приложения и передать в этот параметр дату, но мы сразу приступим к активной фазе - передадим в параметре date обычную "кавычку".
Вводим в запрос date='
и нажимаем "Send".
Результат выполнения запроса выдает нам ошибку обработки команды и полностью подтверждает нашу теорию о том, что пользовательский ввод ограничен только на стороне клиента. Но почему именно кавычку? Пентестеры же любят "пихать" кавычки, а если серьезно, до ввода кавычки у меня не получилось заставить сервер хоть что-то внятное мне ответить. Не стал долго думать и "пихнул" - считаю оправданно!
Готовим payload
Как видно из ошибки, параметр запроса date передается на вход Linux-команде (интерпретатора bash) grep на сервере, которая ищет соответствующий паттерн в определенном файле и выводит результат выполнения Linux-командой echo.
При штатном поведении пользователя, при выборе в веб-интерфейсе даты, она передается аргументом команды grep и пользователю выдается список найденых по дате событий.
На лицо атака типа Command Injection. Проблема заключается в том, что аргумент команды grep, куда попадает наш параметр, экранируется с двух сторон одинарными "кавычками". Необходимо подготовить payload имея следующий паттерн:
grep '<payload_в_date>' /home/server/data/events.txt || echo ""
Из того, что пришло мне в голову - надо как-то выйти за пределы "кавычек" и выполнить произвольную команду. Немного пофантазировав и поигравшись с параметрами, удалось скрафтить следующую конструкцию:
grep '.' *;grep '.' /home/server/data/events.txt || echo ""
где, .' *;grep '.
- и есть наш payload.
Следуя логике полученной конструкции, в результате успешного выполнения запроса, нам должно показать содержимое всех файлов в текущей директории и содержимое файла events.txt. Проверяем...
В Burp Suite в тело запроса пишем date=.' *;grep '.
, нажимаем "Send".
О чудо! Нам вывели содержимое всех файлов в текущей директории.
Продвигаемся дальше, давайте посмотрим список пользователей в домашней директории /home
, для чего в теле запроса пишем date=.' /home/*;grep '.
Получаем localuser и server.
Посмотрим что есть у пользователя localuser - date=.' /home/localuser/*;grep '.
Видим еще две директории: Classified и programs.
Посмотрим что есть в первой директории Classified - date=.' /home/localuser/Classified/*;grep '.
И получаем флаг - MCTF{D@RkZ3r5K-iS_w@1ch1ng}
Заключение
Таким образом, наш боевой payload выглядит следующим образом:
date=.' /home/localuser/Classified/*;grep '.
, благодаря которому на стороне сервера выполняется команда:
grep '.' /home/localuser/Classified/*;grep '.' /home/server/data/events.txt || echo ""
Надеюсь, что читателям понравится данный writeup. Как и для всех заданий в CTF, не исключаю возможности более быстрого и лаконичного решения. Данная статья - это лишь описание хода моих мыслей при решении.
Тем, кто не смог решить данный таск, желаю не расстраиваться, а взять технику "пихать кавычку везде,где только можно" себе на вооружение!