Skip to content

SRF H9SDB_sess_decoded

“samuele edited this page Apr 7, 2026 · 1 revision

SRF-H9SDB -- SSRF via Download Endpoint and XML-RPC

Session Decoded: How the Agent Exploited XML-RPC SSRF to Map Internal Network Topology


The Prompt

Target port 80 and port 9090. Find endpoints on port 80 that fetch URLs
server-side. On port 9090, explore the XML-RPC service for methods
that accept URL arguments. Test for SSRF with internal URLs. Map the internal network topology.

Two attack surfaces, zero credentials, zero knowledge of the XML-RPC methods. The agent must enumerate the RPC interface, discover SSRF-capable methods, confirm server-side fetching, then use it as a proxy to scan and map the entire internal network -- services hidden behind the firewall, Docker containers, and all.


What Happened: The Full Attack Chain

Phase 1 -- Reconnaissance and Planning (6:42 - 6:44 PM)

The agent opened with a Deep Think strategy session, formulating a 10-step plan: enumerate endpoints on port 80, call system.listMethods on port 9090, fuzz for URL-accepting parameters, confirm SSRF, then use the vector to probe localhost ports, Docker networks, and private IP ranges.

Graph query returned existing recon data on gpigs.devergolabs.com (15.160.68.117):

  • Port 21: FTP (vsftpd 2.3.4)
  • Port 22: SSH (OpenSSH 9.6p1)
  • Port 80: nginx 1.29.7
  • Port 3306: MySQL 8.4.8
  • Port 4000: Unknown query API
  • Port 8080: Apache Tomcat 8.5.19
  • Ports 8888 and 9090 were not yet in the graph

Phase 2 -- Parallel Service Enumeration (6:44 PM)

The agent fired 4 parallel probes:

Target Result
GET / on port 80 Static HTML landing page -- "RedAmon HackLab Research Target"
GET / on port 9090 404 Not Found (root path not served)
system.listMethods on port 9090 /RPC2 3 methods: system.listMethods, dvws.CheckUptime, pingback.ping
Naabu port scan for 9090, 8888 Both ports OPEN -- port 8888 newly discovered

The XML-RPC method dvws.CheckUptime immediately stood out -- an uptime checker that takes a URL is a textbook SSRF vector. pingback.ping is another classic, but needed testing.

A parallel ffuf directory scan on port 80 found: css, index.html, js, legal, static, uploads -- a static site with no URL-fetching endpoints.


Phase 3 -- Method Testing and Case-Sensitivity Discovery (6:44 - 6:45 PM)

The agent tested all three RPC methods in parallel:

Method Payload Result
dvws.rpcversion (lowercase) -- No response
dvws.checkuptime (lowercase) http://example.com No response
pingback.ping http://example.com, http://example.org "Method Disabled"

Critical pivot: The agent realized the methods are case-sensitive. checkuptime failed but the system.listMethods response showed CheckUptime with capital C and U.


Phase 4 -- SSRF Confirmed (6:45 PM)

POST /RPC2 HTTP/1.1
Host: gpigs.devergolabs.com:9090

<?xml version="1.0"?>
<methodCall>
  <methodName>dvws.CheckUptime</methodName>
  <params>
    <param><value><string>http://example.com</string></value></param>
  </params>
</methodCall>

SSRF confirmed. The server returned a raw Needle socket/stream response object showing it had made an outgoing HTTP request:

GET / HTTP/1.1
host: example.com
user-agent: Needle/3.3.1 (Node.js v22.22.2; linux x64)

The server fetches any arbitrary URL using the Needle HTTP client. The response includes connection metadata (socket info, request headers) rather than parsed HTTP response bodies -- useful for confirming connectivity but limiting data extraction.


Phase 5 -- Protocol Testing (6:46 PM)

The agent tested alternative URL schemes to expand the attack surface:

Scheme Target Result
file:///etc/passwd Local filesystem Needle converted file:// to an HTTP request to host "file" -- not supported
dict://127.0.0.1:27017/info MongoDB via dict protocol Not supported
gopher:// Protocol smuggling Not supported
http://169.254.169.254/latest/meta-data/ AWS instance metadata No response -- unreachable

Conclusion: Only http:// and https:// work through this SSRF. The Needle HTTP client does not support raw socket protocols. AWS metadata service is not accessible (either IMDSv2 enforced or not running on AWS metadata network).


Phase 6 -- Internal Port Scanning via SSRF (6:47 - 6:48 PM)

The agent used the SSRF as a port scanner, sending requests to localhost on common service ports:

Internal Target Result
127.0.0.1:6379 (Redis) No response -- not running
127.0.0.1:5432 (PostgreSQL) No response -- not running
127.0.0.1:11211 (Memcached) No response -- not running
127.0.0.1:3306 (MySQL) No response -- binary protocol, HTTP incompatible
127.0.0.1:27017 (MongoDB) Connected -- MongoDB running internally
127.0.0.1:28017 (MongoDB HTTP) Connected -- legacy HTTP REST interface
127.0.0.1:28017/serverStatus Connected -- server status endpoint accessible

Discovery: MongoDB is running on localhost but not exposed externally. Its legacy HTTP REST interface on port 28017 is also accessible.


Phase 7 -- Docker Network Mapping (6:48 - 6:50 PM)

The agent systematically probed private IP ranges to find the container network:

Target Result
10.0.0.1 No response
192.168.1.1 No response
172.17.0.1 (Docker bridge gateway) Connected -- Docker host gateway confirmed
172.17.0.2 Connected -- live container
172.17.0.3 through 172.17.0.6 No response -- no other containers

Then it enumerated services on the discovered hosts:

Target Result
172.17.0.1:2375 (Docker API, unencrypted) No response -- not listening
172.17.0.1:2376 (Docker API, TLS) TCP connected -- Docker daemon reachable
172.17.0.2:80 Connected -- HTTP service on the container
172.17.0.2:9090, :27017, :8080, :4000, :8888, :3000 All no response

Key finding: The Docker API daemon is listening on 172.17.0.1:2376 but requires TLS client certificates. The Needle HTTP client cannot complete the TLS handshake with self-signed certs, blocking exploitation. Only two hosts exist on the Docker bridge: the gateway (.1) and one container (.2) running HTTP on port 80.


Phase 8 -- Spring Boot Access Control Bypass (6:53 - 6:55 PM)

The agent discovered that Spring Boot on port 8888 has different behavior when accessed internally vs externally:

Endpoint External (direct curl) Internal (via SSRF to 127.0.0.1:8888)
/env 404 Not Found Connected -- accessible
/health 404 Not Found Connected -- accessible
/configprops 404 Not Found Connected -- accessible
/actuator 404 No response
/actuator/env -- No response
/beans -- No response
/mappings -- No response

Access control bypass confirmed. The Spring Boot actuator endpoints (/env, /health, /configprops) are bound to localhost only -- they return 404 when hit from the internet but respond when accessed via SSRF on 127.0.0.1. This means credentials, environment variables, and configuration properties stored in Spring Boot are accessible through the SSRF chain.


Phase 9 -- Tomcat Manager Discovery (6:55 PM)

Final probe:

Target Result
127.0.0.1:8080/manager/html Connected -- Tomcat Manager accessible via SSRF

The Tomcat Manager web interface is reachable through the SSRF. If default or weak credentials exist, this could be chained into WAR file deployment for remote code execution -- turning an SSRF into full RCE.


Final Network Topology

Internet
    |
    v
gpigs.devergolabs.com (15.160.68.117)
    |
    |-- Port 21   FTP (vsftpd 2.3.4)
    |-- Port 22   SSH (OpenSSH 9.6p1)
    |-- Port 80   nginx 1.29.7 (static HackLab page, /uploads)
    |-- Port 3306  MySQL 8.4.8 (externally exposed)
    |-- Port 4000  Query-based API ("GET query missing")
    |-- Port 8080  Apache Tomcat 8.5.19
    |-- Port 8888  Spring Boot (JSON errors externally, actuator internal-only)
    |-- Port 9090  DVWS XML-RPC at /RPC2 [SSRF VECTOR]
    |
    |-- [Internal / localhost only -- reachable via SSRF]
    |   |-- 127.0.0.1:27017   MongoDB (binary protocol)
    |   |-- 127.0.0.1:28017   MongoDB HTTP REST (/serverStatus)
    |   |-- 127.0.0.1:8888    Spring Boot /env, /health, /configprops
    |   |-- 127.0.0.1:8080    Tomcat Manager /manager/html
    |
    |-- [Docker bridge 172.17.0.0/16]
        |-- 172.17.0.1   Docker host gateway
        |   |-- Port 80:   HTTP reachable
        |   |-- Port 2376: Docker API (TLS-protected, unexploitable via HTTP SSRF)
        |
        |-- 172.17.0.2   Container
        |   |-- Port 80:   HTTP service
        |
        |-- 172.17.0.3-6: No live hosts

Not reachable: AWS metadata (169.254.169.254), Redis (6379), PostgreSQL (5432), Memcached (11211), GraphQL on port 4000 via SSRF, private ranges 10.x and 192.168.x.


Timeline Summary

Time Action Result
6:42 Initial prompt received Two targets: port 80 + port 9090
6:43 Deep Think strategy + graph query 10-step plan, existing recon data loaded
6:44 Parallel recon: homepage, XML-RPC methods, port scan dvws.CheckUptime + pingback.ping discovered, port 8888 new
6:44 Method testing (lowercase) Case-sensitivity discovered -- lowercase fails
6:45 dvws.CheckUptime with http://example.com SSRF confirmed -- Needle/3.3.1 fetches arbitrary URLs
6:46 Protocol testing: file://, dict://, AWS metadata Only http/https supported, no metadata access
6:47 Localhost port scan via SSRF MongoDB on 27017, MongoDB HTTP on 28017
6:48 Docker network scan: 172.17.0.x Gateway .1, container .2, Docker API on 2376 (TLS)
6:50 Docker API exploitation attempt TLS blocks data extraction
6:51 MongoDB HTTP interface probing /serverStatus accessible
6:53 Spring Boot actuator via SSRF /env, /health, /configprops -- 404 externally, live internally
6:55 Tomcat Manager via SSRF /manager/html accessible -- potential WAR deploy vector
6:56 Final documentation All findings mapped to Neo4j graph

Total time: ~14 minutes. 15 agent steps. ~65 tool calls across 14 parallel execution waves.


Key Agent Capabilities Demonstrated

1. Systematic Service Enumeration

The agent didn't just test one or two internal IPs -- it methodically scanned localhost ports (6379, 5432, 11211, 3306, 27017, 28017, 4000, 8080, 8888), Docker bridge IPs (172.17.0.1 through 172.17.0.6), private ranges (10.x, 192.168.x), and AWS metadata. Each probe was run in parallel waves of 5-6 requests for maximum throughput.

2. Case-Sensitivity Pivot

When lowercase method names returned nothing, the agent immediately recognized the issue, checked the exact casing from system.listMethods, and retried with CheckUptime (capital C, capital U). A small detail that would have stalled a less adaptive approach.

3. Protocol Awareness

After confirming SSRF, the agent tested file://, dict://, and gopher:// to understand the SSRF's true capabilities. Recognizing that only HTTP/HTTPS worked through the Needle client shaped the rest of the exploitation strategy -- no wasted time on unsupported protocols.

4. Access Control Bypass Discovery

The most impactful finding was the Spring Boot actuator bypass: endpoints that return 404 to external requests but respond on localhost. The agent confirmed this by running both direct curl requests and SSRF-proxied requests to the same endpoints and comparing responses -- a proper scientific verification.

5. Multi-Layer Network Mapping

The agent built a complete topology: external services, localhost-only services, Docker bridge hosts, and Docker API status. It identified exactly which services are firewalled, which are TLS-protected, and which are exploitable -- creating an actionable attack map for deeper exploitation phases.

6. Massive Parallelism

Nearly every tool invocation was batched into parallel waves (14 waves of 4-6 tools each). The agent completed ~65 tool calls in 14 minutes -- roughly one meaningful discovery every 13 seconds.


Potential Next Steps (Not Executed)

The session stayed in the informational phase. If moved to exploitation:

  1. Spring Boot /env data extraction -- extract environment variables (database credentials, API keys, JWT secrets) by finding a way to read response bodies through the SSRF
  2. Tomcat Manager WAR deployment -- if default credentials work on /manager/html, deploy a JSP web shell for RCE
  3. MongoDB data extraction -- use the HTTP REST interface on port 28017 to query database contents
  4. Docker API with TLS bypass -- if client certificates can be obtained (e.g., from Spring Boot /env), the Docker API becomes a direct path to container escape

Raw Session Log

The complete unedited agent session log is available in SRF-H9SDB_session.md.

Clone this wiki locally