Embryonic Plant
Embryonic Plant is a sanitized challenge note from the local HTB archive, organized for quick review by category, difficulty, evidence flow, and reusable operator
Scenario
Embryonic Plant attack path
Embryonic Plant 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 Crypto evidence, validation, and reusable operator lessons.
Walkthrough flow
Challenge parameters
Weak assumption
Recovered secret state
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.
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.
- Crypto/Embryonic-Plant/writeup.md
- htb-challenge/Crypto/Embryonic-Plant/notes.md
- htb-challenge/Crypto/Embryonic-Plant/memory-summary.md
- htb-challenge/Crypto/Embryonic-Plant/hypothesis-board.md
- HTB/_knowledge/exports/ctf-lightrag-latest-203412/documents/challenge__Crypto__Embryonic-Plant__memory-summary.md.77e981cb73.md
- HTB/_knowledge/exports/ctf-lightrag-latest-203412/documents/challenge__Crypto__Embryonic-Plant__notes.md.b9aceee5fd.md
Technical Walkthrough
Writeup
Challenge
- Name: Embryonic-Plant
- Category: Crypto
- Difficulty: Easy
- Mode: hybrid
Summary
The server prints a three-prime RSA modulus n, five outputs from a linear
recurrence modulo one prime factor r, and an AES-encrypted flag. The recurrence
outputs leak r through standard LCG determinant relations. After recovering
r, p and q follow directly from output differences, allowing recovery of
the RSA private exponent d. The AES key is sha256(long_to_bytes(d)), so the
flag decrypts locally.
Artifact Inventory
files/a12c7374-1a55-4bfc-aa2e-4ddc453c66aa.zip: original challenge ZIP.files/extracted/crypto_embryonic_plant/server.py: source for the remote
service.
- Remote instance:
<TARGET>:30340. analysis/remote-instance-output.txt: captured liven,s, and
enc_flag.
analysis/decrypt-redacted.txt: decrypted plaintext with the flag redacted.
Analysis
The source has:
s_next = (s*p + q) mod r
n = p*q*rFor output differences d_i = s_{i+1} - s_i, the recurrence gives:
d_{i+1} = p*d_i mod rTherefore:
r | d_{i+2}*d_i - d_{i+1}^2Taking the GCD of n and two such determinants recovers r. Then:
p = d_1 * inverse(d_0, r) mod r
q = s_2 - p*s_1 mod rThe recovered pqr validates against n. From there, compute phi,
recover d, derive the AES key with SHA-256, and decrypt the ECB ciphertext.
Solve
Run:
python3 solve/solve.py --host <TARGET> --port 30340The script writes:
- raw flag candidate:
loot/flag-candidate.txt - redacted plaintext:
analysis/decrypt-redacted.txt - live service output:
analysis/remote-instance-output.txt
Flag
Raw flag is stored in loot/flag.txt and intentionally not reproduced here.
Lessons
- A small number of LCG-like outputs can be enough when the modulus is a hidden
factor of a known composite.
- Always use the source to derive the exact leakage relation before treating a
crypto challenge as a generic factoring problem.
- Keep public/RAG research advisory only; here the provided source was sufficient
to derive the full solve.
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: Embryonic-Plant
- Category: Crypto
- Difficulty: Easy
- Mode: hybrid
- Remote instance: <TARGET>:30340
- Start time: 2026-06-09T13:39: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
| File | Size | SHA256 | Type | Notes |
|---|---|---|---|---|
files/a12c7374-1a55-4bfc-aa2e-4ddc453c66aa.zip | 910 | <hash redacted> | Zip archive data, at least v1.0 to extract, compression method=store | zip entries: 2 shown in artifact inventory JSON |
Evidence Ledger
| Time | Action | Output/File | Finding | Confidence | Next |
|---|---|---|---|---|---|
| 2026-06-09T13:39:14Z | harness init | challenge-state.json | Workspace initialized with deterministic state file | High | Inventory artifacts |
| 2026-06-09T13:39:29Z | artifact inventory | analysis/artifact-inventory.json | 1 artifact(s) inventoried | High | Build or update hypotheses |
| 2026-06-09T13:40:05Z | hypothesis recorded | hypothesis-board.md | Recover r from recurrence determinant gcds, recover p and q modulo r, factor n, compute RSA private exponent d, derive AES key, decrypt enc_flag. | Medium | Use consecutive output differences to compute gcd(n, d2d0-d1^2, d3d1-d2^2). |
| 2026-06-09T13:40:06Z | source audit | analysis/source-audit.md | Source audit recorded | High | Gate before exploit |
| 2026-06-09T13:40:16Z | checkpoint recorded | analysis/checkpoint-analysis-20260609T134016483847Z-e48d482a.md | Checkpoint for ANALYSIS | High | Use checkpoint to drive next decision |
| 2026-06-09T13:41:00Z | local memory record | analysis/local-memory-records.md | Prior local notes reviewed as fallback/advisory context | Medium | Validate against current evidence |
| 2026-06-09T13:41:14Z | evaluator | analysis/evaluator-20260609T134114771644Z-a989731d.md | Proceed | High | Write solve.py, fetch live parameters, decrypt locally, capture flag. |
| 2026-06-09T13:42:00Z | live solve | analysis/remote-instance-output.txt | Remote printed n, five recurrence outputs, and enc_flag; solver recovered factors and decrypted a valid HTB-format flag candidate | High | Capture with harness |
| 2026-06-09T13:42:30Z | solve script | solve/solve.py | Reproducible solver implements determinant GCD recovery, RSA private exponent derivation, and AES decrypt | High | Complete challenge |
| 2026-06-09T13:42:14Z | flag capture | loot/flag.txt | HTB-format flag captured; raw value kept in loot only | High | Write solution and run completion gate |
| 2026-06-09T13:43:01Z | source audit | analysis/source-audit.md | Source audit recorded | High | Gate before exploit |
| 2026-06-09T13:43:02Z | completion gate | challenge-state.json | Completion gate passed; state marked COMPLETE | High | Optional sanitized memory summary approval |
Key Findings
server.pydefinesn = pqrfor 768-bit primes withp,q < r.- The RNG recurrence is
s_next = (s*p + q) mod r; five outputs leak the modulusr. - Consecutive differences satisfy
d_{i+1} = pd_i mod r, sordividesd_{i+2}d_i - d_{i+1}^2. gcd(n, determinant_0, determinant_1)recoversr.p = d_1 inverse(d_0, r) mod r, andq = s_2 - ps_1 mod r.- Once
p,q,rare known, computed = inverse(0x10001, phi), derive the AES key assha256(long_to_bytes(d)), and decryptenc_flag.
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: Crypto
- Challenge: Embryonic-Plant
- Difficulty: Easy
- 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.
| Rank | Path | Evidence | Missing Proof | Cheapest Validation | Confidence | Status |
|---|---|---|---|---|---|---|
| 1 | Recover r from recurrence determinant gcds, recover p and q modulo r, factor n, compute RSA private exponent d, derive AES key, decrypt enc_flag. | server.py emits n, five RNG outputs s, and AES-ECB encryption under sha256(long_to_bytes(d)); RNG is s_next = sp + q mod r with p,q<r and n=pq*r. | Use consecutive output differences to compute gcd(n, d2d0-d1^2, d3d1-d2^2). | Medium | Active |
Closed Branches
| Branch | Evidence Tested | Failure Output | Reason Closed | Revisit Condition |
|---|
Memory Summary
approval_required: true
Sanitized Memory Summary
Metadata
- Platform: HackTheBox Challenges
- Category: Crypto
- Challenge: Embryonic-Plant
- Difficulty: Easy
- 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: Embryonic-Plant
- Category: Crypto
- Difficulty: Easy
- Mode: hybrid
- Remote instance: <TARGET>:30340
- Start time: 2026-06-09T13:39: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
| File | Size | SHA256 | Type | Notes |
|---|---|---|---|---|
files/a12c7374-1a55-4bfc-aa2e-4ddc453c66aa.zip | 910 | <hash redacted> | Zip archive data, at least v1.0 to extract, compression method=store | zip entries: 2 shown in artifact inventory JSON |
Evidence Ledger
| Time | Action | Output/File | Finding | Confidence | Next |
|---|---|---|---|---|---|
| 2026-06-09T13:39:14Z | harness init | challenge-state.json | Workspace initialized with deterministic state file | High | Inventory artifacts |
| 2026-06-09T13:39:29Z | artifact inventory | analysis/artifact-inventory.json | 1 artifact(s) inventoried | High | Build or update hypotheses |
| 2026-06-09T13:40:05Z | hypothesis recorded | hypothesis-board.md | Recover r from recurrence determinant gcds, recover p and q modulo r, factor n, compute RSA private exponent d, derive AES key, decrypt enc_flag. | Medium | Use consecutive output differences to compute gcd(n, d2d0-d1^2, d3d1-d2^2). |
| 2026-06-09T13:40:06Z | source audit | analysis/source-audit.md | Source audit recorded | High | Gate before exploit |
| 2026-06-09T13:40:16Z | checkpoint recorded | analysis/checkpoint-analysis-20260609T134016483847Z-e48d482a.md | Checkpoint for ANALYSIS | High | Use checkpoint to drive next decision |
| 2026-06-09T13:41:00Z | local memory record | analysis/local-memory-records.md | Prior local notes reviewed as fallback/advisory context | Medium | Validate against current evidence |
| 2026-06-09T13: <REDACTED>, fetch live parameters, decrypt locally, capture flag. | |||||
2026-06-09T13: <REDACTED>, five recurrence outputs, and enc_flag; solver recovered factors and decrypted a valid HTB-format flag candidate | High | Capture with harness | |||
| 2026-06-09T13:42:30Z | solve script | solve/solve.py | Reproducible solver implements determinant GCD recovery, RSA private exponent derivation, and AES decrypt | High | Complete challenge |
| 2026-06-09T13: <REDACTED> | |||||
| 2026-06-09T13:43:01Z | source audit | analysis/source-audit.md | Source audit recorded | High | Gate before exploit |
| 2026-06-09T13:43:02Z | completion gate | challenge-state.json | Completion gate passed; state marked COMPLETE | High | Optional sanitized memory summary approval |
Key Findings
server.pydefinesn = pqrfor 768-bit primes withp,q < r.- The RNG recurrence is
s_next = (s*p + q) mod r; five outputs leak the modulusr. - Consecutive differences satisfy
d_{i+1} = pd_i mod r, sordividesd_{i+2}d_i - d_{i+1}^2. gcd(n, determinant_0, determinant_1)recoversr.p = d_1 inverse(d_0, r) mod r, andq = s_2 - ps_1 mod r.- Once
p,q,rare known, computed = inverse(0x10001, phi), derive the AES key assha256(long_to_bytes(d)), and decryptenc_flag.
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.
Technical analogy
How to remember this solve
Think of the challenge like a locked box where the lock is mathematical but slightly flawed. The goal is not to smash the box; it is to notice which part of the lock repeats, leaks, or trusts the wrong assumption.
For Embryonic Plant, 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.