Challenge / Crypto

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

EasyPublished 2024-04-09Sanitized local writeup

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.

Embryonic Plant sanitized attack graph

Walkthrough flow

01

Challenge parameters

02

Weak assumption

03

Recovered secret state

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.

  • 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 live n, s, and

enc_flag.

  • analysis/decrypt-redacted.txt: decrypted plaintext with the flag redacted.

Analysis

The source has:

text
s_next = (s*p + q) mod r
n = p*q*r

For output differences d_i = s_{i+1} - s_i, the recurrence gives:

text
d_{i+1} = p*d_i mod r

Therefore:

text
r | d_{i+2}*d_i - d_{i+1}^2

Taking the GCD of n and two such determinants recovers r. Then:

text
p = d_1 * inverse(d_0, r) mod r
q = s_2 - p*s_1 mod r

The 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:

bash
python3 solve/solve.py --host <TARGET> --port 30340

The 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

FileSizeSHA256TypeNotes
files/a12c7374-1a55-4bfc-aa2e-4ddc453c66aa.zip910<hash redacted>Zip archive data, at least v1.0 to extract, compression method=storezip entries: 2 shown in artifact inventory JSON

Evidence Ledger

TimeActionOutput/FileFindingConfidenceNext
2026-06-09T13:39:14Zharness initchallenge-state.jsonWorkspace initialized with deterministic state fileHighInventory artifacts
2026-06-09T13:39:29Zartifact inventoryanalysis/artifact-inventory.json1 artifact(s) inventoriedHighBuild or update hypotheses
2026-06-09T13:40:05Zhypothesis recordedhypothesis-board.mdRecover r from recurrence determinant gcds, recover p and q modulo r, factor n, compute RSA private exponent d, derive AES key, decrypt enc_flag.MediumUse consecutive output differences to compute gcd(n, d2d0-d1^2, d3d1-d2^2).
2026-06-09T13:40:06Zsource auditanalysis/source-audit.mdSource audit recordedHighGate before exploit
2026-06-09T13:40:16Zcheckpoint recordedanalysis/checkpoint-analysis-20260609T134016483847Z-e48d482a.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-09T13:41:00Zlocal memory recordanalysis/local-memory-records.mdPrior local notes reviewed as fallback/advisory contextMediumValidate against current evidence
2026-06-09T13:41:14Zevaluatoranalysis/evaluator-20260609T134114771644Z-a989731d.mdProceedHighWrite solve.py, fetch live parameters, decrypt locally, capture flag.
2026-06-09T13:42:00Zlive solveanalysis/remote-instance-output.txtRemote printed n, five recurrence outputs, and enc_flag; solver recovered factors and decrypted a valid HTB-format flag candidateHighCapture with harness
2026-06-09T13:42:30Zsolve scriptsolve/solve.pyReproducible solver implements determinant GCD recovery, RSA private exponent derivation, and AES decryptHighComplete challenge
2026-06-09T13:42:14Zflag captureloot/flag.txtHTB-format flag captured; raw value kept in loot onlyHighWrite solution and run completion gate
2026-06-09T13:43:01Zsource auditanalysis/source-audit.mdSource audit recordedHighGate before exploit
2026-06-09T13:43:02Zcompletion gatechallenge-state.jsonCompletion gate passed; state marked COMPLETEHighOptional sanitized memory summary approval

Key Findings

  • server.py defines n = pqr for 768-bit primes with p,q < r.
  • The RNG recurrence is s_next = (s*p + q) mod r; five outputs leak the modulus r.
  • Consecutive differences satisfy d_{i+1} = pd_i mod r, so r divides d_{i+2}d_i - d_{i+1}^2.
  • gcd(n, determinant_0, determinant_1) recovers r.
  • p = d_1 inverse(d_0, r) mod r, and q = s_2 - ps_1 mod r.
  • Once p,q,r are known, compute d = inverse(0x10001, phi), derive the AES key as sha256(long_to_bytes(d)), and decrypt enc_flag.

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: 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.

RankPathEvidenceMissing ProofCheapest ValidationConfidenceStatus
1Recover 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).MediumActive

Closed Branches

BranchEvidence TestedFailure OutputReason ClosedRevisit 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

FileSizeSHA256TypeNotes
files/a12c7374-1a55-4bfc-aa2e-4ddc453c66aa.zip910<hash redacted>Zip archive data, at least v1.0 to extract, compression method=storezip entries: 2 shown in artifact inventory JSON

Evidence Ledger

TimeActionOutput/FileFindingConfidenceNext
2026-06-09T13:39:14Zharness initchallenge-state.jsonWorkspace initialized with deterministic state fileHighInventory artifacts
2026-06-09T13:39:29Zartifact inventoryanalysis/artifact-inventory.json1 artifact(s) inventoriedHighBuild or update hypotheses
2026-06-09T13:40:05Zhypothesis recordedhypothesis-board.mdRecover r from recurrence determinant gcds, recover p and q modulo r, factor n, compute RSA private exponent d, derive AES key, decrypt enc_flag.MediumUse consecutive output differences to compute gcd(n, d2d0-d1^2, d3d1-d2^2).
2026-06-09T13:40:06Zsource auditanalysis/source-audit.mdSource audit recordedHighGate before exploit
2026-06-09T13:40:16Zcheckpoint recordedanalysis/checkpoint-analysis-20260609T134016483847Z-e48d482a.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-09T13:41:00Zlocal memory recordanalysis/local-memory-records.mdPrior local notes reviewed as fallback/advisory contextMediumValidate 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 candidateHighCapture with harness
2026-06-09T13:42:30Zsolve scriptsolve/solve.pyReproducible solver implements determinant GCD recovery, RSA private exponent derivation, and AES decryptHighComplete challenge
2026-06-09T13: <REDACTED>
2026-06-09T13:43:01Zsource auditanalysis/source-audit.mdSource audit recordedHighGate before exploit
2026-06-09T13:43:02Zcompletion gatechallenge-state.jsonCompletion gate passed; state marked COMPLETEHighOptional sanitized memory summary approval

Key Findings

  • server.py defines n = pqr for 768-bit primes with p,q < r.
  • The RNG recurrence is s_next = (s*p + q) mod r; five outputs leak the modulus r.
  • Consecutive differences satisfy d_{i+1} = pd_i mod r, so r divides d_{i+2}d_i - d_{i+1}^2.
  • gcd(n, determinant_0, determinant_1) recovers r.
  • p = d_1 inverse(d_0, r) mod r, and q = s_2 - ps_1 mod r.
  • Once p,q,r are known, compute d = inverse(0x10001, phi), derive the AES key as sha256(long_to_bytes(d)), and decrypt enc_flag.

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 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.