networking

HTTP Port 80: Operational Guide (Ports/Protocols) in Pentesting

HTTP Port 80: Operational Guide (Ports/Protocols) in Pentesting

Port 80 in pentest lab: scan, HTTP fingerprint, vhost enum, directory brute force, misconfig and detection. Workflow with Nmap/ffuf/curl.

  • Posted on 2026-07-09
  • Reading time: 8 min

HTTP 80: Ports, Protocols, and Payloads in Pentesting (Offensive Cybersecurity Guide) #

You're on an HTB/PG target and nmap returns 80/tcp open . From there, you have two options: waste time opening the browser at random, or take out the server, virtual host, directory, and verifiable misconfigs in 10 minutes. This article covers the latter: HTTP fingerprinting, vhost/directory enumeration, and the five misconfigs on port 80 that unlock more boxes than meets the eye (authorized lab/HTB/PG/VM only).

Why HTTP 80 is a “high leverage” port #

In short: 80/tcp is rarely "just a site": it's often a gateway to authentication, panels, APIs, and internal assets. If poorly exposed, it multiplies risk.

A reverse proxy (Nginx/Apache) in front of multiple apps is not fingerprinted by looking at “Server: nginx”, but by observing behaviors:

  • What paths exist?
  • which respond with 200/301/401/403
  • What changes when you change the Host/Header/Method?

When the goal is only liveness (host up/down), don't get hung up on 80: do discovery first and then get into the application details.

Door Statuses: What “Open” Really Means #

In short: "open" indicates that the port is accepting connections, not that the service is vulnerable. The vulnerability arises from version + config + exposure + context.

bash
nmap -sS -Pn -p80 --reason --open 10.10.10.10
text
PORT   STATE SERVICE REASON
80/tcp open  http    syn-ack

You know that the 80 responds at the TCP level. Now you need to demonstrate that it speaks HTTP and with what features.

Common mistake: “80 open = vulnerable web.” False — fingerprint before drawing any conclusions.

Also keep in mind for UDP: “filtered” can hide a firewall/rate-limit (false negatives), and on UDP “open|filtered” is often just silence, not confirmation.

Port scanning: SYN scan, connect scan, UDP scan #

In short: SYN scan is fast and semi-open, connect scan is more compatible but noisy, and UDP is slow and ambiguous. The technique changes the type of evidence you get.

SYN scan (quick map of actually reachable TCP ports):

bash
nmap -sS -Pn -p- --min-rate 2000 --open 10.10.10.10
text
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http
445/tcp open  microsoft-ds

Common error + fix: aggressive scan and dirty results → lower --min-rate.

Connect scan (when you don't have raw privileges, e.g. container):

bash
nmap -sT -Pn -p80,443 --open 10.10.10.10

Common error + fix: different results between -sS e -sT → possible filtering; check with traffic capture.

UDP scan (DNS, SNMP, DHCP, NTP live here and disappear if you don't look for them):

bash
nmap -sU -Pn -p53,67,161 --open 10.10.10.10
text
PORT    STATE         SERVICE
53/udp  open|filtered domain
161/udp open|filtered snmp

Common error + fix: "open|filtered = definitely open" is false. Valid with dedicated probes.

HTTP Fingerprint: Beyond “Server: Apache” #

In short: out of 80, you need repeatable signals—server header, title, allowed methods, redirects. This provides the roadmap for targeted testing.

bash
nmap -sS -Pn -p80 -sV --script http-title,http-server-header,http-methods 10.10.10.10
text
80/tcp open  http    nginx 1.18.0
| http-title: Lab Panel
| http-server-header: nginx/1.18.0
| http-methods:
|   Supported Methods: GET HEAD POST OPTIONS
|_  Potentially risky methods: TRACE

Title and methods already say “role” (panel) and possible misconfig (TRACE enabled).

Se TRACE is among the supported methods, check it out — it is the basis of Cross-Site Tracing (XST), historically used to bypass HttpOnly on cookies by reading the request header reflected in the response:

bash
curl -X TRACE http://10.10.10.10 -H "Cookie: session=test123" -i

If the answer (200 OK with Content-Type: message/http) reflects the header Cookie that you sent, the method is actually usable and not just “listed”.

Common error + fix: -sV “wrong” version behind reverse proxy → switches to fingerprint for path and manual probe.

Quick alternative with curl (more convenient than nc for a quick check):

bash
curl -I http://10.10.10.10

With -I send a HEAD instead of a GET: same response headers, less traffic generated — useful for repeated banner grabbing without downloading the body each time.

Headers that should always be read, not just “Server”:

  • Server / X-Powered-By — technology stack (often deactivatable, if present it is already a sign of non-hardened configuration)
  • Set-Cookie — cookie name and flag (HttpOnly, Secure, SameSite): cookies without HttpOnly are readable by JS (XSS→theft risk), without Secure they also travel in the clear
  • Location — where it redirects you (often reveals internal application paths)
  • Cache-Control — if missing on pages with sensitive data, they may remain in shared caches

To roughly confirm what it actually responds to (without tools):

bash
printf 'HEAD / HTTP/1.1\r\nHost: 10.10.10.10\r\nConnection: close\r\n\r\n' | nc -nv -w 3 10.10.10.10 80
text
HTTP/1.1 302 Found
Server: nginx
Location: /login
Set-Cookie: session=...; HttpOnly

Redirect to login + session cookie: already a concrete application surface. Here the cookie has HttpOnly but not Secure: on a pure HTTP channel it is still interceptable in clear text.

Common error + fix: “400 Bad Request” response → missing Host: or correct CRLF formatting.

Virtual Host and Host Header: What the Reverse Proxy Hides #

In short: (In Italian only) a single IP out of 80 often serves multiple different applications based on the header HostIf you don't try different vhosts, you're missing out on half the surface.

On HTB it's almost the norm: admin.target.htb, api.target.htb They respond completely differently from the naked IP.

bash
gobuster vhost -u http://10.10.10.10 -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt --append-domain

Or manually, just changing the header:

bash
curl -H "Host: admin.target.htb" http://10.10.10.10

Change Host: It can cause a completely different application to appear from the same IP/port — this is normal behavior for a reverse proxy with multiple vhosts configured.

Common error + fix: gobuster vhost gives false positives on almost identical responses → use -fs/--exclude-length to filter the default size.

Enumeration: directories, panels, leakage #

In short: after fingerprinting, the question is which endpoints exist and what they reveal. You don't need endless bruteforce, you need high-leverage candidates (admin, API, backup, debug).

Instant checks, zero noise, before any brute force:

bash
curl http://10.10.10.10/robots.txt
curl http://10.10.10.10/sitemap.xml

robots.txt often lists paths that the owner wanted “hidden” from crawlers — not from a pentester.

bash
nmap -Pn -p80 --script http-enum 10.10.10.10
text
| http-enum:
|   /admin/: Possible admin folder
|   /api/:   Possible API endpoint
|_  /backup/: Directory listing may be enabled

It's not "pwn", it's a list of leads to check with targeted requests.

Common error + fix: silent script → possible WAF/redirect/vhost. Check first. / by hand and repeat.

For a more in-depth listing, http-enum This is just the starting point — a targeted brute force with ffuf or feroxbuster covers much more ground:

bash
ffuf -u http://10.10.10.10/FUZZ -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt -fc 404
bash
feroxbuster -u http://10.10.10.10 -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt

Common error + fix: too many false positives → filter by status code (-fc) or by response size, not by single word found.

WAF fingerprint , if the responses seem “strange” (generic block page, 403 on everything):

bash
wafw00f http://10.10.10.10

Knowing that there is a WAF (and which one) tells you whether to slow down the rate or change your evasion technique, before continuing to fumble around in vain.

Favicon hash , a modern technique to identify the application stack even behind a generic proxy:

bash
curl -s http://10.10.10.10/favicon.ico | md5sum

The hash (or MurmurHash used by Shodan) allows you to look up on Shodan/Censys exactly which product uses that favicon — useful when header and title don't say anything.

The 5 misconfigs out of 80 that become attack vectors #

In short: most of the 80 issues are incorrect configurations, not CVEs. A healthy test is: test → evidence → impact → fix.

1) Cleartext HTTP on internal network (sniffable credentials/sessions):

bash
sudo tcpdump -ni any host 10.10.10.10 and port 80 -A | head -n 40
text
POST /login HTTP/1.1
Host: 10.10.10.10

user=lab&pass=lab123

High-impact test: clear text credentials. Common error + fix: "I don't see anything" → wrong interface or traffic on 443, check routing.

Hardening: force HTTPS, HSTS to 443, redirect 80→443.

2) Directory listing/backup exposed:

bash
printf 'GET /backup/ HTTP/1.1\r\nHost: 10.10.10.10\r\nConnection: close\r\n\r\n' | nc -nv -w 3 10.10.10.10 80
text
HTTP/1.1 200 OK
Index of /backup/
- db.sql
- site.zip

Common error + fix: “403 therefore nothing” → false, a 403 can still confirm existence; compare different paths.

Hardening: disable autoindex, ACLs on directories, remove backups from docroot.

3) “Open” reverse proxy towards internal services:

bash
printf 'GET /internal/ HTTP/1.1\r\nHost: 10.10.10.10\r\nConnection: close\r\n\r\n' | nc -nv -w 3 10.10.10.10 80
text
HTTP/1.1 200 OK
X-Upstream: 127.0.0.1:8080

A path that bridges to a backend makes the 80 an application pivot.

Hardening: upstream allowlist, sensitive path blocking, segmentation.

4) Missing security headers (not a direct exploit, but a hardening finding that should always be reported):

bash
curl -I http://10.10.10.10 | grep -iE "strict-transport|content-security|x-frame|x-content-type|referrer-policy"

If grep returns nothing, you are missing Strict-Transport-Security, Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, Referrer-PolicyTheir absence is not a direct vulnerability, but it is a legitimate finding: it opens the door to clickjacking (without X-Frame-Options) or downgrade attacks (without HSTS).

5) .git exposed (very popular on HTB — downloadable sources and repo history):

bash
curl -s -o /dev/null -w "%{http_code}" http://10.10.10.10/.git/HEAD

If it returns 200, the repo is reachable. Download and extract with:

bash
git-dumper http://10.10.10.10/.git/ ./dumped-repo

Interpretation: History, commit, and config files often end up with hardcoded credentials or secrets in old commits even if they were removed from the latest release.

Hardening: remove .git from docroot in production, never deploy directly from working copy.

Two HTTP attacks that deserve a separate article #

In short: on 80, in addition to the misconfigs seen above, there are two classes of attacks that depend directly on how headers and caches are handled — too broad for a box here, but directly related to what you just enumerated.

If you notice cache headers during fingerprinting (Cache-Control, X-Cache, Age) on a reverse proxy, the service is potentially exposed to web cache poisoning: injecting non-canonicalized headers (X-Forwarded-Host, unkeyed parameters) you can cache a malicious response for all subsequent users. Operational insight: Cache Poisoning: A Complete Guide.

If the target is behind a reverse proxy/load balancer (very common on 80) and you notice inconsistencies between how the front-end and back-end parse Content-Length/Transfer-Encoding, you are in the territory of theHTTP Request Smuggling — bypassing access controls and cache poisoning "upstream." Operational insight: HTTP Request Smuggling: A Complete Guide.

Why the “door → attack” map also counts outside of 80 #

In short: an open port is a hook: it tells you which protocol to use and what errors to look for. Quick examples on SMB/FTP/SSH/RDP.

  • SMB445 — non-destructive check for MS17-010: nmap -Pn -p445 --script smb-vuln-ms17-010 10.10.10.10A “VULNERABLE” is a patching priority, not a license for out-of-scope exploitation.
  • FTP 21 nmap -Pn -p21 --script ftp-anon 10.10.10.10 Check if anonymous login reads directories (classic data exposure).
  • SSH 22 nmap -Pn -p22 -sV --script ssh-hostkey,ssh2-enum-algos 10.10.10.10 valid config and crypto policy, no need to “shoot dictionaries”.
  • RDP3389 nmap -Pn -p3389 -sV 10.10.10.10 Exposure confirmation; public RDP is already a risk finding.

Tools: Nmap, Masscan, Netcat #

In short: Nmap gives quality and context, Masscan speed over range, Netcat manual control over the protocol.

bash
# Nmap: qualità e ripetibilità
nmap -sS -Pn -p80,443,22,445 --open -sV --reason 10.10.10.10

# Masscan: velocità su un range in lab
sudo masscan 10.10.10.0/24 -p80 --rate 1000

# Netcat: verità grezza sul protocollo
printf 'GET / HTTP/1.1\r\nHost: 10.10.10.10\r\nConnection: close\r\n\r\n' | nc -nv -w 3 10.10.10.10 80

Masscan quickly tells you “who has 80 open” on a range; Nmap does the quality work afterward.

Automatic scanners for an initial burst of signals without writing requests by hand:

bash
whatweb -a 4 10.10.10.10
nikto -h http://10.10.10.10
nuclei -u http://10.10.10.10 -t nuclei-templates/

whatweb identify tech stack and CMS in one go; nikto finds common known/misconfig files but is noisy (not on sensitive out-of-scope targets); nuclei applies thousands of community templates — if it detects WordPress/Joomla, it switches to wpscan/joomscan for CMS-focused enumeration.

Practical Scenario: From "80 Open" to Highlight in 4 Steps #

Target 10.10.10.10, objective: Identify the service and find 1-2 high-leverage endpoints.

bash
sudo masscan 10.10.10.10 -p80 --rate 500
nmap -sS -Pn -p80 -sV --script http-title,http-server-header,http-methods 10.10.10.10
nmap -Pn -p80 --script http-enum 10.10.10.10
printf 'HEAD / HTTP/1.1\r\nHost: 10.10.10.10\r\nConnection: close\r\n\r\n' | nc -nv -w 3 10.10.10.10 80

Expected result: status code, Server: header, title and at least 1 interesting path (/login, /admin, /api, /backup).

Operational checklist #

  • Confirmation 80/tcp open with --reason.
  • Separate discovery (ports) from enumeration (script/HTTP).
  • Extract at least 3 signals: status, Server/header, title.
  • Check the allowed methods (be careful with TRACE).
  • Check it out robots.txt/sitemap.xml e .git/HEAD before any brute force.
  • Try at least 1 alternative vhost by changing the header Host.
  • Run whatweb/nikto/nuclei for a first round of automatic signals.
  • Run http-enum + ffuf/feroxbuster for high probability paths.
  • Check for missing security headers (HSTS, CSP, X-Frame-Options).
  • Validate manually / and 1-2 paths with minimal HTTP request.
  • If you suspect WAF/filtering, reduce rates, try wafw00f and check with tcpdump.
  • Don't confuse proxy version with app version.

Counterintuitive concepts #

  • “80 open = normal site” —it's often an exposed proxy or internal panel. Treat it as a gateway, not a homepage.
  • “Server header = real version of the app” —says little about the app behind a proxy. Application signals (path, redirect, cookies) are required.
  • “UDP open|filtered = open” — Silence is normal on UDP, validation with a probe is needed.
  • “403 = there is nothing” — A 403 can confirm that the endpoint exists, only protected. Compare different paths.

FAQ #

If I see 80 open, where do I start? Confirmation open with --reason, then fingerprint (http-title/http-server-header/http-methods), then http-enum, then manual request with nc.

Why -sV does he sometimes get the version wrong? Because there's often a reverse proxy on 80. Use headers, redirects, and paths for the actual application fingerprint.

How do I tell the difference between a proxy and a direct app? Compare headers and redirects between different paths; if possible, check with a traffic capture tool.

When does Masscan make sense instead of Nmap? When you just need to quickly find out who's exposing 80/443 on a range. Then you switch to Nmap for the details.

Why does the same IP on 80 show different apps? Why a reverse proxy routes based on the header Host, not just on IP/port. Change Host: (manually or with gobuster vhost) reveals hidden vhosts.

Authoritative references #

#http #port 80

leave a message

I'm not a robot