Files
2026-04-22 10:58:32 +03:00

3.5 KiB
Raw Permalink Blame History

UmbrellaBioAccess

Web 979 pts

Переходим по ссылке и видим перед нами три раздела: Field Directory, Emergency Recovery и Partner Access. Логично предположить, что решение будет состоять из нескольких шагов. Для этого необходим будет эксплуатировать две уязвимости: SQL injection в legacy-поиске и кривой recovery-flow, который позволяет привязать новый passkey к чужому аккаунту, зная только recovery_code. Благодаря этому получаем сессию директора и доступ к BioCore Vault.

flowchart LR
    D(["/directory<br/><i>SQLi UNION</i>"])
    R(["/recovery<br/><i>bind own passkey</i>"])
    A(["/access<br/><i>passkey login</i>"])
    V(["/vault<br/><b>→ flag</b>"])

    D -->|recovery_code| R -->|own passkey linked| A -->|director session| V

    classDef step fill:#e0e7ff,stroke:#6366f1,color:#312e81
    classDef win  fill:#fee2e2,stroke:#dc2626,color:#7f1d1d
    class D,R,A step
    class V win

Решение

Начинаем с /directory. Поиск по legacy-справочнику, и прямо там висит подпись Quote-aware matching enabled.. Проверяем одинарной кавычкой — параметр поиска улетает внутрь выражения вида ILIKE '%...%', можно попоробовать использовать SQLi. Простая булева инъекция (OR true) подтверждает наличие дыры, но к нужным скрытым полям доступа не даст. Идём через UNION SELECT и подменяем displayName значением recovery_code:

') UNION ALL SELECT codename,recovery_code,division,dossier
FROM directory_public_view WHERE role='director' --

В ответе появляется запись директора:

Поле Содержимое
codename кодовое имя директора
displayName 24-символьный hex recovery_code

Идём в /recovery.

Здесь не прямо классический WebAuthn, атаку необходимо провести на бизнес-логику восстановления.

Знание recovery_code считается достаточным основанием, чтобы привязать новый passkey к существующему аккаунту. Вводим извлечённый recovery-код, завершаем регистрацию своего passkey, и он оказывается связан с директорским профилем.

Ну все, мы фактически на финише. На /access вводим директорский codename, логинимся обычным passkey-флоу уже своим ключом — получаем сессию с ролью director. Открываем /vault (или напрямую дёргаем GET /api/vault/biocore) — сервер отдаёт флаг.

Флаг

caplag{read_only_sqli_rebinds_director_passkeys}