Packed Light — TryHackMe Challenge Writeup
Initial Inspection
We start by analyzing the provided packet capture file, traffic.pcapng, using Wireshark or tshark to understand the network activity and identify any suspicious communications.
::Protocol Hierarchy & HTTP Activity
Checking the protocol hierarchy reveals a small amount of HTTP traffic amidst background network chatter:
Filtering specifically for HTTP request methods and target URIs reveals an interesting interaction between the local machine (192.168.1.141) and an external server (34.41.103.191 / byte-lotus-hotel.thm:8080):
Output:
Key Observation: The victim machine initially fetches a Python script (/temp/updates.py) in
packet 16, followed immediately by 30 periodic GET requests to /. This pattern strongly suggests
a Command and Control (C2) agent staging an initial payload and subsequently exfiltrating data.
Extracting the C2 Payload
::Inspecting Packet 19
Packet 19 contains the HTTP 200 OK response from byte-lotus-hotel.thm:8080 for /temp/updates.py. We can dump the HTTP response body using tshark:
The response payload is sent as plaintext Python code in the HTTP response:
Reverse Engineering the Keylogger
Analyzing updates.py reveals how the keystrokes are captured, encrypted, and exfiltrated:
- ▹Keystroke Hooking: Uses
pynput.keyboard.Listenerto intercept every key pressed by the user. - ▹Encryption Key: The function
getkey()concatenates two strings to form the XOR key:"H0t3lSt@ff0NlyK3epS3cr3t!". - ▹Data Exfiltration: Each character is passed to
sendltr(), encrypted viaxor(), base64-encoded, and sent via an HTTP GET request inside theCookie: hotel_sess_state=<base64>header.
The Encryption Quirk (Cryptanalysis): Look closely at xor(data, key) when called from
sendltr(character). Because sendltr() encrypts keystrokes one character at a time, the
length of data is always 1. Consequently, i in enumerate(data) is always 0. This means
every single keystroke is XORed against only the first character of the key, which is 'H'
(ord('H') = 0x48).
Reconstructing the Keystroke Stream
::
We can list all hotel_sess_state cookie values from the 30 subsequent HTTP GET requests in the packet capture:
Output:
::Writing the Decryption Script
We write a quick Python snippet to base64-decode each cookie and XOR the resulting byte with 0x48 ('H'):
Execution Output:
Flag Capture
Automation
This entire challenge — from parsing the PCAPNG file to extracting the C2 staging payload, cryptanalyzing the XOR keylogger, and decrypting the exfiltrated keystrokes — can be fully automated. Instead of running each step manually, here's an interactive demo of the standalone Python solver script in action:
Standalone Solver Script: View or download the complete automated Python exploit script
thm_packed_light_solve.py
in our /autosolve directory.
References

Red Team Consultant · Penetration Tester · Bug Bounty Hunter
Offensive security professional with 250+ vulnerabilities reported across 50+ organizations including Atlassian, Vimeo, and AT&T. Sharing research, tools, and field notes.