Разбор таска Dirty logs с M*CTF 2022 или как желание пихнуть кавычку помогает решать CTF

от автора

Прошел почти год с того момента, как я написал свою первую сатью на Хабр. Начал этот путь именно с разбора задания MCTF 2021. Решил продолжить традицию в этом году и написать writeup на интересный таск с MCTF 2022.

Обзор

Для начала перейдем на сайт с заданием и посмотрим его структуру.
Из кликабельных элементов пока заметна только кнопка «Логин«. Нажмем на нее и посмотрим, что будет.

http://mctf.ru:7777/
http://mctf.ru:7777/

Открывается страница авторизации. Можно пробовать проверить на XSS- и SQL-инъекции, но результата это не даст (еще не время для кавычек). Нужно искать другой путь.

http://mctf.ru:7777/auth
http://mctf.ru:7777/auth

Вспоминаем про название таска — «Dirty logs«.

Попробуем перейти по адресу http://mctf.ru:7777/logs.

http://mctf.ru:7777/logs
http://mctf.ru:7777/logs

Странно, но это сработало, изучим логи и подумаем, что делать дальше…

Проникаем в систему

Похоже на результат журналирования событий нашей страницы авторизации. Набор данных содержит логины пользователей и пароли, при неуспешной попытки аутентификации. Мне сразу бросился в глаза товарищ «v_ozerov«, по попыткам которого можно сделать предположение, что он просто не может правильно написать свою парольную фразу.

Похоже, что товарищ Озеров не может правильно написать фразу HeadOfTheCity
Похоже, что товарищ Озеров не может правильно написать фразу HeadOfTheCity

Попробуем ввести его возможный пароль и пройти аутентификацию с кредами v_ozerov/HeadOfTheCity. Удалось попасть в «яблочко» с первого раза.
Креды для входа оказались верными — идем дальше!

А дальше мы попадаем на страницу http://mctf.ru:7777/dashboard.

http://mctf.ru:7777/dashboard
http://mctf.ru:7777/dashboard

Изучаем систему

Теперь, когда мы в системе, давайте посмотрим, что тут вообще происходит. Есть какие-то «События«, «Аварии» и «Загрязнение».
По нажатию кнопки «Вывести данные» — выводятся данные (очень логично). Для пользовательского ввода доступно только поле «Дата» в формате даты (и снова логично). То есть ничего кроме цифр даты мы ввести туда не можем.

Пользовательский ввод веб-интерфейса
Пользовательский ввод веб-интерфейса

Обычно такие ограничения реализованы только на стороне клиента, а не сервера, если сайт написан на коленке. Чтобы это проверить, нужно как-то перехватить запрос пользователя, модифицировать его и отправить на сервер — запускаем Burp Suite!

Пробуем модифицировать запросы

Заранее оговорю тот момент, что подробно рассказывать о том, что такое Burp Suite и как им пользоваться я не буду. Это тема целой статьи, да и мануалов в Интернете достаточно. Итак, приступим…
В Burp Suite переходим в раздел «Proxy» и нажимаем «Open Browser«.

Раздел "Proxy" в Burp Suite
Раздел «Proxy» в Burp Suite

Переходим в открывшемся браузере на страницу с дашбордом 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».

Пробуем наш payload
Пробуем наш payload

О чудо! Нам вывели содержимое всех файлов в текущей директории.
Продвигаемся дальше, давайте посмотрим список пользователей в домашней директории /home, для чего в теле запроса пишем date=.' /home/*;grep '.

Программа выполнилась с ошибкой, но дала нам полезную информацию о названии директорий
Программа выполнилась с ошибкой, но дала нам полезную информацию о названии директорий

Получаем localuser и server.

Посмотрим что есть у пользователя localuserdate=.' /home/localuser/*;grep '.

Видим еще две директории: Classified и programs.
Посмотрим что есть в первой директории Classifieddate=.' /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, не исключаю возможности более быстрого и лаконичного решения. Данная статья — это лишь описание хода моих мыслей при решении.
Тем, кто не смог решить данный таск, желаю не расстраиваться, а взять технику «пихать кавычку везде,где только можно» себе на вооружение!


ссылка на оригинал статьи https://habr.com/ru/post/696586/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *