/Разборы задач
31 октября 2026
Райтап на задачу «Дуглас Муглис»
Исследуем подозрительный WebSocket и расшифровываем данные, отправляемые JavaScript-скиммером.4
5

Web
Задача «Бесконечный бензин»
Откроем сайт, сразу вооружимся chrome DevTools и посмотрим, что у нас есть. Сразу вызывает подозрение поле «Надпись в чеке после покупки». Вы когда-нибудь могли настроить это при заказе топлива на АЗС? Или где-либо ещё... Вот и я о том же.
Перед тем как начнём копать в эту сторону, посмотрим, что мы ещё имеем. Откроем local storage и увидим bugOilToken, откроем jwt.io и посмотрим, что в нём закодировано.
Теперь мы знаем, где записан username и browserSession.
После нажатия кнопки «Сохранить» летит POST-запрос на /api/profile/setting.
После него есть GET-запрос /api/me, который показывает информацию о пользователе.
Теперь у нас есть способ проверить, когда мы смогли выполнить свои злодеяния.
Попробуем штатно потыкать кнопки. Действительно, купить больше 30 литров не получается. Мы получаем ошибку, что больше 30 литров нельзя. Но если мы введём достаточно большое число, например 1e999, то получим интересный ответ.
Этот ответ сыграет свою роль в будущем. Теперь мы знаем, что для переполнения, то есть возможности получать бесконечность бензина, надо будет ввести именно 1e309.
Скопируем сразу POST-запрос на /api/profile/setting и пойдём в консоль мурыжить этот бедный эндпоинт.
Попробуем побаловаться с параметрами.
Написав в пути abc.def «helloworld», мы смогли записать это в своего пользователя.
Этот эндпоинт хороший кандидат на prototype pollution. Пробуем написать в path: __proto__.effectiveMaxLiters (как оно написано в api/me) со значением 1e309 (мы ведь хотим максимально много бензина, ведь так?).
Но увы, ничего не срабатывает. Лимит все ещё 30 литров, пробуем вводить limit, cap, max и на maxLiters у нас получается записать «Infinity». Почему именно maxLiters? Смею предположить, что effectiveMaxLiters «динамически» создаётся, а загрязнять нужно источник, а не производное. maxLiters отсутствует на объекте и читается через прототип, а effectiveMaxLiters – уже посчитанное собственное поле.
Теперь открываем страницу, покупаем бесконечность топлива и начинаем наливать, пока в браузере не высветится флаг.