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 TARGET

Common 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.txt

Version & 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

ItemPurpose
/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.confMain 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.logHit paths, hidden params, other vhosts users visited
/var/log/nginx/error.logApp paths, upstream errors, config leaks
location + alias blocksAlias traversal / off-by-slash misconfig targets
try_files + PHPLFI / 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 -20

Credential / 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.txt

2) 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

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