Cryptohorrific
Cryptohorrific is a sanitized challenge note from the local HTB archive, organized for quick review by category, difficulty, evidence flow, and reusable operator
Scenario
Cryptohorrific attack path
Cryptohorrific 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.
Walkthrough flow
Extracted an iOS Simulator .app bundle from the...
Found challenge.plist containing a Base64-encoded...
Used Mach-O Objective-C metadata and otool...
Verified the app reads the plist proof,...
Reconstructed CCCrypt parameters from register/stack...
Source coverage
High source coverage
Status: complete. This article is generated from 4 sanitized Markdown sources and keeps raw flags, credentials, keys, cookies, and reusable secrets out of the rendered blog.
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/Cryptohorrific/writeup.md
- htb-challenge/Mobile/Cryptohorrific/notes.md
- htb-challenge/Mobile/Cryptohorrific/memory-summary.md
- htb-challenge/Mobile/Cryptohorrific/hypothesis-board.md
Technical Walkthrough
Writeup
Challenge
- Name: Cryptohorrific
- Category: Mobile
- Difficulty: Medium
- Mode: file
Summary
The archive contains an iOS Simulator .app bundle. The app stores a Base64 ciphertext in challenge.plist and decrypts it at launch with CommonCrypto.
Static Mach-O analysis showed the decrypt routine uses AES with PKCS7 padding and ECB mode. The hardcoded key is stored as a constant NSString in the binary. Replaying the same decrypt operation against the plist ciphertext recovers the flag.
Artifact Inventory
files/a12c7373-8d1f-4cf7-94d7-f895d8927018.zip: original HTB archive.analysis/extracted/hackthebox.app/: extracted iOS app bundle.analysis/extracted/hackthebox.app/hackthebox: Mach-O 64-bit x86_64 executable.analysis/extracted/hackthebox.app/challenge.plist: plist containing the encryptedflagvalue.analysis/otool-disasm.txt: Objective-C and CommonCrypto call flow evidence.analysis/crypto-params.txt: reconstructed crypto parameters.
Analysis
file identified the executable as a 64-bit Mach-O for x86_64. This matched the bundle metadata in analysis/info-plist.txt, which marks the supported platform as iPhoneSimulator.
challenge.plist contains one dictionary with a Base64-encoded flag field. The binary imports _CCCrypt, and Objective-C metadata exposes a method named SecretManager:key:iv:data:.
The viewDidLoad disassembly in analysis/otool-disasm.txt shows the app:
- opens
challenge.plist; - reads index
0; - extracts the
flagkey; - Base64-decodes the string into
NSData; - calls
SecretManager:key:iv:data:.
The SecretManager:key:iv:data: disassembly then sets up CCCrypt as:
- operation: decrypt;
- algorithm: AES;
- options: PKCS7 padding plus ECB mode;
- key length: 16 bytes;
- input: Base64-decoded plist ciphertext.
The two constant NSStrings used as key and IV are in __cfstring. The IV is still passed to CCCrypt, but ECB mode does not use it.
Solve
solve/solve.py reproduces the app behavior:
- loads
analysis/extracted/hackthebox.app/challenge.plist; - Base64-decodes the
flagvalue; - decrypts with <secret redacted> and PKCS7 unpadding;
- writes the candidate to
loot/flag-candidate.txt.
The harness captured the candidate into loot/flag.txt.
Flag
Raw flag is stored in loot/flag.txt and intentionally not reproduced here.
Lessons
- Mobile challenges are not always APKs; inspect the archive before assuming Android tooling.
- CommonCrypto calls can be reconstructed directly from x86_64 Mach-O register setup.
kCCOptionECBModemakes an IV parameter irrelevant even if the application passes one.- Treat RAG as advisory only; the decisive proof was the current binary’s
CCCryptcall setup.
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: Cryptohorrific
- Category: Mobile
- Difficulty: Medium
- Mode: file
- Remote instance: none
- Start time: 2026-06-15T04:39:28Z
- 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
| File | Size | SHA256 | Type | Notes |
|---|---|---|---|---|
files/a12c7373-8d1f-4cf7-94d7-f895d8927018.zip | 26184 | <hash redacted> | Zip archive data, at least v2.0 to extract, compression method=store | zip entries: 17 shown in artifact inventory JSON |
Evidence Ledger
| Time | Action | Output/File | Finding | Confidence | Next |
|---|---|---|---|---|---|
| 2026-06-15T04:39:28Z | harness init | challenge-state.json | Workspace initialized with deterministic state file | High | Inventory artifacts |
| 2026-06-15T04:39:28Z | artifact inventory | analysis/artifact-inventory.json | 1 artifact(s) inventoried | High | Build or update hypotheses |
| 2026-06-15T04:39:28Z | hypothesis recorded | hypothesis-board.md | Reverse the mobile artifact, identify insecure cryptography or hardcoded material, and recover the HTB flag from app resources/code. | Medium | Extract APK/source, inspect manifest/resources/classes, and search for crypto APIs, embedded ciphertext, keys, and flag validation logic. |
| 2026-06-15T04:39:39Z | checkpoint recorded | analysis/checkpoint-triage-20260615T043939369546Z-ce3714a1.md | Checkpoint for TRIAGE | High | Use checkpoint to drive next decision |
| 2026-06-15T04:41:24Z | RAG query | analysis/rag/rag-query-20260615T044111117094Z-ed89c336.txt | RAG helper exited 0; output saved | Medium | Record retrieval tag and validation |
| 2026-06-15T04:42:20Z | instrumentation plan | analysis/instrumentation-plan.md | Recover the encrypted flag from the iOS Mach-O app by validating CommonCrypto parameters statically. | High | If static CCCrypt parameter reconstruction fails or decrypted output is not HTB-formatted, request apktool/class-dump/Ghidra-style tooling instead of guessing alternate modes. |
| 2026-06-15T04:42:36Z | RAG record | analysis/rag-records.md | Retrieved memory tagged MATCHED | Medium | Validate or reject with live evidence |
| 2026-06-15T04:42:36Z | research record | analysis/research/research-records.md | Research tagged MATCHED | Medium | Validate against current evidence |
| 2026-06-15T04:42:44Z | evaluator | analysis/evaluator-20260615T044244753271Z-3e17e633.md | Proceed | High | Gate before exploit and capture the locally recovered flag candidate. |
| 2026-06-15T04:42:50Z | flag capture | loot/flag.txt | HTB-format flag captured; raw value kept in loot only | High | Write solution and run completion gate |
| 2026-06-15T04:43:41Z | flag capture | loot/flag.txt | HTB-format flag captured; raw value kept in loot only | High | Write solution and run completion gate |
| 2026-06-15T04:43:49Z | completion gate | challenge-state.json | Completion gate passed; state marked COMPLETE | High | Optional sanitized memory summary approval |
Key Findings
- The archive contains an iPhone Simulator
.appbundle, not an Android APK. - Main binary:
analysis/extracted/hackthebox.app/hackthebox, Mach-O 64-bit x86_64. challenge.pliststores a Base64-encodedflagvalue.ViewController viewDidLoadloadschallenge.plist, readsflag, Base64-decodes it, and passes the bytes intoSecretManager:key:iv:data:.SecretManager:key:iv:data:wrapsCCCryptwith decrypt operation, AES, 16-byte key, PKCS7 padding, and ECB mode.- The IV string is passed but ignored because ECB mode is set.
- Reproducible solver:
solve/solve.py. - Raw captured flag:
loot/flag.txt.
RAG / Advisory Memory
RAG output is advisory only. Record evaluated retrievals with:
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: Mobile
- Challenge: Cryptohorrific
- 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.
- Extracted an iOS Simulator
.appbundle from the challenge archive. - Found
challenge.plistcontaining a Base64-encoded encrypted flag field. - Used Mach-O Objective-C metadata and
otooldisassembly to locateViewController viewDidLoadandSecretManager:key:iv:data:. - Verified the app reads the plist flag, Base64-decodes it, then passes it to CommonCrypto.
- Reconstructed
CCCryptparameters from register/stack setup: decrypt, AES, PKCS7 padding, ECB mode, 16-byte key. - Decrypted the plist ciphertext with a reproducible Python solver.
- Captured the recovered HTB flag through the harness.
Reusable Lessons
- Do not assume Mobile means Android; this was an iPhone Simulator Mach-O app.
otool -ovandotool -tvVcan be enough for small Objective-C iOS Simulator binaries.- In CommonCrypto, options value
3means PKCS7 padding plus ECB mode. - In ECB mode, an IV argument can be present but unused.
Dead Ends
- APK/JADX path was not applicable after ZIP inventory showed an iOS
.app. - Runtime/emulator tooling was unnecessary because the static CommonCrypto parameters were complete.
Tool Quirks
apktool,adb,frida, andclass-dumpwere unavailable, but did not block the solve.otool -tvVproduced usable disassembly;otool -tValone initially produced no useful output.- Python crypto libraries were available locally; solver supports both
pycryptodomeandcryptography.
Evidence Paths
analysis/challenge-plist.txtanalysis/otool-objc.txtanalysis/otool-disasm.txtanalysis/crypto-params.txtsolve/solve.pyloot/flag.txt
Ingestion Decision
- Proposed for LightRAG: yes
- 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.
| Rank | Path | Evidence | Missing Proof | Cheapest Validation | Confidence | Status |
|---|---|---|---|---|---|---|
| 1 | Reverse the mobile artifact, identify insecure cryptography or hardcoded material, and recover the HTB flag from app resources/code. | Challenge is Mobile/Medium named Cryptohorrific; prompt emphasizes secure coding and application security. | Extract APK/source, inspect manifest/resources/classes, and search for crypto APIs, embedded ciphertext, keys, and flag validation logic. | Medium | Active |
Closed Branches
| Branch | Evidence Tested | Failure Output | Reason Closed | Revisit Condition |
|---|
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 Cryptohorrific, 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.