Challenge / Mobile

Celestial Scribe

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

MediumPublished 2025-01-23Sanitized local writeup

Scenario

Celestial Scribe attack path

Celestial Scribe 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 Mobile evidence, validation, and reusable operator lessons.

Celestial Scribe sanitized attack graph

Walkthrough flow

01

Artifact review

02

Hypothesis

03

Validated solve path

04

Proof captured

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.

  • Mobile/Celestial-Scribe/writeup.md
  • htb-challenge/Mobile/Celestial-Scribe/notes.md
  • htb-challenge/Mobile/Celestial-Scribe/memory-summary.md
  • htb-challenge/Mobile/Celestial-Scribe/hypothesis-board.md
  • HTB/_knowledge/exports/ctf-lightrag-latest-203412/documents/challenge__Mobile__Celestial-Scribe__memory-summary.md.754769096e.md
  • HTB/_knowledge/exports/ctf-lightrag-latest-203412/documents/challenge__Mobile__Celestial-Scribe__notes.md.ee0b0ebd70.md

Technical Walkthrough

Writeup

Challenge

  • Name: Celestial-Scribe
  • Category: Mobile
  • Difficulty: Medium
  • Mode: hybrid

Summary

Celestial Scribe is a mobile/API challenge. The APK exposes a cleartext Express API for user auth and cloud notes. Ordinary IDOR, JWT tampering, path injection, account-name tricks, and delayed permission priming were all negative. The successful path was a true race condition in the note read flow: release a valid permission check for an owned note at the same time as a read of the privileged target note ID 1.

Artifact Inventory

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

  • files/a12c734c-a4c3-4e5a-8caf-a8fb8c8ae634.zip contains celestial_scribe.apk.
  • Decompiled APK package: htb.d3vnu11.securenotes.
  • The app builds a cleartext base API URL of the form http://<host>:<port>/api.
  • Confirmed live routes include /api/auth/register, /api/auth/login, /api/auth/verify, /api/notes, /api/notes/<id>, and /api/notes/<id>/check-permission.

Analysis

The app source showed a two-step note read flow. The client first requests /api/notes/<guid>/check-permission, then requests /api/notes/<guid> to fetch content. That route map is recorded in analysis/source-audit.md.

Baseline API validation showed that simple cross-user note reads were blocked with 403 Access denied; creating a duplicate note ID under another account was also blocked. Those checks are recorded in analysis/api-validation.json.

Additional bounded probes closed the obvious wrong branches:

  • JWT tampering and alg:none: analysis/auth-probe.json, analysis/jwt-notes-probe.json
  • route/path injection: analysis/path-probe.json
  • fixed-delay permission priming: analysis/permission-race-probe.json
  • admin-looking account registration: analysis/admin-email-probe.json
  • object/array ID parser behavior without a content leak: analysis/parser-probe.json

The decisive clue was recorded as advisory research in analysis/research/exact-celestial-scribe-race-hint.md: this challenge requires grouped parallel requests with last-byte synchronization. That differs from the earlier fixed-delay TOCTOU test, so the branch was reopened with a new instrumentation plan.

The raw race harness validated the primitive live. In the first bounded race batch, multiple target reads of /api/notes/1 returned HTTP 200 with note ID admin-note-1 and title Secure System Configuration. The sanitized proof is stored in analysis/race-solve.json; the raw flag material is only in loot/.

Solve

The final solver is solve/race_solve.py.

High-level solve flow:

  1. Register and log in as a fresh user.
  2. List the fresh account's seeded notes and select one owned note GUID.
  3. Prepare raw HTTP requests for:

- GET /api/notes/<owned-guid>/check-permission

- GET /api/notes/1

  1. Open sockets and send every byte except the final byte of each request.
  2. Release the final byte of all grouped requests at the same time.
  3. Scan target note responses for a successful privileged note read and flag candidate.

The successful run is summarized in analysis/race-solve.json. It wrote the flag candidate to loot/flag-candidate.txt, then the harness captured it into loot/flag.txt.

Flag

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

Lessons

  • Fixed-delay TOCTOU checks do not disprove a real race. When the evidence calls for last-byte synchronization, use a raw HTTP or equivalent parallel-release harness.
  • Treat public writeups as leads only. The exact community hint was not accepted until the current instance returned a live privileged note response.
  • Keep raw tokens and flags in loot/; use sanitized analysis/ reports for reproducibility and review.

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: Celestial-Scribe
  • Category: Mobile
  • Difficulty: Medium
  • Mode: hybrid
  • Remote instance: <TARGET>:30357
  • Start time: 2026-06-11T08:31:47Z
  • 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/a12c734c-a4c3-4e5a-8caf-a8fb8c8ae634.zip4220994<hash redacted>Zip archive data, at least v2.0 to extract, compression method=deflatezip entries: 1 shown in artifact inventory JSON

Evidence Ledger

TimeActionOutput/FileFindingConfidenceNext
2026-06-11T08:31:47Zharness initchallenge-state.jsonWorkspace initialized with deterministic state fileHighInventory artifacts
2026-06-11T08:31:47Zartifact inventoryanalysis/artifact-inventory.json1 artifact(s) inventoriedHighBuild or update hypotheses
2026-06-11T08:31:47Zsession bootstrapnotes.mdChallenge metadata, scenario, and prior context seeded into workspaceHighRecord initial hypothesis and research
2026-06-11T08:31:47Zhypothesis recordedhypothesis-board.mdinitial triage from supplied challenge metadataMediuminventory files / inspect app surface / map routes depending on category
2026-06-11T08:31:47Zresearch taskanalysis/research/task-20260611T083147401636Z-3c7ef6e0.mdResearch task created for advisory investigationMediumRecord research output
2026-06-11T08:32:31Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T083231575654Z-56b9ba08.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T08:36:57Zlocal memory searchanalysis/research/local-memory-search-20260611T083657651050Z-1523cd3f.mdFound 8 safe prior-note result(s)MediumRecord useful result or skip
2026-06-11T08:37:06ZRAG queryanalysis/rag/rag-query-20260611T083657652994Z-07d7509d.txtRAG helper exited 0; output savedMediumRecord retrieval tag and validation
2026-06-11T08:38:00ZRAG recordanalysis/rag-records.mdRetrieved memory tagged MISSINGMediumValidate or reject with live evidence
2026-06-11T08:38:00Zsource auditanalysis/source-audit.mdSource audit recordedHighGate before exploit
2026-06-11T08:38:00Zresearch recordanalysis/research/research-records.mdResearch tagged GENERICMediumValidate against current evidence
2026-06-11T08:38:00Zinstrumentation plananalysis/instrumentation-plan.mdValidate the note privacy bypass primitive from decompiled APK endpoints without an Android emulator.HighStop after two negative primitive families without new behavior: direct IDOR/check-permission bypass and client-supplied ID collision/JWT structure.
2026-06-11T08:38:17Zhypothesis recordedhypothesis-board.mdTwo-account note authorization bypass through /api/notes/<id> or /check-permissionHighRegister two users, create a note under user A, and test list/check/read paths as user B.
2026-06-11T08:38:17Zhypothesis recordedhypothesis-board.mdClient-supplied cloud note IDs allow collision, overwrite, or predictable reserved note accessMediumCreate same ID under two accounts and inspect ownership/read behavior; probe safe common IDs only if baseline suggests it.
2026-06-11T08:38:17Zhypothesis recordedhypothesis-board.mdBearer token format exposes weak JWT/identity trustLowDecode token structure offline and validate only if server accepts a modified or unsigned token through /auth/verify.
2026-06-11T08:38:49Zlocal memory recordanalysis/local-memory-records.mdPrior local notes reviewed as fallback/advisory contextMediumValidate against current evidence
2026-06-11T08:39:12Zevaluatoranalysis/evaluator-20260611T083912772764Z-1e46be29.mdProceedHighBuild and run a token-safe API validation script, keeping raw token responses out of chat.
2026-06-11T08:42:48Zbranch closedhypothesis-board.mdServer enforces ownership for ordinary note IDs.HighRerank hypotheses
2026-06-11T08:42:48Zbranch closedhypothesis-board.mdBackend prevents ordinary cross-user ID collision/overwrite.HighRerank hypotheses
2026-06-11T08:57:57Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T085757810611Z-07cbf6a8.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T08:58:10ZRAG queryanalysis/rag/rag-query-20260611T085757869096Z-6ec31048.txtRAG helper exited 0; output savedMediumRecord retrieval tag and validation
2026-06-11T08:58:20ZRAG recordanalysis/rag-records.mdRetrieved memory tagged GENERICMediumValidate or reject with live evidence
2026-06-11T09:05:36Zbranch closedhypothesis-board.mdNo route/path payload produced content, stack traces, or status variance useful for exploitation.HighRerank hypotheses
2026-06-11T09:05:36Zbranch closedhypothesis-board.mdNotes authorization verifies token signatures consistently for tested variants.HighRerank hypotheses
2026-06-11T09:05:36Zbranch closedhypothesis-board.mdPermission-check state appears note-specific or read endpoint still enforces ownership.HighRerank hypotheses
2026-06-11T09:05:36Zbranch closedhypothesis-board.mdNo role/seeded-flag behavior was triggered by account email semantics.HighRerank hypotheses
2026-06-11T09:05:49Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T090549738376Z-38d8b262.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T09:05:49Zevaluatoranalysis/evaluator-20260611T090549791289Z-cb686457.mdValidate firstHighDo not repeat IDOR/JWT/path/route/special-email probes; seek a source-backed clue or targeted hint.
2026-06-11T10:25:17Zinstrumentation plananalysis/instrumentation-plan.mdValidate exact source-backed note-read race primitive without broad fuzzing.HighStop after bounded attempts against id 1 if all target reads remain access denied/timeouts and no new response class appears.
2026-06-11T10:25:17Zhypothesis recordedhypothesis-board.mdLast-byte race between owned check-permission and target note readMediumRegister fresh user, take an owned default note GUID, then repeatedly release raw GET /check-permission and GET /notes/1 at the same final byte and scan sanitized responses for a flag or non-403 target read.
2026-06-11T10:25:17Zresearch recordanalysis/research/research-records.mdResearch tagged PARTIALMediumValidate against current evidence
2026-06-11T10:25:28Zevaluatoranalysis/evaluator-20260611T102528053220Z-91b9d4a1.mdProceedHighImplement and run solve/race_solve.py against current remote instance.
2026-06-11T10:27:03Zflag captureloot/flag.txtHTB-format flag captured; raw value kept in loot onlyHighWrite solution and run completion gate
2026-06-11T10:27:46Zcompletion gatechallenge-state.jsonCompletion gate passed; state marked COMPLETEHighOptional sanitized memory summary approval

Key Findings

  • APK package: htb.d3vnu11.securenotes; the app is a cleartext HTTP client for http://<host>:<port>/api.
  • Live API is Express and implements /auth/register, /auth/login, /auth/verify, /notes, /notes/<id>, and /notes/<id>/check-permission.
  • Regular two-account IDOR is negative: cross-account check/read returns 403 Access denied.
  • JWT is HS256 and is verified consistently by both /auth/verify and notes routes for tested tampered/alg:none variants.
  • Route/path traversal and SQL-style note-ID payloads returned uniform access denied.
  • Permission-check priming did not allow reading a different note ID at 0/50/100/200 ms delays.
  • Special admin-looking email registrations produced ordinary accounts with only generic seeded notes.
  • Notable unresolved quirk: POST /notes accepts object/array id values, and object IDs can produce update/access-denied behavior. No content leak or ownership takeover was proven.
  • Current harness decision is Validate first; do not repeat the closed branches without backend source, a recovered JWT secret, or a narrow hint for the object-ID/parser primitive.

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.

Scenario

A new secure note-taking app promises complete privacy, or is it?

Operator Question

HTB Mobile Medium Celestial Scribe secure note-taking app privacy APK source remote flag solve path

Memory Summary

Metadata

  • Platform: HackTheBox Challenges
  • Category: Mobile
  • Challenge: Celestial-Scribe
  • 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
1initial triage from supplied challenge metadatachallenge name, category, difficulty, scenario, and remote target were provided by operatorinventory files / inspect app surface / map routes depending on categoryMediumActive
1Two-account note authorization bypass through /api/notes/<id> or /check-permissionAPK source exposes direct note read and a separate permission-check route; challenge scenario targets note privacy.Register two users, create a note under user A, and test list/check/read paths as user B.HighActive
2Client-supplied cloud note IDs allow collision, overwrite, or predictable reserved note accessAPK POST /api/notes accepts caller-provided id instead of forcing server-generated ID.Create same ID under two accounts and inspect ownership/read behavior; probe safe common IDs only if baseline suggests it.MediumActive
3Bearer token format exposes weak JWT/identity trustAPK stores and reuses server token; no client-side crypto beyond bearer flow.Decode token structure offline and validate only if server accepts a modified or unsigned token through /auth/verify.LowActive
1Last-byte race between owned check-permission and target note readExact community hint plus APK-confirmed two-step note-read flow; previous test only used delayed priming, not concurrent release.Register fresh user, take an owned default note GUID, then repeatedly release raw GET /check-permission and GET /notes/1 at the same final byte and scan sanitized responses for a flag or non-403 target read.MediumActive

Closed Branches

BranchEvidence TestedFailure OutputReason ClosedRevisit Condition
Simple direct note IDOR and check-permission bypassanalysis/api-validation.json: cross-account check and direct read of user A note as user B both returned 403.read_b_a_note_direct/check_b_a_note returned access deniedServer enforces ownership for ordinary note IDs.Only revisit if token/ID confusion or route injection changes identity or note ownership context.
Simple client-supplied note ID collisionanalysis/api-validation.json: user B attempted to create a note with user A's existing ID.create_b_same_id returned 403 access deniedBackend prevents ordinary cross-user ID collision/overwrite.Only revisit with parser/path traversal payload or if token forging changes ownership.
Route/path injection in note IDanalysis/path-probe.json and analysis/api-validation.jsonEncoded traversal and SQL-style route payloads returned uniform access denied/no flag.No route/path payload produced content, stack traces, or status variance useful for exploitation.Only revisit if backend source or a hint identifies a different ID parser.
JWT tampering / alg none / decoded-token notes authorizationanalysis/auth-probe.json and analysis/jwt-notes-probe.jsonAuth verify and notes endpoints rejected tampered, none-alg, and object-shaped ID payload tokens with 403.Notes authorization verifies token signatures consistently for tested variants.Only revisit with recovered JWT secret or backend source.
Permission-check priming / TOCTOUanalysis/permission-race-probe.jsonSuccessful own-note permission checks did not allow reading other note IDs at 0/50/100/200 ms.Permission-check state appears note-specific or read endpoint still enforces ownership.Only revisit with evidence of server-side cache keyed incorrectly.
Special admin-looking registrationsanalysis/admin-email-probe.jsonAdmin-looking emails registered as ordinary users and received only generic seeded notes.No role/seeded-flag behavior was triggered by account email semantics.Only revisit with a known existing admin email or password reset route.

Memory Summary

approval_required: true

Sanitized Memory Summary

Metadata

  • Platform: HackTheBox Challenges
  • Category: Mobile
  • Challenge: Celestial-Scribe
  • 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: Celestial-Scribe
  • Category: Mobile
  • Difficulty: Medium
  • Mode: hybrid
  • Remote instance: <TARGET>:30357
  • Start time: 2026-06-11T08:31:47Z
  • 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/a12c734c-a4c3-4e5a-8caf-a8fb8c8ae634.zip4220994<hash redacted>Zip archive data, at least v2.0 to extract, compression method=deflatezip entries: 1 shown in artifact inventory JSON

Evidence Ledger

TimeActionOutput/FileFindingConfidenceNext
2026-06-11T08:31:47Zharness initchallenge-state.jsonWorkspace initialized with deterministic state fileHighInventory artifacts
2026-06-11T08:31:47Zartifact inventoryanalysis/artifact-inventory.json1 artifact(s) inventoriedHighBuild or update hypotheses
2026-06-11T08:31:47Zsession bootstrapnotes.mdChallenge metadata, scenario, and prior context seeded into workspaceHighRecord initial hypothesis and research
2026-06-11T08:31:47Zhypothesis recordedhypothesis-board.mdinitial triage from supplied challenge metadataMediuminventory files / inspect app surface / map routes depending on category
2026-06-11T08:31:47Zresearch taskanalysis/research/task-20260611T083147401636Z-3c7ef6e0.mdResearch task created for advisory investigationMediumRecord research output
2026-06-11T08:32:31Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T083231575654Z-56b9ba08.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T08:36:57Zlocal memory searchanalysis/research/local-memory-search-20260611T083657651050Z-1523cd3f.mdFound 8 safe prior-note result(s)MediumRecord useful result or skip
2026-06-11T08:37:06ZRAG queryanalysis/rag/rag-query-20260611T083657652994Z-07d7509d.txtRAG helper exited 0; output savedMediumRecord retrieval tag and validation
2026-06-11T08:38:00ZRAG recordanalysis/rag-records.mdRetrieved memory tagged MISSINGMediumValidate or reject with live evidence
2026-06-11T08:38:00Zsource auditanalysis/source-audit.mdSource audit recordedHighGate before exploit
2026-06-11T08:38:00Zresearch recordanalysis/research/research-records.mdResearch tagged GENERICMediumValidate against current evidence
2026-06-11T08: <REDACTED>
2026-06-11T08:38:17Zhypothesis recordedhypothesis-board.mdTwo-account note authorization bypass through /api/notes/<id> or /check-permissionHighRegister two users, create a note under user A, and test list/check/read paths as user B.
2026-06-11T08:38:17Zhypothesis recordedhypothesis-board.mdClient-supplied cloud note IDs allow collision, overwrite, or predictable reserved note accessMediumCreate same ID under two accounts and inspect ownership/read behavior; probe safe common IDs only if baseline suggests it.
2026-06-11T08: <REDACTED>
2026-06-11T08:38:49Zlocal memory recordanalysis/local-memory-records.mdPrior local notes reviewed as fallback/advisory contextMediumValidate against current evidence
2026-06-11T08: <REDACTED>, keeping raw token responses out of chat.
2026-06-11T08:42:48Zbranch closedhypothesis-board.mdServer enforces ownership for ordinary note IDs.HighRerank hypotheses
2026-06-11T08:42:48Zbranch closedhypothesis-board.mdBackend prevents ordinary cross-user ID collision/overwrite.HighRerank hypotheses
2026-06-11T08:57:57Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T085757810611Z-07cbf6a8.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T08:58:10ZRAG queryanalysis/rag/rag-query-20260611T085757869096Z-6ec31048.txtRAG helper exited 0; output savedMediumRecord retrieval tag and validation
2026-06-11T08:58:20ZRAG recordanalysis/rag-records.mdRetrieved memory tagged GENERICMediumValidate or reject with live evidence
2026-06-11T09:05:36Zbranch closedhypothesis-board.mdNo route/path payload produced content, stack traces, or status variance useful for exploitation.HighRerank hypotheses
2026-06-11T09: <REDACTED>
2026-06-11T09:05:36Zbranch closedhypothesis-board.mdPermission-check state appears note-specific or read endpoint still enforces ownership.HighRerank hypotheses
2026-06-11T09: <REDACTED>
2026-06-11T09:05:49Zcheckpoint recordedanalysis/checkpoint-analysis-20260611T090549738376Z-38d8b262.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-11T09: <REDACTED>
2026-06-11T10:25:17Zinstrumentation plananalysis/instrumentation-plan.mdValidate exact source-backed note-read race primitive without broad fuzzing.HighStop after bounded attempts against id 1 if all target reads remain access denied/timeouts and no new response class appears.
2026-06-11T10: <REDACTED>, take an owned default note GUID, then repeatedly release raw GET /check-permission and GET /notes/1 at the same final byte and scan sanitized responses for a flag or non-403 target read.
2026-06-11T10:25:17Zresearch recordanalysis/research/research-records.mdResearch tagged PARTIALMediumValidate against current evidence
2026-06-11T10:25:28Zevaluatoranalysis/evaluator-20260611T102528053220Z-91b9d4a1.mdProceedHighImplement and run solve/race_solve.py against current remote instance.
2026-06-11T10: <REDACTED>
2026-06-11T10:27:46Zcompletion gatechallenge-state.jsonCompletion gate passed; state marked COMPLETEHighOptional sanitized memory summary approval

Key Findings

  • APK package: htb.d3vnu11.securenotes; the app is a cleartext HTTP client for http://<host>:<port>/api.
  • Live API is Express and implements /auth/register, /auth/login, /auth/verify, /notes, /notes/<id>, and /notes/<id>/check-permission.
  • Regular two-account IDOR is negative: cross-account check/read returns 403 Access denied.
  • JWT is HS256 and is verified consistently by both /auth/verify and notes routes for tested tampered/`alg: <REDACTED>
  • Route/path traversal and SQL-style note-ID payloads returned uniform access denied.
  • Permission-check priming did not allow reading a different note ID at 0/50/100/200 ms delays.
  • Special admin-looking email registrations produced ordinary accounts with only generic seeded notes.
  • Notable unresolved quirk: POST /notes accepts object/array id values, and object IDs can produce update/access-denied behavior. No content leak or ownership takeover was proven.
  • Current harness decision is Validate first; do not repeat the closed branches without backend source, a recovered JWT secret, or a narrow hint for the object-ID/parser primitive.

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.

Scenario

A new secure note-taking app promises complete privacy, or is it?

Operator Question

HTB Mobile Medium Celestial Scribe secure note-taking app privacy APK source remote flag solve path

Technical analogy

How to remember this solve

Think of the app like a packed suitcase. You unpack it, inspect the labels and hidden pockets, then trace which local file or network call contains the useful clue.

For Celestial Scribe, 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.