Home > Writeups > Raptor Weekly 2 - ECHELON Network 1 - 2.1 ; INTERCEPT

Raptor Weekly 2 - ECHELON Network 1 - 2.1 ; INTERCEPT

Parsing a raw HTTP traffic capture to identify an authenticated session, replaying a stolen token against a restricted endpoint, and reading every response header carefully enough to find a value that won't make sense until Tier 4.

2.1 ; INTERCEPT

Challenge Description

ECHELON internal API traffic captured on 2026-03-14. Something authenticated. Something else used that authentication. Reconstruct the session.

Files provided: intercept.pcap


Overview

The PCAP contains HTTP traffic on port 8080 across two source IPs. A legitimate analyst authenticates and receives a session token. A second IP then replays that token against a different endpoint. The session token is JWT_PT1, the first half of the JWT secret needed in 2.3 ; SIGNED.

A response header in the replay exchange contains a value that is not relevant to this challenge but will matter in Tier 4. Note it and move on.


Step 1: Survey the Traffic

Open in Wireshark and filter tcp.port == 8080. Two source IPs appear: 10.7.0.44 (legitimate analyst) and 10.7.0.92 (anomalous).

Follow the TCP stream from 10.7.0.44. The first exchange is a POST to /api/v1/auth. Extract TCP payloads programmatically:

import struct

def parse_pcap(path):
    with open(path, "rb") as f:
        f.read(24)
        packets = []
        while True:
            hdr = f.read(16)
            if len(hdr) < 16: break
            ts_s, ts_us, inc_len, _ = struct.unpack("<IIII", hdr)
            data = f.read(inc_len)
            if len(data) < 54: continue
            ip_ihl   = (data[14] & 0x0f) * 4
            tcp_off  = 14 + ip_ihl
            tcp_doff = (data[tcp_off + 12] >> 4) * 4
            src_ip   = ".".join(str(b) for b in data[26:30])
            payload  = data[tcp_off + tcp_doff:]
            if payload:
                packets.append((ts_s + ts_us/1e6, src_ip, payload))
    return packets

Step 2: Extract the Session Token

The server response to the POST /api/v1/auth is a JSON body:

import json

for ts, src_ip, payload in packets:
    text = payload.decode("utf-8", errors="replace")
    if "session_token" in text:
        body = text.split("\r\n\r\n", 1)[1]
        data = json.loads(body)
        print(data["session_token"])
        # 656368656c6f6e2e6e6f646530372e73
        print(data["flag"])
        # ECHELON{s3ssions_leave_gh0sts}

The session token is a 32-character hex string, this is JWT_PT1. The flag is also present in the auth response body as the flag field.


Step 3: Read Every Response Header

Before moving to the replay, read the full server response to the auth POST. Beyond the JSON body, it contains:

X-Request-ID: 4a9c2f81

This value is not needed for this challenge. It becomes the decryption key in 2.2 ; DEAD DROP. Record it now.

Step 4: Identify the Replay

The second source IP 10.7.0.92 connects shortly after and issues a GET to /api/v1/node/07/config using the same X-Session-Token value. This is a session replay, the token was captured and reused from a different host.

The server response to the replay contains a header:

X-Session-Trace: f1e2d3c4b5a69788

This value is not relevant to the current challenge either. It surfaces again in Tier 4. Record it.


Key Takeaways

Session tokens transmitted in cleartext over internal networks are as exposed as credentials. Any attacker with network visibility can capture and replay them without needing to break any cryptography. The X-Session-Trace header in the server response shows that the server logged the replay attempt, but by then the damage was already done.


Flag

ECHELON{s3ssions_leave_gh0sts}

< Back to All Writeups