Files
Serdtse-Sysoly/finals/task11_flowbase/WRITEUP.md
T
2026-09-17 00:50:07 +03:00

50 lines
3.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<h1 align="center">FlowBase</h1>
<p align="center">
<img src="https://img.shields.io/badge/category-Web-blueviolet" alt="Web"/>
<img src="https://img.shields.io/badge/difficulty-hard-critical" alt="hard"/>
</p>
В платформе автоматизации FlowBase собираем потоки из нод и запускаем их вебхуками. Флаг лежит в `/flag.txt`, доступном служебному пользователю `flowsvc`. В сервисе открыта регистрация. Начинаем с создания учётной записи.
## Решение
`robots.txt` подсказывает каталог `/dl/`. Файл, записанный в этот каталог, можно будет забрать через веб. Регистрируемся через `POST /api/register` с JSON-полями `username` и `password`. Из поля `token` ответа получаем bearer-токен и передаём его в `Authorization: Bearer <token>` при чтении потоков и их версий. `GET /api/flows` показывает только потоки текущего пользователя. Сразу после регистрации список пуст.
Зато `GET /api/flows/{id}/versions` владельца не проверяет. Перебираем числовые ID от 1 до 40 с полученным токеном и находим чужой `backup-daily`. В JSON версий находим ноду `system.run` и берём `webhook_uuid` соответствующей версии. Проверяем её параметры.
| Поле | Почему интересно |
|---|---|
| `owner = admin` | Поток принадлежит администратору |
| `webhook_uuid` | Адрес запуска потока |
| Нода `system.run` | Выполняет `curl $CURL_OPTS $BACKUP_URL` |
IDOR дал UUID вебхука. Проверка его ключа отключена через `WebhookAuthEnable=false`, поэтому `POST /webhooks/{uuid}/run` запускает поток без авторизации. Тело запроса позволяет задать `env` для нод.
Сервис проверяет, что первое слово команды равно `curl`, но аргументы берёт из переданных переменных. Подставляем локальный источник и файл назначения:
```json
{
"env": {
"BACKUP_URL": "file:///flag.txt",
"CURL_OPTS": "-s -o /app/static/dl/leak.txt"
}
}
```
Отправляем этот JSON в `POST /webhooks/{uuid}/run` с `Content-Type: application/json`, без заголовка авторизации. На сервере получается:
```bash
curl -s -o /app/static/dl/leak.txt file:///flag.txt
```
Процесс `flowsvc` может прочитать флаг и записать файл в каталог статики. Вывод ноды в ответ вебхука не попадает. Сохранённый результат забираем через `GET /dl/leak.txt`.
Доступ к версиям чужого потока раскрывает UUID, которого достаточно для запуска. Переданные переменные окружения становятся аргументами `curl`, позволяя скопировать закрытый файл в доступный каталог.
[Солвер](solve/solve.py).
## Флаг
`CAPLAG{flowb4s3_webhook_def4ult_0ff}`