-
Notifications
You must be signed in to change notification settings - Fork 412
RCE VG0FN_sess_decoded
Exploit the target at gpigs.devergolabs.com (port 80).
Achieve command injection on the Express API and use it to harvest MySQL credentials.
Dump all databases from the internal MySQL server.
The agent started with nothing but a hostname and a port. No credentials, no API keys, no prior access. The objective was clear: find command injection, extract credentials, exfiltrate MySQL data. What followed was a methodical multi-phase attack spanning nearly 50 tool calls across coordinated fireteam members, culminating in an 81 KB database dump.
The agent began with a Neo4j graph query, finding the target running nginx 1.29.8 on port 80 at gpigs.devergolabs.com (15.160.68.117). A parallel wave of probes followed:
- Web search identified the platform as Damn Vulnerable Web Services (DVWS-Node), an intentionally vulnerable Node.js/Express application with API endpoints
-
FFUF directory scan discovered API surface:
/api/v2/login,/api/v2/users,/api/v2/notes, Swagger docs - Subfinder enumerated subdomains (none found beyond the primary)
The agent identified the target stack: Express/Node.js with JWT Bearer authentication. No credentials were known at this point.
The agent spawned 4 parallel fireteam members working simultaneously:
| Member | Role | Outcome |
|---|---|---|
| JS Analyst | Probed static files, Swagger docs | Identified API endpoint patterns |
| Auth Specialist | Registered users, obtained JWTs | Discovered JWT uses HS256 with header {"typ":"JWT","alg":"HS256"}
|
| Injection Login | Tested command injection on /api/v2/login
|
No injection found |
| Injection Register | Tested injection on user registration | No injection found |
Registered accounts for testing: testuser:Test1234!, testuser2:Test1234!, fuzzuser:fuzzpass.
Breakthrough: The Auth Specialist member analyzed the JWT structure and discovered the HS256 algorithm. A web search revealed the DVWS-Node GitHub repository uses the hardcoded secret access for JWT signing.
The agent spawned 3 fireteam members for deeper exploitation:
| Member | Role | Outcome |
|---|---|---|
| Endpoint Mapper | Fuzzed authenticated endpoints | Discovered /api/v2/sysinfo/:command and /api/v2/release/:release as potential injection vectors |
| Parameter Discovery | Tested parameter injection | Identified noSQL injection surface in query parameters |
| JWT Escalation | Forged admin JWT token | Created token with admin:read and admin:write permissions using secret access
|
JWT Forgery (member-2-ec0f1226):
The forged admin token:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiJhZG1pbiIsInBlcm1pc3Npb25zIjpbImFkbWluOnJlYWQiLCJhZG1pbjp3cml0ZSJdLCJpc3MiOiJ...
With this token, the agent accessed GET /api/v2/users and retrieved all user accounts with bcrypt password hashes.
The agent then extensively tested time-based command injection on authenticated endpoints:
-
/api/v2/notes-- no injection -
/api/v2/users-- no injection -
/api/v2/login-- no injection -
/api/v2/release/:release(unauthenticated) -- no injection found
The agent spawned 2 fireteam members for focused injection testing:
| Member | Role | Outcome |
|---|---|---|
| Vulnerability Researcher | Tested release endpoint variations | Confirmed /api/v2/release/:release NOT injectable |
| Authenticated Injection Tester | Systematic sysinfo testing | COMMAND INJECTION CONFIRMED |
The Winning Payload ($(sleep 5)# on /api/v2/sysinfo/:command):
The endpoint GET /api/v2/sysinfo/:command passes user input directly to child_process.exec() with a -a suffix. The agent discovered that shell substitution via $(...) executes before the Node.js call, and appending # comments out the trailing -a.
Baseline: /api/v2/sysinfo/whoami → 0.13s
Injection: /api/v2/sysinfo/$(sleep 5)%23 → 5.10s ⚡ TIME DIFFERENCE: 4.96s
Multiple payloads confirmed execution: $(sleep 5), `sleep 5`, whoami||sleep 5 (which returned "Hostname: root\n").
Using the confirmed command injection, the agent crafted a payload to exfiltrate the application's environment file:
write_payload = "$(cat /home/dvws-node/.env | base64 > /home/dvws-node/public/uploads/env.txt)#"Extracted .env contents:
EXPRESS_JS_PORT=80
XML_RPC_PORT=9090
GRAPHQL_PORT=4000
JWT_SECRET=access
MONGO_LOCAL_CONN_URL=mongodb://localhost:27017/node-dvws
MONGO_DB_NAME=dvws-user-auth
SQL_LOCAL_CONN_URL=localhost
SQL_DB_NAME=dvws_sqldb
SQL_USERNAME=root
SQL_PASSWORD=mysecretpassword
Critical discovery: The environment revealed WAIT_HOSTS=dvws-mysql:3306 -- the MySQL server was a separate Docker container named dvws-mysql, not accessible from the internet.
The agent faced several obstacles:
| Obstacle | Resolution |
|---|---|
| MySQL port 3306 not exposed externally | Used command injection as proxy |
mysql CLI binary not installed |
Used Node.js mysql2 driver from app's node_modules
|
MySQL host was dvws-mysql, not localhost
|
Discovered via WAIT_HOSTS env var |
| Complex scripts timed out (120s limit) | Built single-shot Node.js script via base64 injection |
The final dump script used mysql2 to connect to dvws-mysql:3306, enumerate all databases and tables, and write the complete dump as JSON to the publicly accessible /uploads directory. The agent then fetched it via HTTP.
Result: An 81 KB JSON dump (fulldump.json) containing all tables from mysql and dvws_sqldb databases -- successfully saved to /tmp/fulldump.json.
The agent compiled a comprehensive penetration test summary documenting:
- 9 vulnerabilities found (1 Critical, 2 High, 3 Medium, 2 Low, 1 Informational)
- All discovered credentials
- Attack chain methodology
- Remediation recommendations
| # | Vulnerability | Severity | Description |
|---|---|---|---|
| 1 | OS Command Injection (CWE-78) | Critical |
GET /api/v2/sysinfo/:command passes user input to exec() without sanitization |
| 2 | Hard-coded JWT Secret (CWE-798) | High | Secret access is publicly known from GitHub repo |
| 3 | Weak Password Exposure | High | MySQL root password in plain-text .env file |
| 4 | Information Disclosure (CWE-200) | Medium | Password hashes leaked in API responses |
| 5 | Missing Authentication | Medium | Unauthenticated user registration gives initial foothold |
| 6 | Missing Authorization (CWE-862) | Medium | No role checks on command injection endpoint |
| 7 | Excessive Permissions (CWE-250) | Low | Node.js process can write to /uploads
|
| 8 | Unrestricted File Upload | Low |
/api/upload endpoint may permit arbitrary uploads |
| 9 | nginx CVEs (Informational) | Info | CVE-2005-3299, CVE-2011-3192 (irrelevant to compromise) |
| Target Host | Service | Username | Secret | Notes |
|---|---|---|---|---|
| dvws-mysql:3306 | MySQL | root | mysecretpassword |
Full database access via RCE proxy |
| gpigs.devergolabs.com | JWT Secret | (N/A) | access |
Used to forge admin tokens |
| gpigs.devergolabs.com | Registered | testuser | Test1234! |
Created during recon |
| gpigs.devergolabs.com | Registered | testuser2 | Test1234! |
Created during recon |
| gpigs.devergolabs.com | Registered | testuser123 | testpass123 |
Created during recon |
| gpigs.devergolabs.com | Registered | fuzzuser | fuzzpass |
Created during recon |
| Time | Action | Result |
|---|---|---|
| 11:07 | Task received | Objective: command injection to credential harvesting |
| 11:09 | Graph query + web search | Identified DVWS-Node, nginx 1.29.8, Express API |
| 11:18 | FFUF directory scan | Discovered API endpoints: /api/v2/login, /api/v2/users
|
| 11:21 | Fireteam 1: API Discovery (4 members) | Registered users, obtained JWTs, discovered HS256 algorithm |
| 11:30 | Fireteam 2: Endpoint Mapping + JWT Escalation (3 members) |
Admin JWT forged using secret access, accessed all users with hashes |
| 12:07 | Fireteam 3: Injection Testing (2 members) | Systematic testing of all endpoints |
| 12:41 | COMMAND INJECTION CONFIRMED |
$(sleep 5)# on /api/v2/sysinfo/:command -- 4.96s delay |
| 12:48 |
.env file extracted |
MySQL credentials: root:mysecretpassword@dvws-mysql:3306
|
| 12:51 | MySQL dump debugging | Identified correct host (dvws-mysql), mysql2 driver available |
| 13:00 | Single-shot dump script executed | 81 KB fulldump.json -- all databases exfiltrated |
| 13:05 | File download complete |
fulldump.json saved to /tmp/fulldump.json
|
| 13:08 | Final report generated | 9 vulnerabilities documented with remediation |
Total active time: ~2 hours from first probe to complete MySQL exfiltration.
The agent discovered the JWT secret access not by cracking or brute-force, but by recognizing the DVWS-Node application from web search results and connecting it to the public GitHub repository. This intelligence-driven approach bypassed the need for any JWT attacks.
The agent deployed 3 sequential fireteams with a total of 9 coordinated member agents, each specializing in a different attack vector. This parallelized the discovery process:
- While some members tested injection on login, others registered accounts and analyzed JWT tokens
- While some fuzzed endpoints, others forged admin tokens and tested authenticated surfaces
- The fireteam results were automatically aggregated into the attack graph
The target appended -a to all commands via child_process.exec(). The agent recognized that $() substitution is evaluated by the shell before Node.js sees the command string, and that appending # comments out the trailing -a:
Input: $(cat /etc/passwd)#
Executed: $(cat /etc/passwd)# -a
Evaluated: cat /etc/passwd (then: # -a is a comment)
After achieving RCE, the agent extracted the full environment (not just .env). The WAIT_HOSTS=dvws-mysql:3306 variable revealed that MySQL was a separate Docker container, not on localhost -- preventing the initial failed connection attempts and enabling the correct target specification.
When which mysql returned empty, the agent didn't give up. It:
- Listed
node_modulesto find available database drivers - Tested
require('mysql')andrequire('mysql2')via Node.js - Both drivers confirmed available --
mysql2selected - Built and injected a complete Node.js dump script via base64 encoding
- Wrote output to the publicly accessible
/uploadsdirectory
The agent's full dump script timed out after 120 seconds due to dozens of sequential injection+fetch cycles. It adapted by writing a single Node.js script that dumped all databases into one JSON file on the server side, then fetched it in one HTTP request. This reduced the exfiltration to 2 round-trips and succeeded within seconds.
Full session transcript: RCE-VG0FN_session.md
Getting Started
Core Workflow
- Red Zone
- Recon Pipeline Workflow
- Running Reconnaissance
- AI Agent Guide
- Fireteam — Parallel Specialists
- Agent Workspace
- Reverse Shells
Scanning & OSINT
- Adversarial AI Recon
- JS Reconnaissance
- GraphQL Security Testing
- Subdomain Takeover Detection
- VHost & SNI Enumeration
- GVM Vulnerability Scanning
- GitHub Secret Hunting
- TruffleHog Secret Scanning
AI & Automation
- AI Model Providers
- MCP Tool Plugins
- Knowledge Base & Web Search
- Agent Skills
- Chat Skills
- Tradecraft Lookup
- Playwright Browser Automation
- CypherFix — Automated Remediation
- Rules of Engagement (RoE)
HackLab
Analysis & Reporting
- Insights Dashboard
- Pentest Reports
- Attack Surface Graph
- Surface Shaper
- EvoGraph — Attack Chain Evolution
- Data Export & Import
Contributing
Reference & Help