Nginx — Enumeration & Exploitation
Ctrl+F:
sites-enabled·server_name·proxy_pass·alias·nginx
Nginx is a high-performance web server and reverse proxy. On OSCP boxes it often fronts PHP, proxies to internal apps, or hosts multiple vhosts on one IP.
📌 Identify Nginx
curl -sI http://TARGET | grep -i server
# Server: nginx/1.18.0 (Ubuntu)
nmap -p 80,443 -sV --script http-server-header TARGETCommon ports: 80, 443, sometimes 8080 / 8443 as alt HTTP(S).
📌 External enumeration (no shell)
Directory & vhost fuzzing
# Paths
gobuster dir -u http://TARGET -w /usr/share/wordlists/dirb/common.txt -x php,html,txt,bak -t 40
ffuf -u http://TARGET/FUZZ -w /usr/share/wordlists/SecLists/Discovery/Web-Content/common.txt
# Vhost / subdomain discovery (different Host header → different site on same IP)
ffuf -u http://TARGET -H "Host: FUZZ.TARGET" -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-5000.txt -fs 0
gobuster vhost -u http://TARGET -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-5000.txtVersion & misconfig checks
nikto -h http://TARGET
# Nginx + PHP-FPM path normalization bug (if version/misconfig matches)
# CVE-2019-11043 — https://github.com/neex/phuip-fpizdam📌 Quick reference — paths & commands
| Item | Purpose |
|---|---|
/etc/nginx/sites-enabled/ | Subdomain / vhost enum on compromised web server — symlinks to enabled site configs |
/etc/nginx/sites-available/ | All site configs (enabled + disabled) |
/etc/nginx/nginx.conf | Main config — include, worker, global settings |
grep -r server_name /etc/nginx/ | List all server_name / vhost hostnames |
grep -r proxy_pass /etc/nginx/ | Find backends (internal apps, APIs, Jenkins, etc.) |
grep -r root /etc/nginx/ | Document roots per vhost |
/var/log/nginx/access.log | Hit paths, hidden params, other vhosts users visited |
/var/log/nginx/error.log | App paths, upstream errors, config leaks |
location + alias blocks | Alias traversal / off-by-slash misconfig targets |
try_files + PHP | LFI / path traversal chains with Local File Inclusion (LFI) |
📌 Post-compromise enumeration (Linux shell)
When you have www-data (or any read on /etc/nginx):
# Vhosts — missed subdomains from external recon
ls -la /etc/nginx/sites-enabled/
cat /etc/nginx/sites-enabled/*
ls -la /etc/nginx/sites-available/
# All hostnames nginx serves
grep -r server_name /etc/nginx/ 2>/dev/null
grep -r listen /etc/nginx/ 2>/dev/null
# Backends & document roots
grep -rE 'proxy_pass|root|alias|fastcgi_pass' /etc/nginx/ 2>/dev/null
# Included snippets (often hold TLS paths, auth, upstreams)
grep -r include /etc/nginx/nginx.conf /etc/nginx/sites-enabled/ 2>/dev/null
# Logs — discover apps and parameters
tail -100 /var/log/nginx/access.log
tail -50 /var/log/nginx/error.log
grep -i admin /var/log/nginx/access.log | tail -20Credential / secret hunt in web roots
grep -rni "password\|passwd\|secret\|apikey\|db_" /var/www/ 2>/dev/null | head -30
find /var/www -name ".env" -o -name "wp-config.php" -o -name "config.php" 2>/dev/null→ Privilege escalation > 📌 Phase 1 — Linux Manual Enum · Linux
📌 Exploitation paths
1) Missed vhost → new attack surface
Config shows server_name dev.internal.target but you only scanned the main site:
# Add to /etc/hosts or use Host header
curl -H "Host: dev.internal.target" http://TARGET_IP/
ffuf -u http://TARGET_IP -H "Host: FUZZ.target.htb" -w subdomains.txt2) proxy_pass → internal service
Nginx proxies /jenkins/ → http://127.0.0.1:8080 — access via path on the public vhost or pivot after SSRF/LFI.
3) Alias / location misconfiguration
Classic off-by-slash or alias traversal — read files outside intended directory. Test with Burp path normalization (../, %2e%2e/, trailing slash).
4) PHP behind Nginx
- Upload bypass → File Upload Bypass · webshells in Shell > 📌 Default Linux paths — Kali webshells
- LFI in
try_files/fastcgi_param SCRIPT_FILENAMEchains → Local File Inclusion (LFI)
5) CVE-2019-11043 (Nginx + PHP-FPM)
Specific PHP-FPM under certain nginx configs — use phuip-fpizdam when recon matches.
📌 Quick cheat sheet
# External
curl -sI http://TARGET | grep -i server
ffuf -u http://TARGET -H "Host: FUZZ.target.htb" -w subdomains.txt -fs <baseline>
# On shell (www-data)
ls -la /etc/nginx/sites-enabled/
grep -r server_name /etc/nginx/
grep -r proxy_pass /etc/nginx/
tail -50 /var/log/nginx/access.log