Format: Step-by-step reproduction with commands and evidence snippets.
Note: This document presents an investigative workflow that extracts all seven required flags from the supplied capture.pcap.
Overview
This capture contains HTTP traffic interacting with a LangFlow instance hosted at ai.watchtower.htb:7860. The attacker abuses an unauthenticated code-validation endpoint to submit compressed-and-encoded Python code which is executed server-side. The executed payload runs commands (whoami, id, env) and injects a reverse shell line into a user shell file. Environment variables in responses reveal the Postgres connection string and the host name.
This writeup walks through extracting all of that information from capture.pcap with common forensic tools and lightweight text processing.
Files used
capture.pcap— the pcap provided for the challenge.
Place capture.pcap in your working directory.
Workflow (step-by-step)
All commands assume a Unix-like shell. Adjust paths/names as needed.
1) Inspect the pcap file type and size
file capture.pcap
ls -lh capture.pcap
You should see pcap capture file and file size ~30 KB (depends on the provided capture).
2) Extract readable ASCII blocks quickly
When Wireshark/tshark is not available, strings is a fast way to extract the HTTP payloads:
strings -n 6 capture.pcap > pcap.strings.txt
less pcap.strings.txt
Look for GET/POST lines and /api/v1 strings.
3) Find requests to the suspicious endpoint
Search for occurrences of /api/v1/validate/code:
grep -n "/api/v1/validate/code" -n pcap.strings.txt || grep -n "/api/v1" pcap.strings.txt
You will see several POST entries that look like:
POST /api/v1/validate/code HTTP/1.1
Host: ai.watchtower.htb:7860
...
{"code": "....base64/zlib-ish payload...."}
These payloads are the attacker-supplied code.
4) Extract JSON payloads into separate files for analysis
We can extract the JSON {"code": "..."} blocks using awk/sed/perl. Example using perl:
perl -0777 -ne 'while(/(\{"code":\s*".*?"\})/sg){print "$1
";}' pcap.strings.txt > extracted_code_blocks.json
less extracted_code_blocks.json
You should get 2–4 JSON snippets containing an encoded code string.
5) Identify base64-like blobs inside the code value
The code value typically contains a Python expression that calls zlib.decompress on a base64-decoded blob. Extract long base64-like strings (40+ chars) with grep/pcregrep:
grep -oE '[A-Za-z0-9+/=]{40,}' extracted_code_blocks.json > possible_b64.txt
less possible_b64.txt
Review the candidates — we want to base64-decode then zlib-decompress them.

