tagrawla

Challenge Description

There’s talk of an uprising. Blades are sharpened, armors fortified. Intercept the hidden message and uncover the secret operation.

Provided Files

tagrawla.pcapng

Solution

This challenge is based on DNS-based data exfiltration—specifically, how data can be encoded into DNS queries and stealthily transmitted.

Step 1: Open the Capture

Opening the tagrawla.pcapng file in Wireshark immediately shows a large number of DNS packets.

dns

To filter DNS traffic, we can use the Wireshark display filter dns. This reveals a number of normal dns messages to google, cloudfare… and, to a domain name, zenata.com, that suspeciously, never returns a valid response. Upon inspection the first part of each request (e.g., 343536) varies between packets and is suspiciously hex-like in format.

Step 2: Spot the Pattern

It becomes clear that these subdomains consistently follow the format:

<hex_string>.zenata.com

This is a common exfiltration technique where the attacker encodes data into the subdomain labels of DNS queries. Since the domain name system is hierarchical and distributed, DNS traffic can often pass through unnoticed in many environments, making it a viable covert channel.

Step 3: Extract and Decode

We now want to extract the unique hexadecimal subdomain prefixes and reconstruct the exfiltrated payload. Sorting and deduplicating helps avoid noise from repeated packets.

To test whether it’s meaningful, we decode the first label as a hexadecimal string:

hex: 53656375 ASCII: Secu

This is promising—it matches the beginning of the flag format Securinets{…}.

So, the idea is to:

This can be scripted with pyshark as shown below.

Solution Script

import pyshark
import sys

def extract_unique_hex_labels(pcap_file):
    try:
        capture = pyshark.FileCapture(pcap_file, display_filter='dns')
    except Exception as e:
        print(f"[!] Could not open file: {e}")
        return ""

    seen = set()
    hex_fragments = []

    for packet in capture:
        try:
            if 'DNS' in packet and hasattr(packet.dns, 'qry_name'):
                qname = packet.dns.qry_name.lower()
                if qname.endswith('.zenata.com'):
                    first_label = qname.split('.')[0]
                    if first_label not in seen:
                        seen.add(first_label)
                        hex_fragments.append(first_label)
        except AttributeError:
            continue

    capture.close()
    return ''.join(hex_fragments)

def decode_hex_payload(hex_payload):
    try:
        return bytes.fromhex(hex_payload).decode('ascii')
    except Exception as e:
        return f"[!] Decode error: {e}"

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: python solver.py <file.pcapng>")
        sys.exit(1)

    file_path = sys.argv[1]
    print(f"[+] Processing: {file_path}")

    hex_data = extract_unique_hex_labels(file_path)
    print(f"[+] Extracted hex (unique): {hex_data}")

    decoded = decode_hex_payload(hex_data)
    print(f"[+] Decoded ASCII: {decoded}")

Running the script on the provided capture file yields:

python .\solver.py .\taskfiles\tagrawla.pcapng
[+] Processing: .\taskfiles\tagrawla.pcapng
[+] Extracted hex (unique): 5365637572696e6574737b74726962655f6f665f626c616465735f7368616c6c5f726973657d
[+] Decoded ASCII: Securinets{tribe_of_blades_shall_rise}