Привет читателям блога компании DeteAct!

Меня зовут Омар Ганиев, многие меня знают по нику «Beched».

Во время проведения пентестов и анализа защищённости мы иногда обнаруживаем необычное поведение какой-то системы, которое может приводить к интересным явлениям.

Одной из таких интересных для меня тем являются атаки, которые путём выведения из строя какой-то из частей системы позволяют повысить привилегии, обойти средство защиты и даже исполнить произвольный код.

Давно думаю о том, чтобы систематизировать такие атаки, а пока расскажу про 3 конкретных атаки из практики пентеста.

DoS to RCE или 0-day в WordPress

В далёком 2017 году во время CTF-соревнования в Японии мы с сокомандниками из LC↯BC сидели в лобби отеля посреди ночи и решали задачки.

Пытаясь решить одну из них, я заметил интересное поведение Wordpress: при многопоточных попытках подобрать пароль (/wp-login) сервер через некоторое время начинал отдавать неполные ответы, а спустя несколько десятков запросов возвращал ответ 302 и перенаправлял на страницу установки блога (/wp-admin/install.php).

В ту ночь это поведение осталось загадкой, но позже удалось разобраться, что тот сайт был размещён на shared хостинге, и там существовало ограничение на количество запросов к MySQL (MAX_QUERIES_PER_HOUR).

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

Более того, Wordpress проверяет статус установки блога путём запрашивания некоторых таблиц из базы, так что получалось, будто блог не установлен. Проверочных запросов несколько десятков, и все они должны вернуть ошибку, чтобы функция is_blog_installed вернула false.

Уязвимый исходный код функции is_blog_installed
Уязвимый исходный код функции is_blog_installed

Отсюда возникает идея для атаки: что если звёзды так совпадут, что мы сможем вывести базу из строя ровно на то время, пока выполняется функция is_blog_installed, а потом сразу вернём её к жизни?

В таком случае мы сможем перейти к процедуре установки блога, а там одним из первых действий является добавление нового административного пользователя в базу.

Таким образом, DoS-атака может привести к повышению привилегий, а затем к исполнению произвольного кода (RCE) из админки!

Суть уязвимости в том, что в коде Wordpress не было проверки, какую именно ошибку вернул сервер MySQL, поэтому считалось, что таблицы не существует, даже если в ответ на DESCRIBE попросту не пришёл ответ, или в ответе была ошибка про превышение лимита запросов.

Схематично основные шаги атаки можно изобразить так:

Схема получения контроля над Wordpress через DoS
Схема получения контроля над Wordpress через DoS

Сценарий атаки ужасно сложный и весьма интересный: не очень понятно, как можно классифицировать такой недостаток.

Я хотел написать PoC-эксплойт, но ограничился ручной проверкой возможности такой атаки в синтетических лабораторных условиях. В итоге, отложив исследование в долгий ящик, вернулся к нему только в 2019 году и решил отрепортить в Wordpress: уязвимость была исправлена только через год и получила номер CVE-2020-28037.

DoS to Bypass или как обойти WAF

Помимо анализа защищённости, мы иногда проводим DDoS-тестирование приложений. Зачастую приложения защищены фаерволами, что создаёт интересные эффекты.

Одной из основных проблем решений класса WAF является производительность. Они пытаются анализировать весь трафик веб-приложения, чтобы найти в нём признаки атак, а это вычислительно сложная задача..

В ходе DDoS-тестов мы не раз сталкивались с тем, что под высокой нагрузкой фаервол падает раньше сайта.

К чему это приводит?

Если инфраструктура сконфгурирована так, что фаервол стоит "в разрыв", то тогда ложится вся система.

Если же фаервол стоит "сбоку", то сайт продолжает быть доступен, но при этом фаервол больше не работает! А значит, атакующие могут свободно искать и эксплуатировать уязвимости в приложении без блокировок со стороны WAF.

О каких нагрузках идёт речь? На практике всё очень сильно зависит от конфигурации, но даже простейший HTTP-флуд может повалить топовый WAF при скорости атаки около 300 Мбит/сек.

Лог чекера WAF в ходе DDoS-атаки
Лог чекера WAF в ходе DDoS-атаки

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

DoS to Admin или как обойти авторизацию

Уязвимости, связанные с DoS, часто всплывают самым неожиданным образом.

Так, в ходе тестирования одного приложения, мы получили от заказчика Swagger-описание API. Для начала мы провели стресс-тест и при помощи скрипта отправили все примеры запросов оттуда через Burp Suite.

Просматривая историю запросов в Burp мы заметили аномалию: один из запросов в административный интерфейс вернул ответ 200 OK.

При попытке повторить его мы получали ответ 401 Not Authorized, как и ожидалось. В какой-то момент мы поняли, что аномалия могла быть связана с нагрузкой, и решили попробовать ещё раз.

Отправив тот же запрос много раз в цикле, мы вдруг начали получать хороший ответ!

На скриншоте видно, что после 140 запросов сервер "сдался" и впустил нас в админку, как в анекдотах про китайских хакеров и пароль "Мао Цзэдун".

Обход авторизации через DoS
Обход авторизации через DoS

Интересно, что в ответе видно заголовок "DoSFilter: delayed": это признак использования сервлета DoSFilter в сервере Jetty.

Как можно предположить, и как подтвердилось в ходе общения с заказчиком, для авторизации в API использовался отдельный сервис

Иронично, но под атакой этот сервис переставал работать из-за механизма отказоустойчивости, при этом приложение интерпретировало такой ответ как успешную авторизацию.

DoS to Anything

Отказ в обслуживании какой-то части системы может привести к самым разным неожиданным последствиям.

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

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


  1. EminH
    21.09.2021 13:10

    Почему-то думал что скрипт проверяет наличие wp-admin/install.php и рекомендует его удалять (что я всегда делал). Почитал доки, оказывается, нет, его можно было оставлять (я, видимо, с каким то другим CMS перепутал)


    1. Beched Автор
      21.09.2021 13:32
      +1

      Именно, в большинстве CMS установочный скрипт нужно удалять, но в Wordpress -- нет =)