Posted onInctfViews: Word count in article: 846Reading time ≈3 mins.
We are working on our own custom command and control protocol. Can
you identify any hidden features in the service? We also included a
packet capture of some old sessions so you can learn how it works.
The first step was to examine the provided packet capture
(custom_protocol_log.pcap) to understand the communication
pattern. I used scapy to extract and decode raw data from
the TCP streams.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
#!/usr/bin/env python3 from scapy.allimport * from scapy.layers.inet import TCP
PCAP_FILE = "custom_protocol_log.pcap"
defprint_hex(pcap_path): packets = rdpcap(pcap_path) for pkt in packets: if TCP in pkt and pkt.haslayer(Raw): raw = pkt[Raw].load try: # Attempt to decode or print as hex print(raw.hex()) except Exception as e: print(f"[-] Error: {e}")
if __name__ == "__main__": print_hex(PCAP_FILE)
Protocol Reversal
By analyzing the hex data from the traffic between
172.17.0.1 and 172.17.0.2, a clear pattern
emerged:
The script enumerates the 15 single-byte command values
0x30..0x3e, corresponding to ASCII
0..9:;<=>. Encoding decimal strings
10..14 would produce different multi-byte fields and is not
supported by the retained trace. CRC32 matches all three displayed
request fixtures offline; the PCAP and remote command semantics have not
been rerun.
[*] Starting brute-force with commands: ['30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '3a', '3b', '3c', '3d', '3e'] [+] Opening connection to 35f9359cc67c7983.247ctf.com on port 50385: Done [*] Session ID: 9b2832a1 [+] Receiving all data: Done (54B) [*] Closed connection to 35f9359cc67c7983.247ctf.com port 50385 [*] Response: (2\x001\x00notroot \x003738085711 ---------------------------------------- [*] Connection closed. [+] Opening connection to 35f9359cc67c7983.247ctf.com on port 50385: Done [*] Session ID: 3907e672 [+] Receiving all data: Done (152B) [*] Closed connection to 35f9359cc67c7983.247ctf.com port 50385 [*] Response: 9\x07r\x001\x00uid=1000(notroot) gid=1000(notroot) groups=1000(notroot) \x003051696603 ---------------------------------------- [*] Connection closed. [+] Opening connection to 35f9359cc67c7983.247ctf.com on port 50385: Done [*] Session ID: edd0a465 [+] Receiving all data: Done (96B) [*] Closed connection to 35f9359cc67c7983.247ctf.com port 50385 [*] Response: Фe\x001\x00Sun Mar 1 06:57:51 UTC 2026 \x003480231763 ---------------------------------------- [*] Connection closed. [+] Opening connection to 35f9359cc67c7983.247ctf.com on port 50385: Done [*] Session ID: 705136bc [+] Receiving all data: Done (446B) [*] Closed connection to 35f9359cc67c7983.247ctf.com port 50385 [*] Response: pQ6\x001\x00 total used free shared buff/cache available Mem: 7973384 1587756 3913000 2636 2472628 6135804 Swap: 2097148 0 2097148 \x002165499562 ---------------------------------------- [*] Connection closed. [+] Opening connection to 35f9359cc67c7983.247ctf.com on port 50385: Done [*] Session ID: d0f8fe01 [+] Receiving all data: Done (118B) [*] Closed connection to 35f9359cc67c7983.247ctf.com port 50385 [*] Response: \x01\x001\x00247CTF{<flag-redacted>}\x001655731160 [+] Flag found: \x01\x001\x00247CTF{<flag-redacted>}\x001655731160 [*] Connection closed.
[Process exited 0]
The returned flag belongs to the launched service instance; no
cross-instance invariance is established. Record the
generation/retrieval method and use the current instance response
instead of a fixed-answer spoiler.