Challenge / Reversing

Regas Town

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

MediumPublished 2025-07-21Sanitized local writeup

Scenario

Regas Town attack path

Regas Town 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 Reversing evidence, validation, and reusable operator lessons.

Regas Town sanitized attack graph

Walkthrough flow

01

Binary triage

02

Control-flow recovery

03

Key logic reconstruction

04

Proof captured

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.

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

  • Reversing/Regas-Town/writeup.md
  • htb-challenge/Reversing/Regas-Town/notes.md
  • htb-challenge/Reversing/Regas-Town/memory-summary.md
  • htb-challenge/Reversing/Regas-Town/hypothesis-board.md

Technical Walkthrough

Writeup

Challenge

  • Name: Regas-Town
  • Category: Reversing
  • Difficulty: Medium
  • Mode: file

Summary

Rega's Town is a Rust reversing challenge built around regular-expression rules and arithmetic checks over parts of the input. The binary includes debug symbols, so the relevant functions are visible: filter_input, multiply_characters, check_input, and main.

The solve path is static: extract the regex rules from .rodata, recover the fixed string slices and product constants from check_input, apply two hidden index checks in main, and resolve the final product-order collision using the challenge title.

Artifact Inventory

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

  • files/extracted/dist/rega_town: Rust x86-64 PIE ELF, dynamically linked, with debug info, not stripped.
  • No remote instance is required for this challenge.
  • Main artifacts:

- analysis/source-audit.md

- analysis/disasm-filter_input.txt

- analysis/disasm-check_input.txt

- analysis/disasm-main.txt

- analysis/solver-summary.txt

Analysis

filter_input copies a 9-element Rust &str array from .rodata and compiles each entry with the Rust regex crate. The extracted patterns constrain the flag shape, length, fixed HTB-style wrapping, uppercase positions, underscores, digit count, and several fixed phrase fragments.

multiply_characters maps each character to its Unicode codepoint and multiplies the values as u128.

check_input extracts seven ranges and compares their products:

  • [4:7]
  • [8:11]
  • [12:15]
  • [16:20]
  • [21:23]
  • [24:27]
  • [28:32]

main then checks two individual characters from the collected Vec<char>, resolving two product collisions. The final remaining collision is between a real word and a transposed spelling; the challenge title selects the real word.

Solve

Run:

bash
python3 solve/solve.py

The solver enumerates segment candidates from the regex character classes, filters them by the recovered product constants, applies the two hidden index checks, ranks the semantic candidates, and writes the selected HTB-format value to loot/flag-candidate.txt.

Flag

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

Lessons

  • Rust debug symbols can make a large static binary tractable if you focus only on challenge-owned functions.
  • Product checks over characters are collision-prone; look for additional disambiguation checks or semantic hints.
  • Regex extraction from Rust &str arrays is more reliable than relying on concatenated strings output.

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: Regas-Town
  • Category: Reversing
  • Difficulty: Medium
  • Mode: file
  • Remote instance: none
  • Start time: 2026-06-12T06:02:54Z
  • 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/a12c7398-0fcf-4385-8cf4-1e0f90f48ab9.zip5159621<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-12T06:02:54Zharness initchallenge-state.jsonWorkspace initialized with deterministic state fileHighInventory artifacts
2026-06-12T06:03:09Zartifact inventoryanalysis/artifact-inventory.json1 artifact(s) inventoriedHighBuild or update hypotheses
2026-06-12T06:06:37Zhypothesis recordedhypothesis-board.mdRun the Linux ELF under an amd64 container for behavioral validationMediumIf needed, run a linux/amd64 container with the binary mounted and feed the derived passphrase
2026-06-12T06:06:37Zhypothesis recordedhypothesis-board.mdRecover passphrase by extracting Rust regex constraints and u128 character-product checksHighParse the regex array and product constants, enumerate small segment collisions, and select the meaningful flag phrase
2026-06-12T06:07:36Zsource auditanalysis/source-audit.mdSource audit recordedHighGate before exploit
2026-06-12T06:07:36Zcheckpoint recordedanalysis/checkpoint-analysis-20260612T060736849226Z-31ec9b1d.mdCheckpoint for ANALYSISHighUse checkpoint to drive next decision
2026-06-12T06:07:38Zlocal memory searchanalysis/research/local-memory-search-20260612T060738506300Z-6d3bccc7.mdFound 5 safe prior-note result(s)MediumRecord useful result or skip
2026-06-12T06:08:59Zresearch recordanalysis/research/research-records.mdResearch tagged MATCHEDMediumValidate against current evidence
2026-06-12T06:08:59Zlocal memory recordanalysis/local-memory-records.mdPrior local notes reviewed as fallback/advisory contextMediumValidate against current evidence
2026-06-12T06:08:59Zinstrumentation plananalysis/instrumentation-plan.mdDerive and validate the Rega's Town HTB flag from static Rust binary constraintsHighStop if the solver finds zero candidates, multiple equally plausible semantic candidates after hidden checks, or if evidence contradicts the extracted constants.
2026-06-12T06:09:15Zevaluatoranalysis/evaluator-20260612T060915125086Z-5a3392e6.mdProceedHighBuild and run deterministic solver, then capture the candidate with challenge_harness capture-flag.
2026-06-12T06:11:00Zflag captureloot/flag.txtHTB-format flag captured; raw value kept in loot onlyHighWrite solution and run completion gate
2026-06-12T06:12:23Zcompletion gatechallenge-state.jsonCompletion gate passed; state marked COMPLETEHighOptional sanitized memory summary approval

Key Findings

  • The binary is a Rust x86-64 ELF with debug symbols and visible rega_town::* functions.
  • filter_input validates nine Rust regexes stored as a .rodata array of &str.
  • check_input slices the candidate into seven fixed ranges and compares u128 products of character codepoints.
  • main adds two hidden collision breakers: character index 5 must be '0', and index 9 must be 'r'.
  • Product checks are lossy; after hidden checks, the remaining ambiguity is a Town/Twon product-order collision.
  • The solver chooses the natural challenge-title phrase and stores the HTB-format value only in loot/.

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: Reversing
  • Challenge: Regas-Town
  • 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
2Run the Linux ELF under an amd64 container for behavioral validationlocal host is macOS arm64 and cannot execute the target ELF natively; Docker client is presentDocker daemon/platform image availability is not guaranteed and static validation may be sufficientIf needed, run a linux/amd64 container with the binary mounted and feed the derived passphraseMediumActive
1Recover passphrase by extracting Rust regex constraints and u128 character-product checksstrings and filter_input disassembly show nine regexes; check_input disassembly slices fixed ranges and compares multiply_characters outputs to seven constantsNeed reproduce the constraints in a solver and validate a candidate against all regexes/productsParse the regex array and product constants, enumerate small segment collisions, and select the meaningful flag phraseHighActive

Closed Branches

BranchEvidence TestedFailure OutputReason ClosedRevisit Condition

Technical analogy

How to remember this solve

Think of it like taking apart a small appliance on a workbench. You do not need every screw at once; you trace the control path and rebuild just enough logic to make it reveal the answer.

For Regas Town, 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.