/Разборы задач
25 октября 2026
Райтап на задачу «Десериализатор»
Райтап feadal на задачу «Десериализатор»: небезопасная десериализация в PHP, приватные свойства и получение флага через PHP Object Injection.101
57
Салам, васькИ! Сёдня разбираем очередной веб, 3бать.
АХХАХАХАХАХАХ, ЭТО ЖЕ 3БУЧИЙ НЯНКЭТ, 6ЛЯТЬ, АХАХАХАХАХХА!
В HTML торчит кнопка ?format=r, а ещё подключаются main.js и koulis.js (второй — просто долбо3бский мем, это г0вно не часть задания, забей хYй). Сервер — nginx, приложение — PHP. Ну, пока всё очевидно.
Начинаем долбить format:
?format=UОхYеть, всё, 6лядь, один в один как вывод PHP-функции date($format, $timestamp). Значит, наш 3баный пользовательский ввод суют прямиком в date(). А PHP же, сYка, любит интерполировать ${...} внутри двойных строк — вот и щупаем.
Пробуем самое тупое:
?format=${phpinfo()}И, 3бать мои кирпичи, прилетает полный дамп phpinfo(), страница раздувается с 1,8 КБ до 67 КБ, в заголовке гордо PHP 7.4.33 — phpinfo(). Код исполняется, п1здец.
Пока 3баный дамп перед глазами, выписываем окружение: PHP 7.4.33, процесс крутится от www (uid 1000), file_get_contents живой, open_basedir не задан, рантайм — Docker, 6лядь (.dockerenv в корне). Короче, ничего нас не держит, хYй с ним.
Тут вся подстава, которую в прошлой версии отец родной про3бал: кавычка сама по себе нихYя не ломает. ?format=%27 спокойно отдаёт 200 и возвращает ' прямо в <span> — потому что ввод вставляют в HTML в одинарные кавычки, и сырая кавычка рвёт разметку, а не PHP-код. С " ровно то же самое. Так что не ной, что «фильтр не пускает», — фильтра-то и нет.
То, что реально отваливается в 500, — это 3баный мусор, который не парсится: ${1+1}, ${ini_get('disable_functions')} — оба 500. Короче, внутрь ${...} суём только корректные выражения, а строковый литерал руками часто ломает парсер — тогда собираем строку как мужики, а не лошары.
ХYярим через суперглобальный массив (кавычки нахYй не сдались):
?format=${system($_GET[0])}&0=idЕсть же, сYкаааа! (Кто не понял, мы провернули RCE путём инъекции.)
НахYя ползти по всей файловой системе, если можно сразу ткнуть в корень:
?format=${print_r(scandir(chr(47)))}Вот он, голубчик, 6лядь. Читаем эту залYпу, путь целиком из chr(), чтоб ни один парсер не об0срался:
?format=${print_r(file_get_contents(chr(47).chr(102).chr(108).chr(97).chr(103).chr(54).chr(90).chr(73).chr(109).chr(53)))}(Кто не понял, это /flag6ZIm5 на ASCII-коде.)
Ну вот и всё! Далее по классике: додр4чиваете и спускаете флаг на платформу.