$ cat writeup.md…
$ cat writeup.md…
hackthebox
I found a suspicious program on my computer making HTTP requests to a web server. Please review the provided traffic capture and executable file for analysis. (Note: Flag has two parts)
I found a suspicious program on my computer making HTTP requests to a web server. Please review the provided traffic capture and executable file for analysis. (Note: Flag has two parts)
Files provided:
smphost.exe — 67MB PE64 executable (.NET 8 self-contained)sustraffic.pcapng — Network capture (104 frames)Identified the binary and traffic characteristics:
file smphost.exe # PE32+ executable (console) x86-64, for MS Windows tshark -r sustraffic.pcapng -z io,phs # 104 frames, all TCP/HTTP between client and server at 10.142.0.3 # Pattern: alternating GET / and POST /submit_feedback (9 GET, 4 POST)
The 67MB size immediately suggests a .NET self-contained deployment (bundled runtime). The alternating GET/POST pattern suggests a polling-based C2 protocol.
The executable is a .NET 8 self-contained single-file deployment. The embedded application DLL MyProject.dll (15,872 bytes) was found at offset 0x937000 in the binary, namespace MyNamespace.Program.
Usage: smphost.exe <IPAddress> <Port>
Decompilation revealed a C2 (Command & Control) reverse shell agent that communicates over HTTP disguised as a feedback form. The protocol has two encoding layers:
The C2 server returns HTML pages where each HTML tag maps to a hex nibble. The sequence of tags forms a hex string that decodes to a shell command.
HTML Tag → Hex Nibble Mapping:
| Tag | Hex | Tag | Hex | Tag | Hex | Tag | Hex |
|---|---|---|---|---|---|---|---|
| cite | 0 | img | 4 | div | 8 | nav | c |
| h1 | 1 | ul | 5 | span | 9 | b | d |
| p | 2 | ol | 6 | label | a | i | e |
| a | 3 | button | 7 | blockquote | f | li | skip |
Decoding process: Parse HTML → extract tag names → map each to hex nibble → concatenate → hex decode to ASCII = shell command.
+, =) are kept as-isfeedback in a POST to /submit_feedback with Name=Test UserDecoding process: Split feedback by spaces → take first character of each token → reconstruct Base64 string → Base64 decode.
whoamiCommand: whoami
Output: windows-instanc\pakcyberbot
systeminfoCommand: systeminfo
Output: Windows Server 2016 Datacenter on Google Compute Engine
dir && type file ← FLAG HEREThe command decoded from HTML tags in frame 60:
dir && cd \Users\pakcyberbot\Documents\ && type HTB{Th4ts_d07n37_
Flag Part 1 is embedded directly in the command: HTB{Th4ts_d07n37_
The POST output from frame 67 (Base64 decoded from word encoding) contains directory listing plus:
'h77P_s73417hy_revSHELL}'
Flag Part 2: h77P_s73417hy_revSHELL}
Command: dir && cd \Users\pakcyberbot && echo 'you are hacked' > notes.txt
Output: directory listing
#!/usr/bin/env python3 """Decode C2 commands from HTML tag encoding in HTTP responses.""" import re tag_map = { 'cite': '0', 'h1': '1', 'p': '2', 'a': '3', 'img': '4', 'ul': '5', 'ol': '6', 'button': '7', 'div': '8', 'span': '9', 'label': 'a', 'textarea': 'b', 'nav': 'c', 'b': 'd', 'i': 'e', 'blockquote': 'f' } # Extract opening tags from HTML response body html_body = "..." # from tshark -T fields -e http.file_data tags = re.findall(r'<(\w+)', html_body) # Filter out 'li' (skip marker) and map to hex nibbles hex_nibbles = [tag_map[t] for t in tags if t in tag_map] hex_string = ''.join(hex_nibbles) # Decode hex to ASCII command = bytes.fromhex(hex_string).decode('utf-8') print(f"Command: {command}")
#!/usr/bin/env python3 """Decode C2 output from word-based Base64 encoding in POST feedback.""" import base64 # Extract feedback field from POST body feedback = "..." # from tshark -T fields -e urlencoded-form.value # Each word's first character = original Base64 character words = feedback.split() b64_chars = [w[0] for w in words] b64_str = ''.join(b64_chars) # Decode Base64 to get original command output decoded = base64.b64decode(b64_str).decode('utf-8') print(f"Output: {decoded}")
#!/usr/bin/env python3 """ Complete decoder for Fishy HTTP C2 protocol. Extracts commands from GET responses and outputs from POST requests. """ import re import base64 import subprocess pcap = "sustraffic.pcapng" # Extract HTTP responses (commands) responses = subprocess.run( ["tshark", "-r", pcap, "-Y", "http.response and http.content_type contains html", "-T", "fields", "-e", "frame.number", "-e", "http.file_data"], capture_output=True, text=True ).stdout.strip().split('\n') # Extract POST data (outputs) posts = subprocess.run( ["tshark", "-r", pcap, "-Y", "http.request.method == POST", "-T", "fields", "-e", "frame.number", "-e", "urlencoded-form.value"], capture_output=True, text=True ).stdout.strip().split('\n') tag_map = { 'cite': '0', 'h1': '1', 'p': '2', 'a': '3', 'img': '4', 'ul': '5', 'ol': '6', 'button': '7', 'div': '8', 'span': '9', 'label': 'a', 'textarea': 'b', 'nav': 'c', 'b': 'd', 'i': 'e', 'blockquote': 'f' } def decode_command(html): tags = re.findall(r'<(\w+)', html) nibbles = [tag_map[t] for t in tags if t in tag_map] return bytes.fromhex(''.join(nibbles)).decode('utf-8', errors='replace') def decode_output(feedback): words = feedback.split() b64 = ''.join(w[0] for w in words) return base64.b64decode(b64).decode('utf-8', errors='replace') # Decode and print all exchanges for resp in responses: parts = resp.split('\t', 1) if len(parts) == 2: frame, html = parts cmd = decode_command(html) if cmd.strip(): print(f"[Frame {frame}] Command: {cmd}") for post in posts: parts = post.split('\t', 1) if len(parts) == 2: frame, data = parts # Second field is the feedback value fields = data.split('\t') if len(fields) >= 2: output = decode_output(fields[1]) print(f"[Frame {frame}] Output: {output[:200]}...")
Use this technique when you see:
| Technique | Description |
|---|---|
| HTML Tag Encoding | Each HTML tag name maps to a hex nibble; sequence of tags encodes shell commands |
| Word-Based Base64 Encoding | Base64 characters replaced by random words starting with the same letter |
| C2 Traffic Analysis | Identifying command-and-control patterns in HTTP traffic |
| .NET Decompilation | Extracting and decompiling embedded DLLs from self-contained .NET executables |
| Protocol Reverse Engineering | Understanding custom encoding schemes by analyzing both binary and traffic |
MyProject.dll to understand the C2 protocol$ cat /etc/motd
Liked this one?
Pro unlocks every writeup, every flag, and API access. $9/mo.
$ cat pricing.md$ grep --similar