Web Servers Attacks
A little overview about reconnaissance and misconfiguration-identification phase of web application testing.
Identifying Web Servers
The web server software itself shapes which misconfigurations are possible, which paths are worth checking, and which tools will be most effective. Identifying the server is not a formality. It directly influences every decision that follows.
The Server Response Header
# -s suppresses the progress bar
# -I sends a HEAD request, returning only response headers
curl -sI http://TARGET_MACHINE:80
The -sI flag sends a HEAD request, which returns headers only and no body. To see default error pages, I need a GET request switch to -s without the -I
# HEAD request: headers only, no body
curl -sI http://10.113.172.79:PORT/
# GET request: full response including body
curl -s http://10.113.172.79:PORT/nonexistent-page-xyz
Python HTTP Server
Python ships with a built-in HTTP server.
The Python HTTP server is a realistic finding because it requires no exploitation. There is no vulnerability to trigger. The server is functioning exactly as designed.
# This command serves the current working directory over HTTP on port 8000
python3 -m http.server 8000
Directory Listing
Python HTTP server generates an HTML page listing every file it can see. Browse to the root of the server using the following command or directly browse
http://TARGET_MACHINE:8000 in the browser
Apache
Version Disclosure
Apache on Ubuntu defaults to ServerTokens OS, which includes the OS label alongside the version number. Knowing the exact version helps check for known CVEs and understand the server's capabilities.
The mod_status Page
Apache includes a built-in status page powered by the mod_status module. When correctly configured, it is accessible only from localhost. When misconfigured with Require all granted, it is accessible from any IP. You can access it using
Finding Unlinked Files with Gobuster
# -u is the target URL
# -w is the wordlist path
# -x tells gobuster to also append these extensions to each word
gobuster dir -u http://TARGET_IP:80 -w /usr/share/wordlists/SecLists/Discovery/Web-Content/common.txt -x bak,txt,html -t 20
.htpasswd to store usernames and hashed passwords for HTTP Basic Authentication.
Node.js (Express)
#Verbose Errors
curl -s http://TARGET_IP:3000/api/users | python3 -m json.tool
# Enumerating Routes via Debug Endpoints
curl -s http://TARGET_IP:3000/api/routes
#Exposed Environment Variables
curl -s http://TARGET_IP:3000/api/debug/env
#Static File Serving
curl -s http://TARGET_MACHINE:3000/static/config.js
Nginx
It is most commonly used as a reverse proxy, a load balancer, or a high-performance static file server. In production environments, Nginx often sits in front of an application server and handles the public-facing traffic.
Directory Listing with Autoindex
Nginx does not enable directory listing by default. When a developer wants to expose a directory listing, they add autoindex to a location block in the configuration:
curl -s http://10.113.172.79:8080/files/
Nginx's stub_status module exposes real-time connection metrics at a configurable URL. The secure configuration restricts access to localhost only. The misconfigured version allows access from any IP:
Tip
Tip: Nginx configuration files live in /etc/nginx/ on Ubuntu. If you ever have shell access to a machine running Nginx, reading the site configuration in /etc/nginx/sites-available/ will show you exactly what directories are exposed and what modules are enabled.
Common Misconfigurations Accros Web Server
Security Headers
Security headers are HTTP response headers that instruct the browser on how to handle the page content. They protect against a range of client-side attacks, including clickjacking, MIME sniffing, and cross-site scripting.
| Header | What It Protects Against | Example Value |
|---|---|---|
X-Frame-Options |
Clickjacking (prevents the page from being embedded in an iframe on another domain) | DENY or SAMEORIGIN |
X-Content-Type-Options |
MIME sniffing (prevents the browser from guessing content types) | nosniff |
Content-Security-Policy |
Restricts where scripts, stylesheets, and other resources can load from | default-src 'self' |
Referrer-Policy |
Controls what is sent in the Referer header when navigating to another page |
no-referrer or strict-origin |
Strict-Transport-Security |
Forces HTTPS for subsequent requests (only meaningful on HTTPS servers) | max-age=31536000 |
Note
Note: X-Frame-Options is technically superseded by Content-Security-Policy: frame-ancestors, which provides finer-grained control. Hardened modern sites may handle clickjacking protection through CSP alone and intentionally omit X-Frame-Options. When writing findings, check for both.
Audit each server with curl:
for port in 80 8000 3000 8080; do echo "=== Port $port ==="; curl -sI http://TARGET_MACHINE:$port/ | grep -iE "x-frame-options|x-content-type|content-security-policy|strict-transport|referrer-policy" || echo "(no security headers found)"; done
Automated Scanning with Nikto
Nikto is a web server scanner that checks for known misconfigurations, outdated software, exposed admin interfaces, and missing security headers. It is not subtle; it generates a lot of traffic and is easy to detect
# The -nointeractive flag suppresses prompts so the scan runs without waiting for input.
nikto -h http://TARGET_IP:80 -nointeractive
Patterns That Apply Everywhere
| Misconfiguration | Apache | Python HTTP | Node.js | Nginx |
|---|---|---|---|---|
| Version disclosure in headers | Yes | Yes | Partial | Yes |
| Directory listing | /files/ |
Root path | N/A | /files/ |
| Exposed status or debug endpoint | /server-status |
N/A | /api/debug/env, /api/routes |
/nginx_status |
| Sensitive files accessible | backup.bak, internal-notes.txt |
.env, notes.txt, backup.zip |
config.js |
server-config.txt, deploy-notes.txt |
| Missing security headers | All | All | All | All |
Takeaways
- Response headers are the fastest fingerprinting surface. The Server and X-Powered-By headers reveal software type and sometimes version before you have made a single request to an actual application path.
- Python's built-in HTTP server has no access controls of any kind. When it appears in an engagement, assume the entire working directory is readable, including dotfiles such as
.env. - Apache's mod_status and directory listing are enabled by default on Ubuntu installs and require active configuration to restrict them. Their presence is common and worth checking on every Apache engagement.
- Node.js Express applications in development mode leak stack traces, route lists, and environment variables. Each of those is a finding in its own right, and together they give a complete picture of the application's internals.
- Nginx autoindex and stub_status mirror Apache's directory listing and mod_status patterns. The directives differ, but the investigation approach is the same.
Internet Information Services (IIS)
Is Microsoft's web server platform built into Windows Server. It hosts websites, web applications, and services such as Exchange OWA, SharePoint, and ADFS.
ISS fingerprinting and Enumeration
HTTP.sys is a kernel-mode driver that receives all HTTP traffic before any IIS process touches it.
HTTP Banner Grabbing
Web Distributed Authoring and Versioning (WebDAV) is an HTTP extension that adds file management verbs: PUT (upload), DELETE, COPY, MOVE, PROPFIND, and LOCK.
# The HTTP OPTIONS method asks the server to return its supported methods. A single command tells you whether WebDAV is active
curl -X OPTIONS http://10.113.144.60 -sv 2>&1 | grep -E "Allow:|DAV:"
Testing What File Types Can Be Uploaded and Executed
PUT a test file, then GET it and observe the response. A 200 with output means the server executed it; a 200 with your raw file content means it was served statically.