Не удалось прогрузить медиа
Вступление
Всем привет. Это продолжение статьи по теме состояния гонки в веб приложениях. В прошлой части мы рассмотрели прохождение лаб на портсвиггере и репорты на реальных примерах к каждой. В этой части я хочу показать рейс кондишн на рандомных таргетах, какие я выцепил на просторах интернета. В основном мы будем говорить об обходе рейт лимитов на таргетах, так как это наиболее распространенная проблема. Из за того что рейт лимиты при состоянии гонки обходятся довольно криво статья будет более полезна для баг хантеров. Статья получилась довольно интересной и информативной, давайте начнём
Как я искал таргеты для статьи?
Практика - необходимая часть для хорошего изучения чего-то нового, поэтому можете тестировать все на живых целях как и я
- Fofa
body="Sign up with phone number"
body="forgot password"
body="sign in"
body="send otp"
В запросах и ответах существуют заголовки, какие показывают максимальное количество запросов, которое разрешено выполнить в текущем окне времени (это нужно для дальнейших демонстраций). Поэтому вы можете через && header="заголовок" добавлять их к поисковому запросу. Но я наблюдаю такое не часто, поэтому кол-во результатов сильно уменьшиться и есть шанс упустить много таргетов
X-RateLimit-Limit
X-RateLimit-Remaining
X-RateLimit-Reset
Retry-After
RateLimit-Limit
RateLimit-Remaining
RateLimit-Reset
RateLimit-Policy
- Доркинг
- Ну тут я думаю все понятно. Я пробовал разные расширения страниц (.php .html .aspx .asp .jsp …). Наиболее уязвимыми оказались сайты с расширением .jsp, они прям очень дружат с рейс кондишинс. Но большинство сайтов на джаве с открытым названием расширения .jsp - старый кал. Для сегодняшней демонстрации искал сайты на .html и .php дабы протестить и продемонстрировать все на свежих примерах
HTTP/2 чуть ли не идеальная версия для состояния гонки, благодаря такой фичи как мультиплексирование (о ней мы уже говорили). Но в HTTP/1.1 максимум что есть похожее на мультиплексирование это http pipelining. HTTP/1.1 пайплайнинг позволяет отправлять несколько запросов по одному соединению, но сервер отвечает по порядку. Это приводит к блокировке: если один ответ задерживается, все следующие ждут. В результате трудно добиться точной синхронизации для race conditions, где нужно, чтобы запросы прибыли почти одновременно. Поэтому скрипты как race-single-packet.py не заточены под HTTP 1.1 и нам прийдеться использовать https://gist.github.com/Xib3rR4dAr/4bbd6b06cb59efd1a75aa433df22f1f2 (race.py)
Если вы сгруппируйте в репитер HTTP/1.1 запросы, то увидите что вместо single packet attack у нас есть last byte sync
Не удалось прогрузить медиа
Фишка в том, чтобы отправить несколько запросов почти полностью, но без последнего байта, а потом одновременно дослать этот последний байт. Сервер начинает обработку почти в одно время, снижая джиттер. Это гениально. И задержка действительно относительно минимальная
Разогрев соединения
Если при отправке через last byte sync вы видите чересчур большую разницу во времени ответов, то отправляем группу запросов пару раз через single connection и пару раз через last byte sync (желательно через скрипт race.py) и смотрим на задержки. Если они немного выровнялись - соединение разогрето успешно, мы можем тестить состояние гонки
Бывает такое, что первый запрос в группе дает наибольшее время ответа, а после него все остальные запросы - нормально. Это происходит потому что первый запрос зачастую устанавливает соединение с TLS, для чего надо немного времени. Для этого первым запросом мы ставим запрос к корню сайта.
Обход рейт лимитов на странице входа
Кейс #1
Этот баг я нашёл на поддомене довольно большой конторы, которая имеет свою vdp программу. Баг я зарепортил, но из соображений политики и безопасности замажу все что могло бы вам дать наводку на поддомен. Спустя 5 неудачных попыток входа сайт бьет тревогу и лимитит нас
Не удалось прогрузить медиа
Простым немного модифицированным скриптом race single packet мы можем брутить логин и пароль без лишних заморочек
Не удалось прогрузить медиа
Не удалось прогрузить медиа
Как мы видим, тревогу сайт не бьет. С обычным интрудером воспроизвести баг у меня не вышло :(. Меня удивило что на функционале по сбросу пароля рейт лимитит даже с мультиплексированием, а на странице входа нет. Ну ладно
На этом приложении в одно временное окошко попадает 80-140 запросов, поэтому брутить с рейс кондишинами данные намного выгоднее финансово и быстрее
Кейс #2
Зачастую во всех веб приложениях все далеко не так идеально как в первом примере. На этом таргете при 5ти неудачных попыток входа лимитило на 5 минут. Благодаря состоянию гонки мне удалось добиться 30-ти попыток. Если вы баг хантер - можете репортить, состояние гонки доказано. Не везде можно уловить 100 запросов в один рейс виндов
Не удалось прогрузить медиа
Чтобы увеличить успех брута - пробуйте изучить функционал сайта и построить multi endpoint race conditions
Турбо интрудеру не всегда рады
Некоторые сайты вовсе не лимитят при бруте через обычный интрудер, но кидают ошибки с турбо интрудером
Не удалось прогрузить медиа
Просто вам как интересный факт, что некоторые сайты настроены против мультиплексирования
Email бомбинг
Конечно, зачастую импакт от него минимальный. Максимум что мы можем это проспамить обидчику и добавить отправителя в черный список в популярных почтовых сервисах. Но для демонстрации обхода рейт лимитов это идеально. После 3х попыток сброса нас рейт лимитит, и мы не можем отправить ссылку на сброс пароля
Не удалось прогрузить медиа
Не удалось прогрузить медиа
Но через стандартный race single packet у меня получилось обойти рейт лимиты
При 20 запусках скрипта у меня вышло отправить максимум 103 запроса
Обход otp
Я заметил что все во всех статьях забывают упомянуть одну интересную вещь - иногда при повторной отправке OTP старый OTP все так же валидный
Сделать чтобы больше 200т запросов попали в одно временное окошко - очень сложно. Надо чтобы совпало множество факторов. Мультиплексирование это вам не магическая штука какая может отправить параллельно хоть 99999 запросов.
Поэтому если вы заметили что отп не имеет срока годности - спамим состоянием гонки на функционале повторной отправки отп / отсылаем отп заново любыми методами. Это нам очень поможет
Ну тут все просто, никакой магии. На таргете спустя 8-ой попытки ввода неверного OTP кода нас рейт лимитило, в ответе просто было ‘null’.
Не удалось прогрузить медиа
Из за того что индусы сходу по какой-то причине блокнули мой айпи и версии HTTP/1.1 было понятно что поймать временное окошко было бы довольно трудно. Но я подумал что для статьи репродьюснуть баг с такими “приколами” было бы интересней, нежели простой обход. Я запустил race.py раза 3, и убедился, что поймать временное окошко возможно, хоть и сложно. Пришлось даже подсоединить кабель дабы уменьшить задержку
Не удалось прогрузить медиа
Спустя где-то 30 запусков и прокси я смог поймать 14 запросов в одно временное окно даже на хуевом сервере индусов и меня получилось воспроизвести баг
Если бы на сайте отп не имели срока годности - обеспеченный account takeover
Портим рейтинг - или же проблема ucoz
Помните время, как мы пытались взломать сайт нашей школы и мечтали поставить на главной странице сайта лицо директрисы прифотошоплена к … где негр ее …. . Ну вы поняли) Почти все школьные сайты написаны именно на ucoz
Как оказалось - cms ucoz это действительно то еще помойное дерьмо. Причем в интернете если погуглить то никаких cve вы не найдёте, безопасность их не волнует. Когда мне попадались сайты на нём под горячую руку - почти всегда было полно xss и sqli. Оно и неудивительно, в основе веб приложений лежит пхп. А так как у самой конторы доход сосиска в год - финансов занимается безопасностью попросту нету
Но это все не в рамках этой статьи. У них также есть проблема с состоянием гонки. Как в других местах - не знаю, но, блин, все сайты уязвимы на функционале лайков/оценки
Вот рейтинг до моего появления
Не удалось прогрузить медиа
А вот после
Не удалось прогрузить медиа
Причем состояние гонки на эндпоинтах по типу комментариев/лайков - стандартная ситуация
Не удалось прогрузить медиа
Eternal disclosed on HackerOne: Race condition in User comments Likes
The researcher found a Race Condition to artificially inflate the upvotes of user comments in the Restaurant's review section
Не удалось прогрузить медиа
hackerone.com
Обход запретов (?)
Недавно я листал каналы в тг на какие я подписан и наткнулся на вот такой вот интересный пост:
Не удалось прогрузить медиа
Тут автор нам рассказывает о том что существуют так называемые “плавающие” баги, каким он не может дать объяснение. Похожий пост я видел с обходом 403 (помните как в прошлой статье James Kettle показывал как таргет сошёл с ума и начал бросать ответы с логами? Тут может быть похожая ситуация из за странно настроенного бека).
Автор так же рассказал, что чтобы их эксплуатировать занимает довольно много времени. Мне показалось это довольно интересным и я начал шерстить интернет
И понял, что функционал для загрузки файлов это тоже очень сочный эндпоинт для состояния гонки. Так что автор скорее всего просто словил аномальное состояние гонки
Возможно в ту же миллисекунду,когда автор отправлял свой запрос на загрузку xlsx файла кто то отправил тоже запрос на загрузку файлов но с разрешенным расширением
(см.
Не удалось прогрузить медиа
Заключение
В этой статье я хотел доказать вам, что race conditions на момент 2025 существует и он далеко не мертв. Все что вам нужно это уметь искать мулти разбивать любой функционал в голове по пунктам, предусматривая конечный импакт. Также вам нужно уметь искать эндпоинты где выполнение разбито на несколько последовательных этапов, складывая запросы как пазлы.
Мы рассмотрели процесс поиска таргетов, какие веб приложения больше всего подвержены этой уязвимости, как эксплуатировать с HTTP 1.1, эндпоинты где она часто встречается с демонстрацией эксплуатации
Если есть какие-то вопросы - задавайте в ЛС. Удачи!
👍24
❤️2
😁6
💯3
LIMB