Challenge / Web

SSOS

SSOS is a sanitized challenge note from the local HTB archive, organized for quick review by category, difficulty, evidence flow, and reusable operator

MediumPublished 2025-10-23Sanitized local writeup

Scenario

SSOS attack path

SSOS is a sanitized challenge note from the local HTB archive, organized for quick review by category, difficulty, evidence flow, and reusable operator

Objective

Challenge walkthrough focused on Web evidence, validation, and reusable operator lessons.

SSOS sanitized attack graph

Walkthrough flow

01

Source and route audit

02

Trust boundary flaw

03

Exploit request chain

04

Admin or proof proof

Source coverage

High source coverage

Status: complete. This article is generated from 6 sanitized Markdown sources and keeps raw flags, credentials, keys, cookies, and reusable secrets out of the rendered blog.

100% coverage
Evidence verdict

High confidence: the page is reconstructed from a primary walkthrough plus multiple supporting notes or evidence sources. Treat the chain as source-backed, while still checking the listed source files for sensitive values.

  • Web/SSOS/writeup.md
  • htb-challenge/Web/SSOS/notes.md
  • htb-challenge/Web/SSOS/memory-summary.md
  • htb-challenge/Web/SSOS/hypothesis-board.md
  • HTB/_knowledge/exports/ctf-lightrag-latest-203412/documents/challenge__Web__SSOS__memory-summary.md.caa61182ec.md
  • HTB/_knowledge/exports/ctf-lightrag-latest-203412/documents/challenge__Web__SSOS__notes.md.e26a435e57.md

Technical Walkthrough

Writeup

Challenge

  • Name: SSOS
  • Category: Web
  • Difficulty: Medium
  • Mode: hybrid

Summary

Artifact Inventory

Reference analysis/artifact-inventory.json and summarize the relevant files or remote surface.

Analysis

Solve

Flag

Raw flag is stored in loot/flag.txt and intentionally not reproduced here.

Lessons

Source-Backed Dossier

The sections below are merged from companion Markdown notes for the same case. They are rendered after sanitization so the article stays precise without publishing raw flags, credentials, or target-specific secrets.

Notes

Scope

  • Challenge: SSOS
  • Category: Web
  • Difficulty: Medium
  • Mode: hybrid
  • Remote instance: <TARGET>:30182
  • Start time: 2026-06-11T00:12:14Z
  • Operator: harness
  • State file: challenge-state.json

Harness Status

  • Current phase: see challenge-state.json
  • Next allowed actions: see next-action.json
  • Raw flags and sensitive material stay in loot/ only. Do not paste them here.

Artifact Inventory

FileSizeSHA256TypeNotes
files/a12c7371-e2ee-4e9b-a80b-94b37779c389.zip66992<hash redacted>Zip archive data, at least v1.0 to extract, compression method=storezip entries: 70 shown in artifact inventory JSON

Evidence Ledger

TimeActionOutput/FileFindingConfidenceNext
2026-06-11T00:12:14Zharness initchallenge-state.jsonWorkspace initialized with deterministic state fileHighInventory artifacts
2026-06-11T00:12:29Zartifact inventoryanalysis/artifact-inventory.json1 artifact(s) inventoriedHighBuild or update hypotheses
2026-06-11T00:14:49Zhypothesis recordedhypothesis-board.mdLeak a teacher OAuth authorization code through path-normalized redirect_uri into an assignment page with an attacker-controlled image, then redeem the code via the normal client callback to become teacher and read the flag submission.HighRegister as student, create a submission with external image beacon, report a crafted authorize URL with redirect_uri=/oauth/callback/../assignment/<id>, confirm beacon receives code in Referer, then redeem via /oauth/callback.
2026-06-11T00:14:49Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T001449626905Z-02153150.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T00:14:56Zsource auditanalysis/source-audit.mdSource audit recordedHighGate before exploit
2026-06-11T00:15:07Zresearch taskanalysis/research/task-20260611T001507445894Z-96eec801.mdResearch task created for advisory investigationMediumRecord research output
2026-06-11T00:15:08Zlocal memory searchanalysis/research/local-memory-search-20260611T001508380599Z-34979848.mdFound 8 safe prior-note result(s)MediumRecord useful result or skip
2026-06-11T00:16:02Zevaluatoranalysis/evaluator-20260611T001602582811Z-10d20595.mdValidate firstHighrun_live_preflight_then_marker_beacon_validation
2026-06-11T00:16:41Zresearch recordanalysis/research/research-records.mdResearch tagged GENERICMediumValidate against current evidence
2026-06-11T00:23:41Zbranch closedhypothesis-board.mdAn external img beacon alone is not reliable enough to leak an OAuth code from the assignment URL; it can validate bot reachability but not full URL exfil.HighRerank hypotheses
2026-06-11T00:59:03Zlocal memory recordanalysis/local-memory-records.mdPrior local notes reviewed as fallback/advisory contextMediumValidate against current evidence
2026-06-11T00:59:03Zevaluatoranalysis/evaluator-20260611T005903373701Z-830cf0cf.mdProceedHighWrite a reproducible solver/probe harness, validate remote sanitizer behavior, then run the OAuth/bot chain only if the primitive is live.
2026-06-11T01:11:15ZRAG queryanalysis/rag/rag-query-20260611T011106000117Z-860a439b.txtRAG helper exited 0; output savedMediumRecord retrieval tag and validation
2026-06-11T01:29:21Zbranch closedhypothesis-board.mdChrome 130 default strict-origin-when-cross-origin strips path/query on cross-origin image requests, so it does not leak the OAuth code.HighRerank hypotheses
2026-06-11T01:29:21Zbranch closedhypothesis-board.mdLive sanitizer behavior matches patched sanitize-html behavior; xmp/noembed/plaintext payloads did not produce executable HTML.HighRerank hypotheses
2026-06-11T01:29:21Zbranch closedhypothesis-board.mdTeacher session cookies were not sent for the cross-site POST in the tested browser context, and available POST actions do not read flag content anyway.HighRerank hypotheses
2026-06-11T01:29:21Zbranch closedhypothesis-board.mdRuntime env password generation is active on the remote; fallback credentials are not valid.HighRerank hypotheses
2026-06-11T01:29:21Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T012921989556Z-1eec5047.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T01:29:32ZRAG recordanalysis/rag-records.mdRetrieved memory tagged MISSINGMediumValidate or reject with live evidence
2026-06-11T01:30:50Zhypothesis recordedhypothesis-board.mdNo current proven exploit path after closing OAuth/referrer and sanitizer branches; next work must identify a new same-origin code sink, actual XSS primitive, or direct authorization bypass.MediumAudit only one new candidate at a time against source, then validate live with a disposable student and collector if source-backed.
2026-06-11T01:30:50Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T013050377847Z-09407c20.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T02:26:47Zbranch closedhypothesis-board.mdNo executable HTML or flag-content leak is created by score mutation.HighRerank hypotheses
2026-06-11T02:26:47Zbranch closedhypothesis-board.mdNo redirect_uri parser split was found to deliver the teacher code directly to attacker infrastructure.HighRerank hypotheses
2026-06-11T02:26:47Zbranch closedhypothesis-board.mdThe attempted auth-refresh plus top-level POST did not carry a usable EduLearn session for the mutation.HighRerank hypotheses
2026-06-11T02:26:47Zbranch closedhypothesis-board.mdNo payload survived remote sanitization in an executable browser context.HighRerank hypotheses
2026-06-11T02:27:04Zevaluatoranalysis/evaluator-20260611T022704174413Z-e995f7b7.mdDo not proceedHighStop repeating OAuth/referrer/sanitizer variants. Search for a specific executable primitive or alternate authorization bug.
2026-06-11T02:27:04Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T022704286293Z-c00bbbd1.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T02:55:40Zresearch recordanalysis/research/research-records.mdResearch tagged PARTIALMediumValidate against current evidence
2026-06-11T02:55:50Zhypothesis recordedhypothesis-board.mdPublic hints point to an XSS/OAuth/teacher-bot chain, but the exact executing primitive remains unidentified.MediumRun the challenge locally with an instrumented bot/browser and test only source-backed DOM/sanitizer/client-side candidates until one produces real JavaScript execution.
2026-06-11T02:56:08Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T025608671791Z-7bc98c5b.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T02:56:10Zresearch recordanalysis/research/research-records.mdResearch tagged PARTIALMediumValidate against current evidence
2026-06-11T02:56:10Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T025610628024Z-057ff9d8.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T02:57:00Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T025700708157Z-826e4802.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T02:57:22Zresearch recordanalysis/research/research-records.mdResearch tagged PARTIALMediumValidate against current evidence
2026-06-11T02:57:22Zresearch recordanalysis/research/research-records.mdResearch tagged PARTIALMediumValidate against current evidence
2026-06-11T03:33:14Zinstrumentation plananalysis/instrumentation-plan.mdFind a source-backed Chrome-executing client-side primitive or same-origin OAuth-code storage sink before any further live exploit attempt.HighStop immediately if local Chrome does not execute the primitive, if no same-origin storage/reflection sink exists, or if the remote behavior differs from the local proof. Do not repeat closed OAuth referrer, sanitizer, score sink, CSRF, or parser-differential branches without new evidence.
2026-06-11T03:58:55Zbranch closedhypothesis-board.mdNo attacker-readable code exfiltration or JavaScript execution was produced.HighRerank hypotheses
2026-06-11T03:58:55Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T035855380968Z-dfabc1e0.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T03:58:55Zevaluatoranalysis/evaluator-20260611T035855432554Z-93b1f49f.mdDo not proceedHighFind a new executable client-side primitive or same-origin storage/reflection route; do not run live exploit attempts until that exists.
2026-06-11T04:00:13Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T040013240997Z-be632fbf.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T04:57:09Zbranch closedhypothesis-board.mdServer allowlist and Object.entries rendering prevent attacker-controlled executable reaction markup.HighRerank hypotheses
2026-06-11T04:57:09Zbranch closedhypothesis-board.mdFragment placement changes where the code lands but does not make it attacker-readable or executable.HighRerank hypotheses
2026-06-11T04:57:09Zbranch closedhypothesis-board.mdThe bot cannot be made to submit unknown teacher credentials, and the logged-in teacher state does not auto-trigger the redirect.HighRerank hypotheses
2026-06-11T04:57:09Zbranch closedhypothesis-board.mdThe tested pollution path does not cross into teacher-rendered executable output or authenticated profile state.HighRerank hypotheses
2026-06-11T04:57:09Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T045709716574Z-caca2dc3.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T04:57:09Zevaluatoranalysis/evaluator-20260611T045709769205Z-f1065996.mdDo not proceedHighStop repeating current candidates. Continue only if new source-backed sink or specific public hint identifies a Chrome-executing primitive.
2026-06-11T05:44:15Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T054415977022Z-966081d9.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T05:54:54Zevaluatoranalysis/evaluator-20260611T055454315842Z-a9ca284c.mdProceedHighRun bounded revalidation scripts only, then record a fresh evaluator.
2026-06-11T05:57:14Zbranch closedhypothesis-board.mdThe refreshed target is reachable, but stored HTML payloads still strip scripts, event handlers, and raw-text wrappers; no executable browser primitive was recovered.HighRerank hypotheses
2026-06-11T05:57:14Zbranch closedhypothesis-board.mdScore mutation accepts unsafe-shaped values, but assignment rendering escapes HTML and stats normalize non-numeric values; no executable or flag-reading sink appears.HighRerank hypotheses
2026-06-11T05:57:14Zbranch closedhypothesis-board.mdBot accepts the submitted URL, but the attempted auth-refresh plus top-level POST does not produce a useful teacher-side mutation; observed score remained normal auto-score.HighRerank hypotheses
2026-06-11T05:57:24Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T055724490561Z-b47bb46d.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T05:57:32Zevaluatoranalysis/evaluator-20260611T055732934169Z-2c022405.mdDo not proceedHighStop live retries; find a new source-backed primitive or trusted specific hint.
2026-06-11T05:59:53Zevaluatoranalysis/evaluator-20260611T055953493988Z-e326e2c1.mdProceedHighRun harmless bot reachability port check, then restore Do not proceed unless a new primitive is identified.
2026-06-11T06:02:06Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T060206889798Z-711e2fee.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T06:02:06Zbranch closedhypothesis-board.mdTeacher bot runs inside the challenge container and expects internal port 1337; submitting edulearn.htb:30182 to the bot produced a server-side failure.HighRerank hypotheses
2026-06-11T06:02:19Zevaluatoranalysis/evaluator-20260611T060219351249Z-9098f4ef.mdDo not proceedHighDo not repeat live probes; build or identify one new primitive using the corrected bot port model.

Key Findings

  • 2026-06-11: New operator-supplied remote instance is <TARGET>:30182.
  • 2026-06-11: Operator-supplied Downloads artifact a12c7371-e2ee-4e9b-a80b-94b37779c389 (1).zip has SHA256 <hash redacted>, matching the existing workspace artifact in files/; no duplicate archive was needed.
  • 2026-06-11: External operator access uses <TARGET>:30182, but URLs submitted to the teacher bot must use the container-internal hostnames and port, e.g. http://edulearn.htb:1337/ or http://sso.edulearn.htb:1337/.... Live check: internal :1337 report returned success; external :30182 report returned a server-side failure.
  • Latest effective gate remains blocked: do not run live remote exploit attempts until a new source-backed executable primitive or same-origin readable sink is found and a fresh Proceed evaluator is recorded.

RAG / Advisory Memory

RAG output is advisory only. Record evaluated retrievals with:

bash
scripts/challenge_harness.py rag-record <workspace> --query "..." --tag MATCHED|PARTIAL|MISSING|<secret redacted>|GENERIC --validation "..."

Secrets/Flags

Raw flags and sensitive material stay in loot/ only. Use scripts/challenge_harness.py capture-flag to validate and record flag capture without printing the value.

Memory Summary

Metadata

  • Platform: HackTheBox Challenges
  • Category: Web
  • Challenge: SSOS
  • Difficulty: Medium
  • Source workspace: <local workspace>

Validated Solve Chain

Concepts only. Do not include raw flags, reusable credentials, tokens, cookies, private keys, or live secrets.

1.

Reusable Lessons

-

Dead Ends

-

Tool Quirks

-

Evidence Paths

-

Ingestion Decision

  • Proposed for LightRAG: yes/no
  • Requires user approval before ingestion: yes

Hypothesis Board

Keep no more than 3 active hypotheses on Easy/Medium and 5 on Hard unless the user explicitly asks for breadth.

RankPathEvidenceMissing ProofCheapest ValidationConfidenceStatus
1OAuth path-prefix remains the likely first half; next work must find the client-side/same-origin exfil primitive that turns a teacher code landed on EduLearn into attacker-readable state.analysis/live-sanitizer-probe.json; analysis/collector/requests.jsonl; analysis/research/sidecar-technical-research-20260611T025452Z.md; source route pass over client/server.jsA concrete same-origin code sink, executable XSS primitive, or direct authorization bypass that lets attacker redeem teacher OAuth code or read the default student's flag submission.Build local instrumented Chrome harness first; test same-origin Referer/location storage and hidden/alternate route candidates before any more live probing.MediumActive
2Public hints point to an XSS/OAuth/teacher-bot chain, but the exact executing primitive remains unidentified.analysis/research/public-hint-research-20260611.md; LinkedIn solver tags ClientSide/XSS/OAuth; Reddit/LinkedIn comments mention URL exfil difficulty; source confirms OAuth redirect and teacher bot.A payload or client-side sink that actually executes in Chrome under the challenge sanitizer and can read or exfiltrate the teacher OAuth code/current URL.Run the challenge locally with an instrumented bot/browser and test only source-backed DOM/sanitizer/client-side candidates until one produces real JavaScript execution.Mediumactive

Closed Branches

BranchEvidence TestedFailure OutputReason ClosedRevisit Condition
Simple img-only code exfil through cross-origin RefererLocal review: Chrome default referrer policy is expected to send only origin cross-origin; source has no referrerpolicy override; sanitize-html allowlist strips referrerpolicy attributes.analysis/source-audit.mdAn external img beacon alone is not reliable enough to leak an OAuth code from the assignment URL; it can validate bot reachability but not full URL exfil.Only revisit if live beacon proves full URL Referer leakage or a same-origin/attacker-observable exfil route is found.
OAuth code exfil via img Referer from teacher-readable submissionWeb/SSOS/analysis/collector/requests.jsonl and Web/SSOS/analysis/referrer-probe-run.jsonCollector received image beacons, but Referer was only http://edulearn.htb:1337/ even when the bot visited /submission/<id>?code=<secret redacted>.Chrome 130 default strict-origin-when-cross-origin strips path/query on cross-origin image requests, so it does not leak the OAuth code.Only revisit if a same-origin open redirect with unsafe referrer policy or an XSS primitive is proven.
sanitize-html stored XSS in student submissionWeb/SSOS/analysis/live-sanitizer-probe.jsonRemote rendered test payloads stripped scripts/events/raw-text wrappers; no script or onerror survived.Live sanitizer behavior matches patched sanitize-html behavior; xmp/noembed/plaintext payloads did not produce executable HTML.Only revisit with a specific payload that survives remote rendering and executes in Chrome.
Cross-site POST CSRF from data: page into EduLearnWeb/SSOS/analysis/csrf-score-probe.jsonBot visited a data: page with an auto-submitting POST to /api/score/<own submission>; score remained the normal auto-score, not the CSRF value.Teacher session cookies were not sent for the cross-site POST in the tested browser context, and available POST actions do not read flag content anyway.Only revisit if a fresh-cookie Lax+POST chain is paired with a useful teacher-only state change.
Default teacher/student fallback credentialslive login attempts via SSO /api/login<email redacted>:teacher123 and <email redacted>:student123 both returned 401.Runtime env password generation is active on the remote; fallback credentials are not valid.Do not revisit unless service is respawned with evidence env password generation failed.
Score field type-confusion/client-side sinkanalysis/score-sink-probe.jsonScore accepts strings/arrays/objects, but assignment rendering escapes HTML and user stats normalize unsafe averageScore values to null.No executable HTML or flag-content leak is created by score mutation.Only revisit if a new route renders score with unescaped output or a controllable object-to-string primitive is found.
Go/Chrome URL parser differential to external hostanalysis/url-parser-differentials.txt; analysis/url-parser-differentials-wide.txt122 candidate encoded slash, backslash, userinfo, tab, fragment, and delimiter variants produced no case where Go validates edulearn.htb:1337 while browser-style parsing goes external.No redirect_uri parser split was found to deliver the teacher code directly to attacker infrastructure.Only revisit with a specific parser differential candidate tested against Go net/url and Chrome.
Fresh-cookie top-level CSRF from bot data pageanalysis/csrf-refresh-score-probe.jsonBot accepted the data URL, but score_after was the normal auto-score, not the CSRF marker 1337.The attempted auth-refresh plus top-level POST did not carry a usable EduLearn session for the mutation.Only revisit if paired with a proven same-site delivery mechanism and a state-changing route that reads or exposes flag content.
Extended sanitize-html raw-text/mXSS fuzz passanalysis/sanitizer-fuzz-20260611.json; analysis/sanitize-html-version-config-check.txtKnown raw-text and mXSS candidates did not produce executable markup. Apparent hits were an event string inside img src and entity-escaped text.No payload survived remote sanitization in an executable browser context.Only revisit with a payload that renders as live DOM event/script in Chrome, not merely entity-decoded text in analysis.
OAuth code exfil via submission image referrer, including two-up path-prefix landinganalysis/local-validation/ssos-local-browser-validation.json; analysis/local-validation/runtime/logs/proxy-requests.jsonlSubmission image fired in teacher Chromium, but external canary Referer was only http://edulearn.htb:1337/ and window.__pwned stayed false. Two-up OAuth redirect lands code on /api/stats/<id>, but only as a same-origin request not readable by the attacker.No attacker-readable code exfiltration or JavaScript execution was produced.Only revisit if a separate same-origin storage/reflection sink or executable sanitizer bypass is proven.
Reaction innerHTML sink bypass via payload shape or itemId pollutionanalysis/local-validation/ssos-candidate-validation.jsonHTML string, array, and duplicate-urlencoded emoji inputs returned 400 Invalid emoji. __proto__/constructor item IDs did not create executable reaction HTML; marker stayed false and reactionHtml was empty.Server allowlist and Object.entries rendering prevent attacker-controlled executable reaction markup.Only revisit with a concrete bypass that makes attacker-controlled reaction key/value render into the teacher page DOM.
OAuth fragment placement as code sinkanalysis/local-validation/ssos-candidate-validation.jsonCode can be placed after a fragment marker in location.hash, but EduLearn source/scripts do not read location.hash; pageReadsHash=false.Fragment placement changes where the code lands but does not make it attacker-readable or executable.Only revisit if a same-origin hash reader/sink is found.
SSO login redirect javascript sink for teacher botanalysis/local-validation/ssos-candidate-validation.jsonLogged-out user submitting known credentials executes javascript redirect marker, but logged-in teacher visiting /login?redirect=javascript:... sees the login form and marker remains false.The bot cannot be made to submit unknown teacher credentials, and the logged-in teacher state does not auto-trigger the redirect.Only revisit if a source-backed way exists to force an SSO login form submission with valid teacher credentials or to auto-trigger redirect while authenticated.
Plain-object map pollution via __proto__ profile/user keysanalysis/local-validation/ssos-candidate-validation.json__proto__ registration/login produced a callback but client profile access fell back to /login; teacher marker remained false and Object.prototype keys stayed empty.The tested pollution path does not cross into teacher-rendered executable output or authenticated profile state.Only revisit with a proven pollution write that changes an own rendered property in a teacher-visible sink.
New-instance sanitizer retry on <TARGET>:30182analysis/live-sanitizer-probe-new-instance-20260611.jsonThe refreshed target is reachable, but stored HTML payloads still strip scripts, event handlers, and raw-text wrappers; no executable browser primitive was recovered.Only revisit with a specific payload that survives sanitize-html and executes in Chrome.
New-instance score sink retry on <TARGET>:30182analysis/score-sink-probe-new-instance-20260611.jsonScore mutation accepts unsafe-shaped values, but assignment rendering escapes HTML and stats normalize non-numeric values; no executable or flag-reading sink appears.Only revisit if a route renders score unescaped in a teacher-visible context.
New-instance bot CSRF retry on <TARGET>:30182analysis/csrf-refresh-score-probe-new-instance-20260611.jsonBot accepts the submitted URL, but the attempted auth-refresh plus top-level POST does not produce a useful teacher-side mutation; observed score remained normal auto-score.Only revisit if paired with a same-site delivery mechanism and a useful teacher-only state-changing/read path.
Bot URL submitted with external operator portanalysis/bot-port-external-30182-20260611.jsonTeacher bot runs inside the challenge container and expects internal port 1337; submitting edulearn.htb:30182 to the bot produced a server-side failure.Use :1337 for any future reported bot URL; use :30182 only for operator-side access and code redemption.

Memory Summary

approval_required: true

Sanitized Memory Summary

Metadata

  • Platform: HackTheBox Challenges
  • Category: Web
  • Challenge: SSOS
  • Difficulty: Medium
  • Source workspace: <local workspace>

Validated Solve Chain

Concepts only. Do not include raw flags, reusable credentials, tokens, cookies, private keys, or live secrets.

1.

Reusable Lessons

-

Dead Ends

-

Tool Quirks

-

Evidence Paths

-

Ingestion Decision

  • Proposed for LightRAG: yes/no
  • Requires user approval before ingestion: yes

Notes

Notes

Scope

  • Challenge: SSOS
  • Category: Web
  • Difficulty: Medium
  • Mode: hybrid
  • Remote instance: <TARGET>:30182
  • Start time: 2026-06-11T00:12:14Z
  • Operator: harness
  • State file: challenge-state.json

Harness Status

  • Current phase: see challenge-state.json
  • Next allowed actions: see next-action.json
  • Raw flags and sensitive material stay in loot/ only. Do not paste them here.

Artifact Inventory

FileSizeSHA256TypeNotes
files/a12c7371-e2ee-4e9b-a80b-94b37779c389.zip66992<hash redacted>Zip archive data, at least v1.0 to extract, compression method=storezip entries: 70 shown in artifact inventory JSON

Evidence Ledger

TimeActionOutput/FileFindingConfidenceNext
2026-06-11T00:12:14Zharness initchallenge-state.jsonWorkspace initialized with deterministic state fileHighInventory artifacts
2026-06-11T00:12:29Zartifact inventoryanalysis/artifact-inventory.json1 artifact(s) inventoriedHighBuild or update hypotheses
2026-06-11T00: <REDACTED>, then redeem the code via the normal client callback to become teacher and read the flag submission.HighRegister as student, create a submission with external image beacon, report a crafted authorize URL with redirect_uri= <REDACTED>, confirm beacon receives code in Referer, then redeem via /oauth/callback.
2026-06-11T00:14:49Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T001449626905Z-02153150.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T00:14:56Zsource auditanalysis/source-audit.mdSource audit recordedHighGate before exploit
2026-06-11T00:15:07Zresearch taskanalysis/research/task-20260611T001507445894Z-96eec801.mdResearch task created for advisory investigationMediumRecord research output
2026-06-11T00:15:08Zlocal memory searchanalysis/research/local-memory-search-20260611T001508380599Z-34979848.mdFound 8 safe prior-note result(s)MediumRecord useful result or skip
2026-06-11T00:16:02Zevaluatoranalysis/evaluator-20260611T001602582811Z-10d20595.mdValidate firstHighrun_live_preflight_then_marker_beacon_validation
2026-06-11T00:16:41Zresearch recordanalysis/research/research-records.mdResearch tagged GENERICMediumValidate against current evidence
2026-06-11T00:23:41Zbranch closedhypothesis-board.mdAn external img beacon alone is not reliable enough to leak an OAuth code from the assignment URL; it can validate bot reachability but not full URL exfil.HighRerank hypotheses
2026-06-11T00:59:03Zlocal memory recordanalysis/local-memory-records.mdPrior local notes reviewed as fallback/advisory contextMediumValidate against current evidence
2026-06-11T00:59:03Zevaluatoranalysis/evaluator-20260611T005903373701Z-830cf0cf.mdProceedHighWrite a reproducible solver/probe harness, validate remote sanitizer behavior, then run the OAuth/bot chain only if the primitive is live.
2026-06-11T01:11:15ZRAG queryanalysis/rag/rag-query-20260611T011106000117Z-860a439b.txtRAG helper exited 0; output savedMediumRecord retrieval tag and validation
2026-06-11T01:29:21Zbranch closedhypothesis-board.mdChrome 130 default strict-origin-when-cross-origin strips path/query on cross-origin image requests, so it does not leak the OAuth code.HighRerank hypotheses
2026-06-11T01:29:21Zbranch closedhypothesis-board.mdLive sanitizer behavior matches patched sanitize-html behavior; xmp/noembed/plaintext payloads did not produce executable HTML.HighRerank hypotheses
2026-06-11T01: <REDACTED>, and available POST actions do not read flag content anyway.HighRerank hypotheses
2026-06-11T01: <REDACTED>
2026-06-11T01:29:21Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T012921989556Z-1eec5047.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T01:29:32ZRAG recordanalysis/rag-records.mdRetrieved memory tagged MISSINGMediumValidate or reject with live evidence
2026-06-11T01:30:50Zhypothesis recordedhypothesis-board.mdNo current proven exploit path after closing OAuth/referrer and sanitizer branches; next work must identify a new same-origin code sink, actual XSS primitive, or direct authorization bypass.MediumAudit only one new candidate at a time against source, then validate live with a disposable student and collector if source-backed.
2026-06-11T01:30:50Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T013050377847Z-09407c20.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T02: <REDACTED>
2026-06-11T02:26:47Zbranch closedhypothesis-board.mdNo redirect_uri parser split was found to deliver the teacher code directly to attacker infrastructure.HighRerank hypotheses
2026-06-11T02:26:47Zbranch closedhypothesis-board.mdThe attempted auth-refresh plus top-level POST did not carry a usable EduLearn session for the mutation.HighRerank hypotheses
2026-06-11T02:26:47Zbranch closedhypothesis-board.mdNo payload survived remote sanitization in an executable browser context.HighRerank hypotheses
2026-06-11T02:27:04Zevaluatoranalysis/evaluator-20260611T022704174413Z-e995f7b7.mdDo not proceedHighStop repeating OAuth/referrer/sanitizer variants. Search for a specific executable primitive or alternate authorization bug.
2026-06-11T02:27:04Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T022704286293Z-c00bbbd1.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T02:55:40Zresearch recordanalysis/research/research-records.mdResearch tagged PARTIALMediumValidate against current evidence
2026-06-11T02:55:50Zhypothesis recordedhypothesis-board.mdPublic hints point to an XSS/OAuth/teacher-bot chain, but the exact executing primitive remains unidentified.MediumRun the challenge locally with an instrumented bot/browser and test only source-backed DOM/sanitizer/client-side candidates until one produces real JavaScript execution.
2026-06-11T02:56:08Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T025608671791Z-7bc98c5b.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T02:56:10Zresearch recordanalysis/research/research-records.mdResearch tagged PARTIALMediumValidate against current evidence
2026-06-11T02:56:10Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T025610628024Z-057ff9d8.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T02:57:00Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T025700708157Z-826e4802.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T02:57:22Zresearch recordanalysis/research/research-records.mdResearch tagged PARTIALMediumValidate against current evidence
2026-06-11T02:57:22Zresearch recordanalysis/research/research-records.mdResearch tagged PARTIALMediumValidate against current evidence
2026-06-11T03:33:14Zinstrumentation plananalysis/instrumentation-plan.mdFind a source-backed Chrome-executing client-side primitive or same-origin OAuth-code storage sink before any further live exploit attempt.HighStop immediately if local Chrome does not execute the primitive, if no same-origin storage/reflection sink exists, or if the remote behavior differs from the local proof. Do not repeat closed OAuth referrer, sanitizer, score sink, CSRF, or parser-differential branches without new evidence.
2026-06-11T03:58:55Zbranch closedhypothesis-board.mdNo attacker-readable code exfiltration or JavaScript execution was produced.HighRerank hypotheses
2026-06-11T03:58:55Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T035855380968Z-dfabc1e0.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T03:58:55Zevaluatoranalysis/evaluator-20260611T035855432554Z-93b1f49f.mdDo not proceedHighFind a new executable client-side primitive or same-origin storage/reflection route; do not run live exploit attempts until that exists.
2026-06-11T04:00:13Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T040013240997Z-be632fbf.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T04:57:09Zbranch closedhypothesis-board.mdServer allowlist and Object.entries rendering prevent attacker-controlled executable reaction markup.HighRerank hypotheses
2026-06-11T04:57:09Zbranch closedhypothesis-board.mdFragment placement changes where the code lands but does not make it attacker-readable or executable.HighRerank hypotheses
2026-06-11T04:57:09Zbranch closedhypothesis-board.mdThe bot cannot be made to submit unknown teacher credentials, and the logged-in teacher state does not auto-trigger the redirect.HighRerank hypotheses
2026-06-11T04:57:09Zbranch closedhypothesis-board.mdThe tested pollution path does not cross into teacher-rendered executable output or authenticated profile state.HighRerank hypotheses
2026-06-11T04:57:09Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T045709716574Z-caca2dc3.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T04:57:09Zevaluatoranalysis/evaluator-20260611T045709769205Z-f1065996.mdDo not proceedHighStop repeating current candidates. Continue only if new source-backed sink or specific public hint identifies a Chrome-executing primitive.
2026-06-11T05:44:15Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T054415977022Z-966081d9.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T05:54:54Zevaluatoranalysis/evaluator-20260611T055454315842Z-a9ca284c.mdProceedHighRun bounded revalidation scripts only, then record a fresh evaluator.
2026-06-11T05:57:14Zbranch closedhypothesis-board.mdThe refreshed target is reachable, but stored HTML payloads still strip scripts, event handlers, and raw-text wrappers; no executable browser primitive was recovered.HighRerank hypotheses
2026-06-11T05: <REDACTED>, but assignment rendering escapes HTML and stats normalize non-numeric values; no executable or flag-reading sink appears.HighRerank hypotheses
2026-06-11T05:57:14Zbranch closedhypothesis-board.mdBot accepts the submitted URL, but the attempted auth-refresh plus top-level POST does not produce a useful teacher-side mutation; observed score remained normal auto-score.HighRerank hypotheses
2026-06-11T05:57:24Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T055724490561Z-b47bb46d.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T05:57:32Zevaluatoranalysis/evaluator-20260611T055732934169Z-2c022405.mdDo not proceedHighStop live retries; find a new source-backed primitive or trusted specific hint.
2026-06-11T05:59:53Zevaluatoranalysis/evaluator-20260611T055953493988Z-e326e2c1.mdProceedHighRun harmless bot reachability port check, then restore Do not proceed unless a new primitive is identified.
2026-06-11T06:02:06Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T060206889798Z-711e2fee.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T06:02:06Zbranch closedhypothesis-board.mdTeacher bot runs inside the challenge container and expects internal port 1337; submitting edulearn.htb:30182 to the bot produced a server-side failure.HighRerank hypotheses
2026-06-11T06:02:19Zevaluatoranalysis/evaluator-20260611T060219351249Z-9098f4ef.mdDo not proceedHighDo not repeat live probes; build or identify one new primitive using the corrected bot port model.

Key Findings

  • 2026-06-11: New operator-supplied remote instance is <TARGET>:30182.
  • 2026-06-11: Operator-supplied Downloads artifact a12c7371-e2ee-4e9b-a80b-94b37779c389 (1).zip has SHA256 <hash redacted>, matching the existing workspace artifact in files/; no duplicate archive was needed.
  • 2026-06-11: External operator access uses <TARGET>:30182, but URLs submitted to the teacher bot must use the container-internal hostnames and port, e.g. http://edulearn.htb:1337/ or http://sso.edulearn.htb:1337/.... Live check: internal :1337 report returned success; external :30182 report returned a server-side failure.
  • Latest effective gate remains blocked: do not run live remote exploit attempts until a new source-backed executable primitive or same-origin readable sink is found and a fresh Proceed evaluator is recorded.

RAG / Advisory Memory

RAG output is advisory only. Record evaluated retrievals with:

bash
scripts/challenge_harness.py rag-record <workspace> --query "..." --tag MATCHED|PARTIAL|MISSING|<secret redacted>|GENERIC --validation "..."

Secrets/Flags

Raw flags and sensitive material stay in loot/ only. Use scripts/challenge_harness.py capture-flag to validate and record flag capture without printing the value.

Technical analogy

How to remember this solve

Think of the web app like a building with signs on every door. The solve usually comes from reading the map carefully, finding the door the app forgot to hide, then sending the exact request that proves you understand the route.

For SSOS, keep the mental model simple: identify the trusted assumption, prove it with the smallest safe test, then automate or repeat only the part that directly leads to the flag.