Challenge / Forensics

RedTrails

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

MediumPublished 2024-07-11Sanitized local writeup

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.

RedTrails sanitized attack graph

Walkthrough flow

01

Reassemble TCP streams from the PCAP and identify...

02

Decode the fake PyPI HTTP payload by reversing and...

03

Extract one proof fragment from decoded persistence...

04

Parse Redis RESP replies and extract one proof...

05

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.

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.

  • 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.json records the original ZIP and extracted capture.pcap.
  • analysis/stream-summary.txt lists the reassembled TCP payload streams.
  • analysis/http-stage1-decoded.sh contains the decoded first-stage shell script.
  • analysis/authorized-key-command.txt contains the nested decoded authorized-key persistence command.
  • analysis/extracted-module-x10SPFHN.so is the rogue Redis module recovered from replication traffic.
  • analysis/system-exec-output-*.bin are decrypted module command outputs.
  • analysis/users-table.tsv contains the parsed users_table hash.

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:

  1. Parses and reassembles TCP payloads from capture.pcap.
  2. Decodes the reversed-base64 HTTP payload and nested authorized-key command.
  3. Parses Redis RESP replies to locate the users_table fragment.
  4. Extracts the Redis module from the rogue replication full-sync stream.
  5. Finds the module AES key and IV, decrypts system.exec replies, and extracts the environment fragment.
  6. 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>, and MODULE LOAD should 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

FileSizeSHA256TypeNotes
files/a12c738a-f7dc-41fe-8463-147b3ddf99a2.zip55807<hash redacted>Zip archive data, at least v2.0 to extract, compression method=deflatezip entries: 1 shown in artifact inventory JSON
files/extracted/capture.pcap291707<hash redacted>pcap capture file, microsecond ts (little-endian) - version 2.4 (Ethernet, capture length 262144)

Evidence Ledger

TimeActionOutput/FileFindingConfidenceNext
2026-06-12T21:54:47Zharness initchallenge-state.jsonWorkspace initialized with deterministic state fileHighInventory artifacts
2026-06-12T21:54:58Zartifact inventoryanalysis/artifact-inventory.json2 artifact(s) inventoriedHighBuild or update hypotheses
2026-06-12T21:58:24Zhypothesis recordedhypothesis-board.mdReconstruct 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.MediumBuild a local parser/decoder that extracts all three fragments from capture.pcap and writes a single HTB-format flag candidate.
2026-06-12T21:58:49Zresearch recordanalysis/research/research-records.mdResearch tagged MATCHEDMediumValidate against current evidence
2026-06-12T22:00:51Zflag captureloot/flag.txtHTB-format flag captured; raw value kept in loot onlyHighWrite solution and run completion gate
2026-06-12T22:01:51Zcompletion gatechallenge-state.jsonCompletion gate passed; state marked COMPLETEHighOptional sanitized memory summary approval

Key Findings

  • The pcap contains authenticated Redis traffic against <TARGET>:6379, including enumeration of users_table.
  • The first attacker path abuses Redis CONFIG SET dir/dbfilename, SET, and SAVE to 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_table hash 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.exec and 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.py reconstructs the flag from capture.pcap and writes the candidate to loot/flag-candidate.txt; the harness-captured flag is in loot/flag.txt.

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

  1. Reassemble TCP streams from the PCAP and identify Redis control traffic.
  2. Decode the fake PyPI HTTP payload by reversing and base64-decoding its embedded blob.
  3. Extract one flag fragment from decoded persistence content.
  4. Parse Redis RESP replies and extract one flag fragment from anomalous database content.
  5. Extract the malicious Redis module from rogue replication full-sync traffic.
  6. Recover the module's <secret redacted> key/IV constants and decrypt encrypted system.exec replies.
  7. 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, and SAVE commands 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

  • tshark was unavailable, so a small Python PCAP/TCP/RESP parser was used.
  • tcpdump was useful for initial triage but too noisy for Redis COMMAND DOCS; custom parsing gave cleaner evidence.

Evidence Paths

  • files/extracted/capture.pcap
  • analysis/stream-summary.txt
  • analysis/http-stage1-decoded.sh
  • analysis/authorized-key-command.txt
  • analysis/users-table.tsv
  • analysis/extracted-module-x10SPFHN.so
  • analysis/system-exec-output-*.bin
  • analysis/attack-summary.md
  • solve/solve.py
  • loot/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.

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

Closed Branches

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