Operator On The Wire
← Back to Knowledge Base
OOTW / Chapter III - Web / Web Servers

Information

Web servers sit between the network and the application.

They decide which host receives a request, which directory maps to the URL, which files are static, which requests are passed to an application runtime, which headers are trusted, where logs are written, and which local user executes the backend code.

When testing web applications, we are not only testing application code. We are also testing the server layer around it.


Core Model

A request usually moves through these layers:

client
  -> load balancer / CDN / reverse proxy
  -> web server
  -> application server / runtime
  -> application code
  -> database / filesystem / internal services

The web server may be the origin server, or it may be a reverse proxy in front of another service.

Common roles:

  • Static file server
  • TLS terminator
  • Reverse proxy
  • Virtual host router
  • Access-control layer
  • Compression/cache layer
  • Request-size and request-rate gate
  • Handler dispatcher for PHP, ASP.NET, CGI, Python, Ruby, Node, Java, or another runtime

This matters because many bugs are not inside the application function that receives the request. They are created by how the web server maps, rewrites, proxies, logs, or handles the request before the application sees it.


What To Identify First

Start every server assessment with the same questions:

  • Which server is handling the request?
  • Is there a reverse proxy in front of the application?
  • Is the server Apache, NGINX, IIS, or something else?
  • Which host header reaches which site?
  • Where is the webroot?
  • Which files are served directly?
  • Which extensions are executed by a runtime?
  • Which paths are proxied to internal services?
  • Where are access and error logs stored?
  • Which local user runs the worker process?
  • Are per-directory config files allowed?
  • Are uploaded files ever placed in an executable directory?

Headers are clues, not proof.

curl -i http://target/
curl -I http://target/
curl -i -H "Host: test.target" http://target/

The Server header may be removed, modified, or replaced by a proxy. Confirm through behavior, default pages, error formats, file paths, and configuration access when we have local read access.


Enumeration Flow

Use this order:

  1. Fingerprint the service.
  2. Enumerate hostnames and virtual hosts.
  3. Enumerate directories and static files.
  4. Check interesting default endpoints.
  5. Identify the webroot and runtime.
  6. Look for exposed backups, source, config, and logs.
  7. If a local file read exists, pull server config and logs.
  8. Map proxy rules, aliases, handlers, and upload directories.
  9. Test server-specific misconfigurations.
  10. Convert findings into the application impact.

Useful first-pass commands:

nmap -sV -sC -p80,443,8080,8000,8443 target
curl -i http://target/
whatweb http://target/
nikto -h http://target/

Virtual host discovery:

ffuf -u http://TARGET_IP/ -H "Host: FUZZ.example.local" \
  -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt

Directory discovery:

gobuster dir -u http://target/ \
  -w /usr/share/seclists/Discovery/Web-Content/common.txt

Important Concepts

Webroot

The webroot is the filesystem directory served by the web server.

Examples:

/var/www/html
/usr/share/nginx/html
C:\inetpub\wwwroot

If the application lets users upload files into the webroot, the file upload lesson becomes more dangerous. If the server executes the uploaded extension, an upload bug can become code execution.

Virtual Hosts

Virtual hosts let one server host multiple sites.

The routing key is usually:

  • IP address
  • Port
  • Host header
  • TLS SNI name

Misrouting can expose staging apps, admin panels, default sites, or internal services.

Handlers

Handlers decide what happens when a requested file has a certain extension or path.

Examples:

.php   -> PHP-FPM or mod_php
.aspx  -> ASP.NET
.cgi   -> CGI handler
static -> served as a file

Handler confusion is a common source of upload and path bugs. A file that should be treated as inert data becomes dangerous if the server treats it as code.

Aliases

Aliases map a URL path to a filesystem path outside the normal webroot.

They are useful for static assets and shared directories. They are risky when the path mapping is wrong, when access control applies to the wrong location, or when traversal is possible around the intended directory.

Reverse Proxies

A reverse proxy forwards requests to another service.

Examples:

NGINX -> gunicorn
Apache -> Tomcat
IIS ARR -> backend IIS/Kestrel app

Proxy rules can create:

  • Internal service exposure
  • Host header trust issues
  • Incorrect scheme detection
  • Header spoofing through X-Forwarded-For
  • Cache poisoning
  • Request smuggling between front and back servers
  • Authentication bypass if only the proxy enforces access control

Common Vulnerability Classes

Directory Listing

Directory listing exposes file names when no index file exists.

It often reveals:

  • Backups
  • Old source files
  • Upload directories
  • Logs
  • Database dumps
  • Admin scripts

Exposed Configuration

Configuration files reveal webroots, upstreams, credentials, internal hostnames, handler mappings, and secrets.

High-value examples:

.htaccess
.htpasswd
web.config
applicationHost.config
nginx.conf
apache2.conf
httpd.conf

Log Poisoning

Log poisoning becomes dangerous when we can write attacker-controlled text into a log file and later force the application runtime to interpret that log as code.

The classic PHP chain needs three conditions:

  • The server logs request data we control, such as the User-Agent.
  • The application has LFI or another include primitive that can read the log file.
  • The included file is interpreted by PHP, not displayed as plain text.

The log file alone does not execute code. The include behavior creates the execution.

Safe proof marker:

curl -A "ootw-log-marker" http://target/

Then attempt to read the expected access log through the local file read primitive. In a real assessment, stop at a harmless marker unless the scope explicitly permits exploitation.

Upload To Executable Path

Uploads become dangerous when these conditions overlap:

  • The user controls file content.
  • The user controls or predicts file extension.
  • The file lands under the webroot.
  • The server executes that extension.
  • Per-directory config can change handlers.

Apache .htaccess and IIS web.config are especially important here.

Host Header And Proxy Trust

Applications often use the Host header to generate links, password reset URLs, tenant routing, or cache keys.

Proxies often add headers such as:

X-Forwarded-For
X-Forwarded-Host
X-Forwarded-Proto
Forwarded

The backend should trust these only from known proxy IPs. If the application trusts client-supplied proxy headers directly, access control, logging, redirects, and rate limits can be bypassed or confused.

Hidden Files And Backups

Common targets:

.git/
.env
backup.zip
site.tar.gz
config.php.bak
web.config.old
database.sql

These are usually application mistakes, but server directory listing and weak static file rules make them reachable.


Local File Read Targets

When LFI or path traversal exists, server files help turn a vague bug into a map.

Linux Apache:

/etc/apache2/apache2.conf
/etc/apache2/sites-enabled/000-default.conf
/var/log/apache2/access.log
/var/log/apache2/error.log
/var/log/httpd/access_log
/var/log/httpd/error_log

Linux NGINX:

/etc/nginx/nginx.conf
/etc/nginx/sites-enabled/default
/etc/nginx/conf.d/default.conf
/var/log/nginx/access.log
/var/log/nginx/error.log

Windows IIS:

C:\inetpub\wwwroot\web.config
C:\inetpub\logs\LogFiles\
C:\Windows\System32\inetsrv\config\applicationHost.config
C:\Windows\System32\LogFiles\HTTPERR\

Remediation

Secure server configuration with these rules:

  • Disable directory listing unless it is intentionally required.
  • Keep server banners minimal.
  • Do not expose config files, backups, source directories, or logs.
  • Keep uploads outside executable webroots.
  • Store user files with generated names and inert extensions.
  • Do not allow per-directory config override unless required.
  • Keep reverse proxy rules explicit.
  • Trust forwarded headers only from controlled proxy IPs.
  • Separate public, admin, and internal applications into clear virtual hosts.
  • Keep server and modules patched.
  • Use least privilege for worker processes.
  • Monitor suspicious path traversal, tilde enumeration, log poisoning markers, WebDAV verbs, and handler-probing requests.

Server configuration is part of the application boundary. Treat it as code.