Skip to content

BRW XSCVR_sess_decoded

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

BRW-XSCVR -- Maximum XSS Coverage Across All Discovered Routes

Session Decoded: How the Agent Mapped 3 Ports, Coordinated 11 Specialists, and Confirmed 5 XSS Vectors in 1 Hour


The Prompt

Target the website gpigs.devergolabs.com on port 80. Enumerate every
route, then find every XSS on every route. Maximum coverage --
reflected, stored, DOM-based, and blind. Report each finding with the
route, parameter, and the payload that fired.

No credentials, no endpoint list, no scope hints. The agent had to discover the full route surface across the entire target (spilling onto ports 8080 Tomcat and 4000 GraphQL as well), then systematically test every input for every XSS class with browser-verified proof of execution.


What Happened: The Full Attack Chain

Phase 1 -- Fingerprint and Graph Check (8:35 PM)

The agent opened with 3 parallel probes:

  • httpx confirmed nginx 1.29.8 on port 80, title "RedAmon HackLab -- Research Target"
  • naabu enumerated open ports: 80 and 8080 exposed (Tomcat would later surface; GraphQL on 4000 was uncovered via Swagger)
  • query_graph returned only the base URL for gpigs.devergolabs.com, no stored paths or parameters yet

The graph was nearly empty for port 80. The agent had to discover the entire attack surface from scratch.


Phase 2 -- Fireteam Wave 1: Route Discovery (8:36 - 9:04 PM)

Rather than walking the surface sequentially, the agent spawned 3 parallel specialists, each with a different discovery technique:

Specialist Skillset Outcome
Directory Fuzzer ffuf, curl Broke through nginx anti-fuzz with low-rate scans, surfaced /api/v1/info leaking JWT_SECRET=access, SQL creds (root/mysecretpassword), MongoDB connection string, full container environment
Passive Recon & JS Analyst gau, jsluice, arjun Enumerated Tomcat 8.5.19 documentation on 8080, injectable parameters (including signing on /docs/changelog.html), Apollo GraphQL on port 4000
Katana Crawler katana, playwright Port 80 rendered as a static nginx landing page. The real SPA lives behind authenticated routes (home.html, notes.html, upload.html, admin*.html) reachable only with a JWT

After 27 minutes the consolidated attack surface was:

  • Port 80 SPA: home.html, receiver.html, search.html, notes.html, upload.html, admin.html, admin_create_user.html, admin_logs.html, admin_user_status.html, all AngularJS-driven
  • Port 80 DOM sinks: document.write(location.hash) in home.html, postMessage handler in receiver.html, wildcard postMessage in userdisplay.js (admin.html)
  • Port 8080 Tomcat: RequestParamExample, CookieExample, SessionExample, JSP examples with reflecting parameters
  • Port 4000 GraphQL: introspection open, updateUserUploadFile(filePath, fileContent), createNote, userLogin, readNote, getPassphrase

Phase 3 -- Phase Transition: Informational to Exploitation (9:04 PM)

The agent flagged a phase transition request with a full risk analysis: WAF/rate limiting on port 80, AngularJS 1.8.3 sandbox escape required for template injection, Tomcat HTML-encoding of angle brackets forcing attribute/JS context payloads. User approved and the agent switched to exploitation step 3.


Phase 4 -- Fireteam Wave 2: Parallel XSS Hunt (9:05 - 9:23 PM)

Four specialists, four attack surfaces, zero shared state:

DOM XSS Specialist (port 80 pages): the breakthrough member. Worked the location.hash and postMessage sinks simultaneously.

Vector Sink Payload Result
home.html document.write(location.hash) feeding AngularJS compilation #{{constructor.constructor('alert(1)')()}} 5 dialogs captured, sandbox bypassed
receiver.html postMessage handler writing directly to innerHTML, no origin check <img src=x onerror=alert(document.domain)> Alert fired with 15.160.68.117
home.html (decoded variant) browser URL-encodes hash, but a monkey-patched decode verified the sink <img src=x onerror=alert('DOM-XSS-decoded')> Exploitable with a prior URL-decode step

Port80 App XSS (search, notes, upload, admin): registered testxss:testxss123, exercised every AngularJS-bound view. Found that the notes API stores unescaped HTML and AngularJS template expressions, but ng-bind/{{ }} interpolation auto-escapes on render, blocking exploitation in the current templates.

Tomcat XSS Hunter (port 8080): canary reflected on every target, but the servlet encodes < and > in all responses. Not exploitable without a parser quirk. Correctly reported as non-vulnerable rather than forcing a false positive.

GraphQL Stored XSS (port 4000): terminated with a connection error after full schema introspection. Recorded the mutation surface for the next wave.


Phase 5 -- User Checkpoint (9:24 PM)

User asked the agent to collect results and prepare a report. The agent chose to run one more fireteam wave first, since four specific surfaces (search.html, notes.html, upload.html, admin SOAP) were still untested.


Phase 6 -- Fireteam Wave 3: Closing the Gaps (9:24 - 9:38 PM)

Search Page XSS: AngularJS 1.8.3 sandbox blocked constructor-based escapes in the search input context. API response round-trip confirmed stored HTML but no template evaluation post-compilation. Not exploitable.

Notes Stored XSS: confirmed that notes API persists unsanitized HTML (<img src=x onerror=alert(1)>), but the AngularJS rendering path calls ng-bind which HTML-escapes on display. Stored but not triggered.

Upload XSS -- the other big win: two confirmed stored XSS variants.

Vector Path Payload Result
GraphQL updateUserUploadFile with path traversal /uploads/testxss/xss-graphql.html <script>alert(document.domain)</script> written directly to web root Dialog fired on navigation, no CSP on /uploads/
/api/upload accepting XML with XHTML script namespace /uploads/testxss/xss-test.xml <html xmlns=... xmlns:script="..."><script:script>alert(1)</script:script></html> Served as XHTML, script executed

Admin SOAP XSS: the SOAP endpoint /dvwsuserservice reflects input verbatim in the XML response. escapeXml on the client side encodes angle brackets and quotes but leaves curly braces intact. AngularJS template injection was plausible, but jQuery.text() is called before the result reaches the binding, neutralising the attack. Exploited stored content, no browser-level alert, reported as partial.


Confirmed Findings

# Type Route Parameter / Source Payload
1 DOM XSS (AngularJS template injection) /home.html location.hash {{constructor.constructor('alert(1)')()}}
2 DOM XSS (postMessage to innerHTML) /receiver.html postMessage data, no origin check <img src=x onerror=alert(document.domain)>
3 DOM XSS (document.write sink) /home.html location.hash after URL decode <img src=x onerror=alert('DOM-XSS-decoded')>
4 Stored XSS (GraphQL arbitrary file write) /uploads/ via GraphQL mutation filePath + fileContent path traversal in updateUserUploadFile Arbitrary HTML/JS written to web root
5 Stored XSS (XML file upload) /uploads/ via /api/upload XML file content XHTML with <script> namespace
6 JWT Leak (misconfiguration) /admin.html (userdisplay.js) postMessage('*') broadcast Any iframe receives the admin JWT

Non-Exploitable (Correctly Identified)

Surface Reason
search.html, notes.html (API-stored) AngularJS ng-bind auto-escapes on render, blocking stored HTML from executing
Tomcat 8080 servlets HTML-encoded < and > on reflection
Admin SOAP (/dvwsuserservice) jQuery.text() extracts text before DOM insertion, escapeXml preserves {} but AngularJS not re-evaluated
AngularJS 1.8.3 sandbox in search input Constructor-chain payloads blocked in that specific context
/proc/self/environ class sinks Not relevant for XSS

Timeline Summary

Time Action Result
8:35:19 PM User prompt Attack surface scope: port 80, every XSS class
8:35:46 PM Wave 3 tools (httpx, naabu, query_graph) nginx 1.29.8, ports 80 + 8080, empty graph
8:36:39 PM Fireteam #1 (3 members, 27m) Port 80 SPA mapped, /api/v1/info credential leak, Tomcat + GraphQL surfaces
9:04:25 PM Phase transition request Informational to exploitation, approved by user
9:05:14 PM Fireteam #2 (4 members, 18m) DOM XSS confirmed on home.html and receiver.html
9:24:38 PM User checkpoint Request to collect and report
9:24:42 PM Fireteam #3 (4 members, 13m) Stored XSS via GraphQL file write and XML upload confirmed
9:39:22 PM Final report 5 confirmed XSS + 1 JWT misconfiguration, cross-referenced by route and payload

Total time: ~1 hour 4 minutes from first request to final report.


Key Agent Capabilities Demonstrated

1. Multi-Phase Fireteam Coordination

Three fireteam waves, 11 independent specialist members, each with its own tool skillset, iteration budget, and target surface. The agent partitioned the work so no two specialists overlapped, then merged their findings into a single cross-referenced report.

2. Phase Discipline

The agent refused to fire a single exploit payload until it formally requested and received a phase transition from informational to exploitation, complete with planned actions and risk analysis. This kept recon and exploitation traceable and safe.

3. AngularJS 1.8.3 Sandbox Awareness

Two different AngularJS contexts produced two different outcomes. home.html was vulnerable because document.write feeds the hash fragment into the compilation pipeline before the sandbox sees it. search.html was not vulnerable because the template compiler runs once at load. The agent distinguished these cases and documented both.

4. Recognising Non-Exploitable Cases

Many targets reflected canaries but encoded dangerous characters (Tomcat) or auto-escaped on render (notes, search). The agent reported these as not exploitable rather than manufacturing false positives, which is the harder and more honest outcome.

5. Chaining GraphQL to Stored XSS

The GraphQL updateUserUploadFile mutation accepted a path traversal pattern, writing arbitrary HTML files to a web-accessible directory with no CSP. This is a server-side authorization flaw that the agent converted into a client-side XSS primitive, showing end-to-end chain thinking across the GraphQL, file-system, and browser layers.

6. Parallel Browser Verification with Playwright

Every confirmed XSS was verified with a Playwright dialog handler capturing alert() proof-of-execution, not just grep matches on reflected strings. Confirmed cases include dialog-captured document.domain for cross-origin proof.


Raw Session Log

The complete unedited agent session log is available in BRW-XSCVR_session.md.

Clone this wiki locally