OSCP Reference

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/Host header, 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, 403 and 405 responses.

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.

ffuf request configuration.

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: 405 can 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.

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.


Top of document · Reference home