$ cat writeup.md…
$ cat writeup.md…
UIUCTF 2026
Task: Next.js chatbot backed by OpenBao/Vault and a flag service. Solution: leak a source map exposing a deprecated client-controllable baoAddr field, use it for SSRF that exfiltrates the X-Vault-Token app token, then abuse an over-broad secret/data/+ ACL wildcard to read the flag API key.
$ cat /etc/rate-limit
Rate limit reached (20 reads/hour per IP). Showing preview only — full content returns at the next hour roll-over.
"Hey! Listen! to the most advanced AI on the market!"
- You do not need to bruteforce anything to solve this challenge, please do not attempt to.
- The openbao instance is expected to 404 on the / path. Check /v1/sys/health before opening a ticket.
Players receive a downloadable config.hcl (OpenBao server config) and three live services:
https://<inst>-nabi-ai.chal.uiuc.tf (Next.js chatbot)https://<inst>-openbao-nabi-ai.chal.uiuc.tfhttps://<inst>-flag-service-nabi-ai.chal.uiuc.tfSemantic clue: "Hey! Listen!" + "Nabi" == Navi, the fairy from The Legend of Zelda. The "advanced AI" is a joke — the chatbot only ever replies with canned Navi catchphrases. It is a decoy.
Goal: obtain the flag service's API key from OpenBao and present it to the flag service.
/v1/sys/health works; every data/sys read is {"errors":["permission denied"]} when unauthenticated. The instance is fully sealed to unauth users.GET / returns 401 {"error":"Invalid API key. Please provide a valid API key with the x-api-token header."} — it requires header x-api-token: <FLAG_API_KEY>.0.0.0.0:8200 tls_disable, storage inmem, seal static (unseal key from env OPENBAO_UNSEAL_KEY).secret/.secret/data/nabi -> NABI_API_KEY; secret/data/flag -> FLAG_API_KEY.nabi-app:path "secret/data/+" { capabilities = ["read"] }
The + is a single-path-segment wildcard in Vault/OpenBao ACL, so it matches BOTH secret/data/nabi AND secret/data/flag. This over-broad wildcard is the core ACL misconfiguration.
initialize "nabi" block (declarative self-initialization) creates an app token with id from env OPENBAO_APP_TOKEN, policies=["nabi-app"], no_parent, no_default_policy.Two chained bugs:
...
$ grep --similar