Прошел почти год с того момента, как я написал свою первую сатью на Хабр. Начал этот путь именно с разбора задания 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.

Посмотрим что есть у пользователя 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, не исключаю возможности более быстрого и лаконичного решения. Данная статья - это лишь описание хода моих мыслей при решении.

Тем, кто не смог решить данный таск, желаю не расстраиваться, а взять технику "пихать кавычку везде,где только можно" себе на вооружение!

Комментарии (6)


  1. xi-tauw
    31.10.2022 22:34

    Коллектив авторов задачи передает привет, и благодарит за райтап.


    1. toxella Автор
      02.11.2022 13:36

      Благодарю, ждём новых задач!


  1. Mingun
    01.11.2022 18:06

    Эм, а зачем специализированный инструмент-то нужен был? Насколько я понял, открытть инструменты разработчика в том же Firefox'е было бы и проще и быстрее. Навскидку два варианта:


    1. На вкладке «Сеть» Изменить и снова отправить нужный запрос с внесёнными изменениями.
    2. Возможно, прокатило бы просто сменить тип поля ввода на text вместо date (который там, судя по скриншоту, установлен). В этом случае полезную нагрузку можно было бы невозбранно писать прямо в удобном поле ввода.


    1. toxella Автор
      02.11.2022 13:34

      Да вы можете хоть curl использовать для решения этой задачи, никто Вам не запрещает. Так же еще проще - даже GUI не надо запускать :)

      Я же писал в статье, что описывал свои действия и мысли во время CTF, а при решении заданий из WEB-категорий - я использую бурп, так как вектор решения не всегда понятен сразу.

      Действительно, решить можно и с использованием браузера, однако репитер в бурпе позволяет удобнее делать повторяющиеся операции и сразу наблюдать результат, имхо


      1. Mingun
        02.11.2022 17:21

        Просто из вашего описания задачи у меня сложилось впечатление, что вы скачали этот «бурп» только ради перехвата и повтора запросов для этой конкретной задачи. А он, у вас, оказывается уже стоял:


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

        О как! Сразу видно — солидный инструмент, аж целый Suite :)! Для меня эта фраза прозвучала как:


        А теперь давайте вычислим 2 + 2. Запускаем Matlab…


  1. Defend1
    02.11.2022 13:42

    Просто топ!!!