3.7 KiB
MongoPages
MongoPages позволяет загружать файлы и выполнять JavaScript на сервере. Результат показывается в предпросмотре страницы как JSON с экспортами модуля. Флаг лежит в /flag.txt. Нужно прочитать его через серверный JS с учётом ограничений загрузки.
Решение
Сначала собираем условия:
| Ограничение | Что оно меняет |
|---|---|
| MongoDB недоступна напрямую | Работаем через веб-интерфейс |
.js не больше 100 байт |
Нужен короткий модуль |
Запрещены подстроки flag без учёта регистра и ../ |
Собираем путь вычислением |
Ошибки скрыты за Evaluation failed |
Выводим результат через exports |
| Страницы приватные | Открываем preview со своей сессией |
Платформа выполняет загруженный модуль через серверный JavaScript MongoDB. В конфигурации задания загрузчик MozJS разрешает динамический import() по абсолютному пути и не проверяет расширение файла.
В задании /flag.txt хранится как ES-модуль с именованным экспортом flag. Значение пока неизвестно, но формат подсказывает канал чтения: импортируем файл и забираем свойство namespace-объекта. Фильтр смотрит на исходный текст, поэтому разбиваем запрещённое слово в пути и имени свойства. Сохраняем код в pwn.js.
export const x=(await import("/"+"fl"+"ag.txt"))["fl"+"ag"];
Это 60 ASCII-байт без завершающего перевода строки — меньше лимита. Подстрок flag и ../ в исходнике нет.
await на верхнем уровне нужен для порядка выполнения. Платформа читает exports после завершения импорта загруженного модуля. К этому моменту вложенный импорт уже закончится и x получит нужное значение.
Регистрируемся через POST /register, передавая username и password как поля формы, затем входим через POST /login с теми же данными и отправляем pwn.js на /upload в multipart-поле file. Затем открываем /pages/<username>/ со своей cookie. В секции серверного выполнения появляется:
{"x":"m0zjs_w4f_byp4ss"}
Оборачиваем значение в формат флага.
Можно также вынести код в h.txt, а из маленького .js сделать export * from "/var/www/pages/<username>/h.txt";. Лимит для .txt — 64 КБ, загрузчик расширение не проверяет. Но фильтр подстрок действует на все файлы, поэтому разбивать flag всё равно придётся.
Флаг
caplag{m0zjs_w4f_byp4ss}