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`.
```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//` со своей cookie. В секции серверного выполнения появляется:
```json
{"x":"m0zjs_w4f_byp4ss"}
```
Оборачиваем значение в формат флага.
Можно также вынести код в `h.txt`, а из маленького `.js` сделать `export * from "/var/www/pages//h.txt";`. Лимит для `.txt` — 64 КБ, загрузчик расширение не проверяет. Но фильтр подстрок действует на все файлы, поэтому разбивать `flag` всё равно придётся.
[Солвер](solve/solve.py).
## Флаг
`caplag{m0zjs_w4f_byp4ss}`