Professional web recon
Runningnmap to map a web application is like doing surgery with
a traffic radar. Nmap discovers port 443 is open — you already
know that, there’s a website. To map a corporate monolith’s real
attack surface, you need to behave exactly like a legitimate user.
This page covers professional recon without raising alarms:
passive recon, silent fingerprinting, type confusion, JA3 and
Client Hints evasion. Full methodology with decision tree at
/en/methodology.
Why Nmap won’t help here
The server sits behind a WAF, a CDN and an API
Gateway. What Nmap touches is the first shield, not the brain.
Layer 0 — Absolute passive recon (zero contact)
You send not a single packet to the client’s server. All info is public.Wayback Machine
Domain URL history. Obsolete endpoints developers forgot to delete and that no longer pass current WAF rules./api/v1/auth(old version without rate limit)/old/admin/login.php(legacy panel not migrated).env,.git/config,backup.sql(accidental uploads)
Certificate Transparency
Every issued cert is published in public logs. SANs are a subdomain goldmine.staging.empresa.com,dev.empresa.com,qa.empresa.comvpn.empresa.com,mail.empresa.com- Internal subdomains accidentally leaked
(
internal-api.empresa.com)
Google / Shodan / Censys dorking
GitHub: abandoned secrets
The first place a modern attacker looks.Layer 1 — Frontend analysis (DevTools, not scanner)
Your dev knowledge makes the difference. The browser does the dirty work, not a scanner the WAF would detect.React/Angular/Vue source maps
If the dev team pushed*.map to production (they do 30% of
the time), you have the original unminified source.
JS bundles: find endpoints, tokens, comments
Even without source maps, minified bundles contain hardcoded API routes, forgotten dev tokens, comments, and feature flags.- Internal endpoints:
/api/v2/internal/users,/admin/debug - Active feature flags:
enable_legacy_auth: true - Forgotten dev Stripe/Mailgun/Sendgrid tokens
- Comments with TODOs and warnings
robots.txt, sitemap.xml, .well-known
The house gifts. Almost always reveal internal routes.Layer 2 — Proxied browsing (passive Burp)
Configure Burp Suite or OWASP ZAP as intermediary and browse manually. Create account, use the app, fill forms with coherent data. 🎯 Goal in this phase is NOT to attack. It’s to:- Map the real directory tree (browser-visible is a fraction).
- Capture all endpoints and HTTP verbs in use.
- Dissect session tokens (JWT, cookies).
- Identify susceptible parameters (numeric IDs, paths, redirects).
Minimum stealth Burp config
Layer 3 — Backend fingerprint (without firing WAF)
After passive browsing, you know tokens, endpoints and structure. Time to identify backend language and framework.Extensions are dead
No modern corporate app exposes file type in URL. Forget about.php or .aspx — clean routing shows /api/v1/auth and nothing
else.
Fingerprint by session cookies
Languages have default names. If the team didn’t rename them (usually they didn’t), you have the fingerprint without sending anything.Fingerprint by headers
Fingerprint by error anatomy (the king technique)
If headers are stripped and cookies obfuscated, force a controlled error. You’re not injecting anything — you want the backend parser to trip.Type Confusion
API expects a string. Send another type.HTTP verb tampering
405 Method Not Allowedwith JSON body{"error":"..."}→ modern well-configured framework.405with HTML error → could be Apache/Tomcat default page.500with stack trace → framework didn’t expect that verb and vomits.
Structural corruption
JSON with extra comma, missing brace, alternate encoding.Layer 4 — What modern WAFs see (and how to evade)
The WAF doesn’t only check your IP. It identifies you across multiple synchronized layers. Faking one tells on you.The IP-block myth
Imagine you change IP via VPN after first block. The WAF blocks you instantly again. Why?- Identical session cookie — The WAF tracks the user, not just the network.
- Identical JA3 fingerprint — Your Python/curl has a unique TLS signature. Changing IP doesn’t change this.
- Distributed attack pattern — 50 different IPs with same JA3 = coordinated attack, max priority.
JA3/JA4: client crypto fingerprint
The TLS handshake (Client Hello) includes supported algorithm and extension list. Each client has a unique signature.Client Hints (sec-ch-ua-*)
Chromium browsers send asec-ch-ua-* block describing brand and
platform. If your User-Agent says Chrome 120 but you don’t send
these, the WAF detects asymmetry.
Header structural order
Real browsers assemble HTTP requests in rigid order. Libraries (Pythonrequests, Go net/http) order them
alphabetically or randomly.
🛡️ Solution: use tools that respect order (tls-client,
curl-impersonate, real browsers).
Geo-blocking and ASN
If the client only allows Spanish IPs, just changing AWS region isn’t enough:
🛡️ Professional solution: legal residential proxies
(Bright Data, Oxylabs). Your traffic comes from real residential
routers in Spain.
Passive browser biometrics
The login page loads JavaScript (reCAPTCHA v3, Cloudflare Turnstile, DataDome) that records in real time:- Mouse trajectory (human = imprecise logarithmic curves).
- Typing dynamics (human = irregular ms between
keydownandkeyup). - Hardware events (real key presses, not direct DOM injection).
password = "123456" in the DOM in 0 ms,
without keyboard events. The JS detects the ghost.
🛡️ Solution:
- Real browser with
playwright-stealthorundetected-chromedriver. - Mouse motion simulation with Bézier curves.
page.type()with realistic delays instead ofpage.evaluate(() => input.value = ...).
Layer 5 — When the wall is smooth (no info leak)
When no error reveals tech, the dev team is competent. Change attack plane — don’t insist on fingerprinting.Timing attacks
Response time is a tell no global exception handler can hide.Endpoint archaeology
Old non-migrated versions:Mass Assignment (the goldmine)
Without knowing tech, try injecting extra fields in legit JSON:/profile if account
got new attributes.
Systematic IDOR
Any endpoint taking an ID:200, IDOR confirmed.
How to harden your own backend against this recon
If you’re defending instead of auditing:1. Global exception handler
Never let the framework leak the stack trace.2. Strip revealing headers
3. Rename session cookies
4. Aggressive rate limiting on fingerprint endpoints
Related resources
- Tactical glossary — Type Confusion, JA3, Mass Assignment, IDOR.
- Professional methodology — Full web decision tree.
- Report template — How to report recon findings in the report.
- Learning resources — PortSwigger Academy is the reference for all this.