RedTrails
RedTrails is a sanitized challenge note from the local HTB archive, organized for quick review by category, difficulty, evidence flow, and reusable operator
Scenario
RedTrails attack path
RedTrails 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 Forensics evidence, validation, and reusable operator lessons.
Walkthrough flow
Reassemble TCP streams from the PCAP and identify...
Decode the fake PyPI HTTP payload by reversing and...
Extract one proof fragment from decoded persistence...
Parse Redis RESP replies and extract one proof...
Extract the malicious Redis module from rogue...
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.
- Forensics/RedTrails/writeup.md
- htb-challenge/Forensics/RedTrails/notes.md
- htb-challenge/Forensics/RedTrails/memory-summary.md
- htb-challenge/Forensics/RedTrails/hypothesis-board.md
Technical Walkthrough
Writeup
Challenge
- Name: RedTrails
- Category: Forensics
- Difficulty: Medium
- Mode: file
Summary
The capture shows a Redis compromise in three stages. First, an authenticated client writes cron persistence by abusing Redis configuration and database save behavior. That cron fetches an obfuscated shell script, which contains one flag fragment. Second, Redis data enumeration exposes another fragment in a suspicious users_table field. Third, the attacker uses rogue Redis replication to load a malicious module that exposes system.exec; decrypting its encrypted command output reveals the final fragment.
Artifact Inventory
analysis/artifact-inventory.jsonrecords the original ZIP and extractedcapture.pcap.analysis/stream-summary.txtlists the reassembled TCP payload streams.analysis/http-stage1-decoded.shcontains the decoded first-stage shell script.analysis/authorized-key-command.txtcontains the nested decoded authorized-key persistence command.analysis/extracted-module-x10SPFHN.sois the rogue Redis module recovered from replication traffic.analysis/system-exec-output-*.binare decrypted module command outputs.analysis/users-table.tsvcontains the parsedusers_tablehash.
Analysis
The pcap begins with a successful Redis AUTH, followed by COMMAND DOCS, INFO, KEYS *, TYPE users_table, and HGETALL users_table. The attacker then changes Redis persistence settings to /var/spool/cron and root, writes cron-formatted values, and calls SAVE. This is the classic Redis write-to-cron persistence technique.
The cron payload causes the Redis host to fetch /packages/VgLy8V0Zxo from files.pypi-install.com. The HTTP body is a shell script that reconstructs and executes echo '<blob>' | rev | base64 -d. The decoded script drops update-motd and SSH authorized-key persistence. The authorized-key command embeds the first flag fragment.
The users_table response contains usernames, password hashes, and email fields. One email field is replaced with a <secret redacted> marker, giving the second fragment.
The later Redis traffic uses SLAVEOF, changes dbfilename to x10SPFHN.so, and loads the resulting Redis module. The module binary is recovered from the full synchronization stream. It imports OpenSSL EVP AES functions, registers system.exec, and includes a 32-byte key plus 16-byte IV. Decrypting the system.exec bulk replies with <secret redacted> reveals command output, including an environment dump with the final fragment.
Solve
The reproducible solver is solve/solve.py.
It:
- Parses and reassembles TCP payloads from
capture.pcap. - Decodes the reversed-base64 HTTP payload and nested authorized-key command.
- Parses Redis RESP replies to locate the
users_tablefragment. - Extracts the Redis module from the rogue replication full-sync stream.
- Finds the module AES key and IV, decrypts
system.execreplies, and extracts the environment fragment. - Concatenates the three fragments and writes the final candidate to
loot/flag-candidate.txt.
The final candidate was captured with challenge_harness.py capture-flag into loot/flag.txt.
Flag
Raw flag is stored in loot/flag.txt and intentionally not reproduced here.
Lessons
- Redis authentication alone is not sufficient when credentials can be exposed or guessed; bind restrictions, network ACLs, and command ACLs matter.
- Dangerous Redis commands such as
CONFIG,SAVE,SLAVEOF/<secret redacted>, andMODULE LOADshould be disabled or tightly restricted in exposed environments. - Rogue replication can be used to write attacker-controlled module files to disk, then load them for command execution.
- Captured malicious modules may encrypt their output; embedded constants and dynamic imports can reveal the decryption path.
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: RedTrails
- Category: Forensics
- Difficulty: Medium
- Mode: file
- Remote instance: none
- Start time: 2026-06-12T21:54: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
| File | Size | SHA256 | Type | Notes |
|---|---|---|---|---|
files/a12c738a-f7dc-41fe-8463-147b3ddf99a2.zip | 55807 | <hash redacted> | Zip archive data, at least v2.0 to extract, compression method=deflate | zip entries: 1 shown in artifact inventory JSON |
files/extracted/capture.pcap | 291707 | <hash redacted> | pcap capture file, microsecond ts (little-endian) - version 2.4 (Ethernet, capture length 262144) |
Evidence Ledger
| Time | Action | Output/File | Finding | Confidence | Next |
|---|---|---|---|---|---|
| 2026-06-12T21:54:47Z | harness init | challenge-state.json | Workspace initialized with deterministic state file | High | Inventory artifacts |
| 2026-06-12T21:54:58Z | artifact inventory | analysis/artifact-inventory.json | 2 artifact(s) inventoried | High | Build or update hypotheses |
| 2026-06-12T21:58:24Z | hypothesis recorded | hypothesis-board.md | Reconstruct the Redis intrusion chain from the pcap: parse Redis RESP traffic, decode the first HTTP payload, extract the rogue Redis module and decrypt system.exec replies, then assemble the three flag fragments from persistence artifacts and database content. | Medium | Build a local parser/decoder that extracts all three fragments from capture.pcap and writes a single HTB-format flag candidate. |
| 2026-06-12T21:58:49Z | research record | analysis/research/research-records.md | Research tagged MATCHED | Medium | Validate against current evidence |
| 2026-06-12T22:00:51Z | flag capture | loot/flag.txt | HTB-format flag captured; raw value kept in loot only | High | Write solution and run completion gate |
| 2026-06-12T22:01:51Z | completion gate | challenge-state.json | Completion gate passed; state marked COMPLETE | High | Optional sanitized memory summary approval |
Key Findings
- The pcap contains authenticated Redis traffic against
<TARGET>:6379, including enumeration ofusers_table. - The first attacker path abuses Redis
CONFIG SET dir/dbfilename,SET, andSAVEto write cron persistence that downloads a shell script from a fake PyPI domain. - The HTTP payload is obfuscated as reversed base64. Decoding it reveals update-motd persistence plus SSH authorized-key persistence. One flag fragment is embedded in that persistence content.
- The Redis
users_tablehash contains another flag fragment in a field that should normally hold an email value. - A later phase uses rogue Redis replication to write and load a malicious module named
x10SPFHN.so. - The module registers
system.execand encrypts command output with <secret redacted>. Its embedded key/IV decrypt the returned bulk strings. One decrypted environment dump contains the final fragment. solve/solve.pyreconstructs the flag fromcapture.pcapand writes the candidate toloot/flag-candidate.txt; the harness-captured flag is inloot/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: Forensics
- Challenge: RedTrails
- 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.
- Reassemble TCP streams from the PCAP and identify Redis control traffic.
- Decode the fake PyPI HTTP payload by reversing and base64-decoding its embedded blob.
- Extract one flag fragment from decoded persistence content.
- Parse Redis RESP replies and extract one flag fragment from anomalous database content.
- Extract the malicious Redis module from rogue replication full-sync traffic.
- Recover the module's <secret redacted> key/IV constants and decrypt encrypted
system.execreplies. - Extract the final fragment from decrypted command output and assemble the flag.
Reusable Lessons
- Redis cron-write persistence can be reconstructed from
CONFIG SET dir,CONFIG SET dbfilename,SET, andSAVEcommands in packet captures. - Rogue Redis replication can transfer an ELF module inside the synchronization stream; the payload can be carved by RESP bulk length.
- Module command output may be encrypted; inspect imports and embedded constants before assuming the output is opaque.
- For multi-part flags, preserve chronology and source context before concatenating fragments.
Dead Ends
- No need for external writeups or RAG; all evidence is in the PCAP.
- TLS traffic to the fake PyPI host was not needed because the Redis module command output contained the final required fragment after decryption.
Tool Quirks
tsharkwas unavailable, so a small Python PCAP/TCP/RESP parser was used.tcpdumpwas useful for initial triage but too noisy for RedisCOMMAND DOCS; custom parsing gave cleaner evidence.
Evidence Paths
files/extracted/capture.pcapanalysis/stream-summary.txtanalysis/http-stage1-decoded.shanalysis/authorized-key-command.txtanalysis/users-table.tsvanalysis/extracted-module-x10SPFHN.soanalysis/system-exec-output-*.binanalysis/attack-summary.mdsolve/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 | Reconstruct the Redis intrusion chain from the pcap: parse Redis RESP traffic, decode the first HTTP payload, extract the rogue Redis module and decrypt system.exec replies, then assemble the three flag fragments from persistence artifacts and database content. | capture.pcap contains Redis AUTH/control traffic, an HTTP payload from files.pypi-install.com, Redis rogue replication/module load traffic, encrypted system.exec replies, and users_table data with a <secret redacted> field. | Build a local parser/decoder that extracts all three fragments from capture.pcap and writes a single HTB-format flag candidate. | Medium | Active |
Closed Branches
| Branch | Evidence Tested | Failure Output | Reason Closed | Revisit Condition |
|---|
Technical analogy
How to remember this solve
Think of the challenge as a small system with one rule that matters more than the rest. The solve is finding that rule, validating it, and using it carefully enough to reach the final proof.
For RedTrails, 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.