SSOS
hackthebox
Task: HTB-style OAuth2 SSO web app (nginx + Express/passport client + Go/Gin provider) with a teacher Puppeteer bot that submits the flag at startup. Solution: win a registration race for the fixed student account, then use a text/plain JSON CSRF (Gin ShouldBindJSON ignores Content-Type) delivered via the bot's /submit-url to swap the shared cookie jar's SSO token to our session, so the bot submits the flag into our own account.
$ ls tags/ techniques/
$ cat /etc/rate-limit
Rate limit reached (20 reads/hour per IP). Showing preview only — full content returns at the next hour roll-over.
SSOS — Hack The Box
Description
Homework? Never heard of her. Let's dance.
A single-domain education platform protected by an OAuth2 SSO provider:
nginx(internal port1337, mapped to a random external port per instance) routes byHostheader.edulearn.htb→ Express client app (Node.js, EJS,passport-oauth2) on127.0.0.1:3000.sso.edulearn.htb→ Go/Gin OAuth2 SSO provider on127.0.0.1:3002.- Default server
302-redirects unknown hosts toedulearn.htb(preserving port).
- A Puppeteer "teacher bot" (
puppeteer-core, HeadlessChrome 130) runs inside the container, resolves both hosts to127.0.0.1, and has no useful external egress. - All secrets (
JWT_SECRET,CLIENT_SECRET,SESSION_SECRET, teacher/student passwords) are generated per-container withopenssl rand— not guessable or forgeable.
Goal: read the real flag, which the bot submits into a student assignment once at container startup.
Analysis
Bot behavior (bot/index.js initialSetup(), runs ONCE at startup)
The bot drives a single Puppeteer browser whose pages all share one cookie jar. At startup it executes, in order:
loginUser(teacher, teacherPw)— SSO login form (sets SSOtokencookie = teacher).loginSSO(teacher)— OAuth authorize, sets the client session = teacher.createAssignment×3 — as teacher.registerUser([email protected], STUDENT_PASSWORD)— random password.loginUser(student, STUDENT_PASSWORD)— SSO login form.loginSSO(student, STUDENT_PASSWORD)— CRITICAL BUG: this function ignores its email/password parameters and authorizes using whatevertokencookie is currently in the shared browser jar.submitFlagToAssignment()— typesprocess.env.FLAGinto the first assignment's submission textarea, submitting as the current client-session user.loginUser(teacher)+loginSSO(teacher)— restore teacher.
...
$ grep --similar
Similar writeups
- [web][Pro]Lab 35 — GateKeeper SSO — Open Redirect via Regex URI Validation— hackadvisor
- [web][free]Secure Secretpickle— gpnctf
- [web][Pro]YOFA 2.0— bug-makers
- [web][Pro]Lab 66 — GrowthPilot — Stored XSS via User Registration— hackadvisor
- [web][Pro]Board of Secrets Revenge— miptctf