# ============================================================ # VULNERABLE Nginx Configuration — CTF Challenge Resource # ============================================================ # This configuration contains INTENTIONAL security weaknesses # for educational / CTF use only. DO NOT deploy in production. # ============================================================ user nginx; worker_processes auto; error_log /var/log/nginx/error.log; pid /run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; # FINDING: Server tokens enabled — leaks exact Nginx version server_tokens on; sendfile on; keepalive_timeout 65; # FINDING: Weak SSL configuration ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:MEDIUM:!aNULL:!MD5:RC4-SHA:DES-CBC3-SHA:RC4-MD5; ssl_prefer_server_ciphers off; # Missing: ssl_session_tickets off; # Missing: ssl_stapling on; # ========================================================== # Primary virtual host — files.ctf-target.com # ========================================================== server { listen 80; listen 443 ssl; server_name files.ctf-target.com; ssl_certificate /etc/nginx/ssl/server.crt; ssl_certificate_key /etc/nginx/ssl/server.key; root /var/www/html; # FINDING: Directory listing enabled globally autoindex on; autoindex_exact_size on; autoindex_localtime on; # FINDING: Missing security headers # (none of the following are set) # add_header X-Frame-Options "DENY"; # add_header X-Content-Type-Options "nosniff"; # add_header X-XSS-Protection "1; mode=block"; # add_header Content-Security-Policy "default-src 'self'"; # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains"; # add_header Referrer-Policy "no-referrer"; # add_header Permissions-Policy "geolocation=(), camera=()"; # FINDING: Alias traversal vulnerability # Requesting /static../etc/passwd will resolve to /etc/passwd location /static { alias /var/www/static/; } # FINDING: Proxy to internal services without authentication location /api/ { proxy_pass http://10.0.1.50:8080/; # No auth_basic or access control # No rate limiting # No request size limit } location /internal-admin/ { proxy_pass http://10.0.1.51:3000/; # Should require authentication — currently open to everyone # Should restrict to internal IPs — no allow/deny rules } location /redis-commander/ { proxy_pass http://10.0.1.52:8081/; # Redis management UI exposed without auth } # FINDING: Exposed status endpoint — no IP restriction location /status { stub_status on; # Missing: allow 127.0.0.1; deny all; } # FINDING: Exposed phpinfo for debugging (left in production) location /phpinfo.php { fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME /var/www/html/phpinfo.php; include fastcgi_params; } # FINDING: Backup files accessible # No rule to block .bak, .sql, .env, .git, etc. # FINDING: No rate limiting configured anywhere # Missing: limit_req_zone / limit_req directives # FINDING: No client body size limit # Missing: client_max_body_size directive (defaults to 1MB but # should be explicitly set for upload endpoints) } # ========================================================== # Internal services reverse proxy # ========================================================== server { listen 8443 ssl; server_name internal.ctf-target.com; ssl_certificate /etc/nginx/ssl/server.crt; ssl_certificate_key /etc/nginx/ssl/server.key; # FINDING: Using same weak SSL config as above (TLS 1.0, weak ciphers) # FINDING: Proxying to Elasticsearch without authentication location /elasticsearch/ { proxy_pass http://10.0.1.60:9200/; } # FINDING: Proxying to Kibana without authentication location /kibana/ { proxy_pass http://10.0.1.60:5601/; } # FINDING: Proxying to Grafana with default admin/admin location /grafana/ { proxy_pass http://10.0.1.61:3000/; } # FINDING: Server-side includes enabled (potential SSI injection) location /legacy/ { ssi on; root /var/www/legacy; } } }