9.2.10 HTTP and Web Application Mapping
← Stage index · Quick sheet · Mechanics | Strategy map | Study methods: Map useful web behavior
Use when: an HTTP(S) endpoint must become a route, request, role, object and input map before exploitation.
Enter with:
SOURCE -> TARGET | tcp PORT | HTTP/TLS evidence | hostname clues | coverage limit.
9.2.10.1 Baseline the application identity
curl -skL -D headers.txt -o body.html http://TARGET:PORT/
curl -sk -o /dev/null -w 'code=%{http_code} bytes=%{size_download} type=%{content_type} redirect=%{redirect_url}\n' http://TARGET:PORT/
Decisive output: record the scheme, hostname/
Hostheader, port, redirects, page title, certificate names, server/framework clues and whether the view is anonymous or authenticated.
9.2.10.1.1 Variant — explicit virtual-host candidate
curl -sk -H 'Host: CANDIDATE.DOMAIN' http://TARGET:PORT/
Compare it with a random hostname. A different status alone is weak evidence; compare body, length, title and redirects.
9.2.10.1.2 Variant — preserve cookies and follow redirects
curl -skL -c cookies.txt -b cookies.txt http://TARGET:PORT/PATH
Use a separate cookie jar per identity. Do not mix anonymous, ordinary-user and administrator evidence.
9.2.10.1.3 Variant — replay through Burp Community
curl -sk -x http://127.0.0.1:8080 http://TARGET:PORT/PATH
Confirm the proxy listener is active on 127.0.0.1:8080. Use -k only for the controlled lab because it disables destination-certificate verification.
9.2.10.2 Map the application's features, roles and working requests Manual behavior map
For every visible function, capture one unchanged request in Burp Proxy history, send it to Repeater and record:
METHOD PATH | CONTENT-TYPE | ACCESS CONTEXT/ROLE
INPUT LOCATION + NAME | BASELINE VALUE
STATUS | LENGTH/HASH | REDIRECT | MARKER/ERROR/TIME
OBJECT/FUNCTION SELECTED | NEXT ONE-VARIABLE TEST
Check login/registration/reset, profiles/objects, search/filter/pagination, download/export/preview, upload/import, administration and every JavaScript API call.
Next: a browser-side restriction is not server authorization. Replay the raw request and change one field, object reference, method or access-context element at a time.
9.2.10.3 Inspect exposed artifacts
curl -sk http://TARGET:PORT/robots.txt
curl -sk http://TARGET:PORT/sitemap.xml
curl -sk http://TARGET:PORT/.git/HEAD
curl -sk http://TARGET:PORT/openapi.json
curl -sk http://TARGET:PORT/swagger.json
Also inspect HTML comments, hidden inputs, form actions, linked JavaScript, route strings, source-map references, cookies and response headers.
Decisive output: a path, parameter, API schema, object identifier, component or secret-bearing artifact that creates a specific next request. Source disclosure is not command execution.
9.2.10.4 Discover files and directories
Request a random nonexistent path first and record its status, length and body marker.
gobuster dir -u http://TARGET:PORT/ -w /usr/share/wordlists/dirb/common.txt -t 10 -o gobuster-root.txt
Decisive output: manually verified routes including useful
200, redirect,401,403and405responses.
9.2.10.4.1 Variant — technology-aware extensions
gobuster dir -u http://TARGET:PORT/ -w WORDLIST -x php,txt,bak,old,zip -t 10 -o gobuster-ext.txt
Choose extensions from observed stack evidence; do not spray every extension.
9.2.10.4.2 Variant — authenticated discovery
gobuster dir -u http://TARGET:PORT/ -w WORDLIST -c 'SESSION=VALUE' -H 'Authorization: Bearer TOKEN' -t 10 -o gobuster-auth.txt
Use only the cookie or header that applies. An expired session can turn every result into the same login redirect.
9.2.10.4.3 Variant — filter a confirmed wildcard body length
gobuster dir -u http://TARGET:PORT/ -w WORDLIST --exclude-length NOISE_LENGTH -t 10 -o gobuster-filtered.txt
Filtering without first confirming the noise response can hide a real path.
9.2.10.5 Discover virtual hosts
gobuster vhost -u http://DOMAIN:PORT/ --append-domain -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -o vhosts.txt
Alternative with automatic calibration:
ffuf -w WORDLIST -u http://TARGET:PORT/ -H 'Host: FUZZ.DOMAIN' -ac -o ffuf-vhosts.json
Failure cue: uniform status/length may be the default vhost. Compare each candidate with a random host header before adding it to the application map.
9.2.10.6 Discover parameters and object values
GET parameter names:
ffuf -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt -u 'http://TARGET:PORT/PATH?FUZZ=test' -ac -o params-get.json
POST form parameter names:
ffuf -w WORDLIST -u http://TARGET:PORT/PATH -X POST -H 'Content-Type: application/x-www-form-urlencoded' -d 'known=value&FUZZ=test' -ac -o params-post.json
Object values with an authenticated API:
ffuf -w NUMBERS -u 'http://TARGET:PORT/api/objects/FUZZ' -H 'Authorization: Bearer TOKEN' -mc all -fc 404 -o object-values.json
Decisive output: a manually reproduced parameter or value that changes application behavior. Tool outliers are candidates, not confirmed access-control flaws.
9.2.10.6.1 ffuf — preserve a captured authenticated request
Save a working raw request from the proxy as request.txt, retain its Host/cookie/body, and put FUZZ at the single parameter name/value or path being tested. Replay it once manually first. The request file does not specify TLS: choose the transport explicitly.
9.2.10.6.2 HTTPS request, including its original method and session headers
# HTTPS request, including its original method and session headers
ffuf -request request.txt -request-proto https -w WORDLIST -mc all -ac -t 10 -o request-https.json
9.2.10.6.3 Plain HTTP request: otherwise ffuf defaults to HTTPS
# Plain HTTP request: otherwise ffuf defaults to HTTPS
ffuf -request request.txt -request-proto http -w WORDLIST -mc all -ac -t 10 -o request-http.json
Read: compare an outlier's status/length/body with a known missing value, then replay that exact request. A login redirect for every value → refresh the session before continuing. A one-time CSRF token → repair token handling; the saved-request flag does not refresh it automatically.
9.2.10.7 Map API methods, schema and authorization
curl -ski http://TARGET:PORT/api/v1/PATH
curl -ski -X OPTIONS http://TARGET:PORT/api/v1/PATH
curl -ski -X POST -H 'Content-Type: application/json' -d '{"username":"TEST_USER","password":"TEST_PASSWORD"}' http://TARGET:PORT/api/v1/login
Interpretation:
405can establish that a route exists but rejects the method. Validation errors can reveal required fields. A token establishes only the authorization demonstrated by a later request.
Build a matrix across anonymous, user A, user B and administrator contexts where available:
PATH | METHOD | IDENTITY/ROLE | OBJECT/PROPERTY | RESULT | NEXT
9.2.10.8 Continue with the capability your result enables Exit and handoffs
Exit condition: each interesting function has a baseline request, access context, controllable input, expected result, observed difference and cheapest next test.
- file/path selector -> file handling attacks;
- shell/diagnostic or database-backed input -> command and SQL injection;
- object/role/property or browser-script context -> access control and XSS;
- product/plugin/version exploit candidate -> Block 6 public-exploit adaptation;
- new credential -> Block 5 credential handling and authenticated re-enumeration;
- verified server command execution -> Block 7 session handling.
9.2.10.9 wfuzz alternative for paths and form values
Use when wfuzz is the available/familiar client for the same controlled-response test. Choose a nonexistent control first; preserve the actual Host and authenticated session.
9.2.10.9.1 Paths; hiding 404s is appropriate only after checking the site's failure behavior
# Paths; hiding 404s is appropriate only after checking the site's failure behavior
wfuzz -c -z file,WORDLIST --hc 404 -u 'http://TARGET:PORT/FUZZ'
9.2.10.9.2 A form value in a working authenticated request
# A form value in a working authenticated request
wfuzz -c -z file,WORDLIST -b 'session=COOKIE' \
-d 'name=FUZZ' --hc 404 -u 'http://TARGET:PORT/PATH'
Read: status/length/body outliers need manual replay. Uniform redirects, wildcard bodies or expired cookies → fix the response/session controls before expanding the list. The presence of an outlier is not a vulnerability result.
Sources: upstream 1.
9.2.10.10 HTTP proxy variables — control which client request goes through Burp
Use when a client honors HTTP proxy environment variables. Keeping them on a single invocation avoids accidentally proxying later unrelated traffic.
9.2.10.10.1 http_proxy=http://127.0.0.1:8080 https_proxy=http://127.0.0.1:8080 \
http_proxy=http://127.0.0.1:8080 https_proxy=http://127.0.0.1:8080 \
curl -i http://TARGET:PORT/PATH
9.2.10.10.2 Explicit proxy and empty bypass list for a request that otherwise skips the proxy
# Explicit proxy and empty bypass list for a request that otherwise skips the proxy
curl --proxy http://127.0.0.1:8080 --noproxy '' -i http://TARGET:PORT/PATH
Read: confirm the request in Burp history before trusting the replay. HTTP proxy settings do not tunnel arbitrary SMB/Kerberos traffic. For HTTPS, the client's certificate trust still matters; distinguish a local proxy/TLS error from an application response.
Sources: upstream 1.
9.2.10.11 Extract candidate paths from a downloaded JavaScript file
Use after reading an actual application JS file. This is a quick string candidate pass; it does not execute the script or understand its routing logic.
curl -f http://TARGET:PORT/PATH/app.js -o app.js
python3 -c 'import re; print("\n".join(sorted(set(re.findall(r"/[A-Za-z0-9_./-]+",open("app.js").read())))))' > js-paths.txt
Read: inspect the list and surrounding source for the correct hostname, API prefix, method, parameter names and required session. Comments, regular expressions and third-party URLs can create false candidates. Replay an observed function before turning strings into a fuzzing list; remove anything outside the assigned scope.
Sources: upstream 1.
9.2.10.12 Sources
Supplied PEN-200 Ch 8, pp201-231; Hexdump web modules; Burp Proxy; curl; Gobuster; ffuf.