Reconnaissance
Before you test anything, you map what is there. This lesson turns the practice environment into an accurate, in-scope inventory of attack surface: what an attacker can learn about an organisation without touching it, what careful probing of in-scope hosts reveals, how to organise it into a target list and a service matrix with evidence, and how a defender sees you doing it.
By the end you can
- Tell passive from active reconnaissance, and say what each one touches
- Describe the public sources that reveal an organisation's footprint, and why defenders should run the same discovery against themselves
- Read what host discovery, a port and service scan and a service banner show you, and what each one does not prove
- Build a target list and a service matrix from the findings, with timestamps and evidence
- Explain how reconnaissance shows up in a defender's logs, and why so much of it is missed
The everyday picture
Think of a quiet shop on a busy street. Long before anyone touches the door, a person across the road can learn a lot just by standing there. The opening-hours sign. The name on the delivery van. A "staff wanted" poster that names the till software. The brand of the alarm box bolted to the wall. The side gate someone left propped open. None of that needs stepping inside, and the shop has no way to know anyone looked.
Then someone walks up and gently tries each door handle, reads the notices taped inside the window, and notes which lights are on. That takes contact. A watchful owner might notice. Good reconnaissance is both halves of this, in order: learn everything you can from a distance first, then confirm the rest with careful, in-scope contact. And the most useful lesson for defenders is that they should walk their own street and try their own handles, because an attacker already does.
An accurate inventory, not a pile of noise
Attack surface is everything an attacker could reach or learn from. Reconnaissance is the phase where you map it. The goal is not to collect as much data as possible. A dump of fifty thousand lines helps no one. The goal is an accurate, in-scope inventory: a short list of the hosts, services and endpoints that actually exist, each one confirmed and tied to evidence. Everything you do next, in Attacking web applications and Attacking networks and services, starts from this inventory, so a wrong or padded one wastes the whole engagement.
Reconnaissance lives inside the scope and the rules of engagement you agreed in Ethics, law and scoping. Recon is the phase most likely to drift out of scope, because public data and DNS names happily point you at systems you were never authorised to touch. Sharing a company name is not authorisation. The discipline is simple: map broadly from public data, but only send traffic to the ranges and hosts your rules of engagement list, and park anything else as a note to confirm with the client.
Quick check
While mapping the in-scope practice network you find a login page on a subdomain that resolves to an IP outside the ranges in your rules of engagement. What should you do?
Recon routinely surfaces systems you are not authorised to touch. A shared name or a plausible purpose is not permission, and scanning or reporting on an out-of-scope host can be both unlawful and a breach of the engagement. Record it, and let the client decide whether to widen scope.
Passive recon: what an attacker learns without touching you
Passive reconnaissance reads what is already public and sends nothing to the target's own servers. The target has no way to notice. The point for a tester is that an attacker starts here, for free, so you should know what it reveals. These are the main sources, described as what they show you rather than how to harvest them at scale:
- DNS records. The public naming system maps names to addresses and lists mail, text and name-server records. It sketches the shape of an organisation's estate and often names hosts like
vpn,mailorlegacythat hint at what they are. - Certificate transparency logs. Certificate transparency logs record almost every TLS certificate issued on the public web. Searching them for a domain lists subdomain names the organisation may have long forgotten, including staging and admin hosts that were never meant to be found.
- Public code and leaked secrets. Public code repositories, paste sites and misconfigured storage sometimes hold source code, internal host names, API paths and, worst of all, credentials or keys committed by mistake.
- Job adverts and tech talks. A hiring post that asks for experience with a particular database, cloud or framework quietly tells you the stack. Conference talks and engineering blogs do the same.
- Archived pages. Web archives keep old copies of pages, so a parameter, path or admin link that was removed from the live site can still be read in last year's snapshot.
Because an attacker can do all of this silently, the defender's answer is to do it first. Attack surface management means an organisation runs this same discovery against itself on a schedule, finds the forgotten staging box and the stale DNS record, and retires them before someone else finds them. You cannot un-publish a certificate transparency log or scrub every archive, so the realistic defence is to own less surface, not to hide it.
Quick check
Which of these is passive reconnaissance, learned without sending a single packet to the target's own servers?
Certificate transparency logs are held by third parties, so reading them tells the target nothing. The other three all send traffic to the target's systems, which makes them active: they can be rate-limited, blocked and logged.
OSINT for people, only within scope
OSINT for people means the public facts about staff: names, roles, email patterns and public posts. It matters for one reason only, and it is a sensitive one. If, and only if, your rules of engagement authorise social engineering, this is how a phishing or pretext scenario is scoped and made realistic. If they do not, people are out of bounds.
Handle it with care even when it is allowed. Collect the minimum you need for the agreed scenario, keep it to work-related, public information, and never target someone's private life or family. The report should justify the tie to the test, not read like a dossier. The methodology bodies that structure this work, such as the Penetration Testing Execution Standard, treat intelligence gathering about people as a bounded, authorised activity, not an open invitation.
Active recon: what the tools show you
Active reconnaissance sends traffic to in-scope hosts to confirm what is really there. Each tool answers one question, and each has a limit worth saying out loud.
- Host discovery asks "which addresses in this range are alive?" A host discovery sweep turns a block of addresses into a short list of responding hosts. Its limit: a host that drops the probe type you used can look dead when it is not.
- Port and service enumeration asks "on a live host, which services are listening, and what are they?" A port scanner lists open ports, and a service scan guesses the protocol and software on each. Its limit: a firewall can hide, filter or fake ports, so an open-looking port is a lead, not a fact.
- Service banners. Many services announce themselves. A service banner may name the web server, database or mail software and a version. That one line is valuable because a known version points at known weaknesses to check later. Its limit: banners can be absent, trimmed, wrong or deliberately faked, so you confirm the real version by behaviour before you ever claim a vulnerability.
- Web content discovery asks "what paths, endpoints and parameters does this web app have that are not linked from the home page?" Web content discovery requests likely names and reads the responses to find admin areas, backup files, API routes and query parameters. Its limit: it is noisy, and a wordlist finds only names someone thought to list.
- Fingerprinting asks "what framework or product built this?" Response headers, cookie names, error pages and file layouts often reveal the framework, so you test the right class of weakness in Attacking web applications.
Active recon is where the rules of engagement bite hardest. Respect the rate limits in the agreement, because a fast scan can knock over a fragile service, and a denial of service you did not intend is still one you caused. Spread requests out, run inside the agreed window, and keep your source address and tooling consistent so the blue team can tell your traffic apart from a real attacker's later.
Quick check
A scan of an in-scope host returns a service banner reporting an old web-server version. What is the right next step?
A banner is a hint, not proof: administrators routinely change or suppress them, and a reverse proxy can report something other than the real software. Reporting on the string alone produces false findings. Firing exploits is not reconnaissance and may breach the rules of engagement; confirm first, exploit later and only in scope.
From data to an inventory: the target list and the service matrix
Raw output is not an inventory. Two artefacts turn it into one. A target list is the confirmed, in-scope hosts, each with the name you reached it by and how you confirmed it is live. A service matrix is a table of those hosts against the services found on them: the port, the protocol, the software and version seen, and a one-line note on why it matters. The matrix is what you prioritise from, because the host exposing a database or an admin panel usually offers a higher-impact path than the one running a single patched service.
Think of the whole phase as a funnel. You start from a few seeds, such as a domain and an organisation name, widen to the hosts in scope, then to the services on them, then to the endpoints inside a web service, filtering at every step to what the rules of engagement allow. Keep evidence as you go: the command or query run, the raw response, and a timestamp. Timestamps are not bureaucracy. They keep you provably inside the agreed window, let the blue team match your activity to their logs in Reporting that gets things fixed, and make every finding reproducible.
How defenders see recon, and why they miss it
Recon is not invisible, but it is quiet, and knowing the signals helps you test fairly and helps a blue team catch the real thing. On the active side, a defender can see a spike in DNS lookups for their own names, a classic port-scan pattern where one source touches many ports or many hosts in a short time, a burst of 404 Not Found responses in the web logs as a content scanner walks a wordlist, and an unusual or repeated user agent string. Writing detections turns these into alert rules.
So why is so much recon missed? Three reasons. Most of the first phase is passive, so there is simply nothing in the target's logs to see. The active part is often shaped to blend in: spread thin over hours, from ordinary-looking addresses, at a pace that hides inside normal traffic. And many teams drown the signal, with scan noise so constant that no one tunes an alert for it. For a tester this is why consistent, logged, in-scope behaviour matters: it lets the defender reconstruct exactly what you did, which is the point of the engagement, not a quiet win.
Build it
Turn the practice environment into a scoped inventory you could hand to the next phase and to the client's blue team.
Pin the scope in front of you first
Before any contact, write the in-scope ranges, the out-of-scope exclusions, the rate limit and the window where you can see them. Everything active you do is checked against this.
OutputIn scope: 10.10.5.0/24 (practice Partner app + lab store network) Out of scope: anything resolving outside that range; staff personal accounts Rate: max 20 requests/second per host; no stress testing Window: weekdays 09:00-17:00; blue team notifiedRun the passive pass and record seeds
Collect only public data: DNS records, certificate transparency hits, public repositories, job adverts, archived pages. Note each host you learn about and whether it falls in scope.
Markdown# Passive findings (no traffic sent to the target) - CT logs: partner, staging-partner, admin-partner (confirm which are in scope) - DNS: mail, vpn, legacy-store (vpn, legacy-store out of range) - Public repo (Lagoon Digital sample): path /partner/api/v2 - Job advert: NestJS + PostgreSQL + Redis - Web archive: old /partner/export?report= parameterRun the active pass inside scope and rate limits
Discover live hosts in range, then enumerate services and read banners. Capture the port, protocol, software, version and a timestamp for each.
Build the service matrix
One row per service on each in-scope host. The "why it matters" column is what you will prioritise from.
Markdown| Host | Service (port) | Version | Why it matters | |--------------|----------------|--------------|--------------------------------| | 10.10.5.11 | HTTPS (443) | nginx 1.24 | Partner app login, web surface | | 10.10.5.12 | Postgres (5432)| PostgreSQL 16| DB reachable from app subnet | | 10.10.5.13 | Redis (6379) | Redis 7.2 | No auth seen, highest priority | | 10.10.5.14 | Admin UI (8080)| Grafana 10.1 | Check for default login |Keep an evidence log with timestamps
One structured line per confirmed finding, so each is reproducible and provably inside the window. Store raw responses alongside it; never store anything out of scope.
JSON{"at": "2026-10-20T10:14:03Z", "host": "10.10.5.13", "port": 6379, "method": "service scan", "finding": "redis banner, no auth prompt", "in_scope": true, "evidence": "banners/10.10.5.13-6379.txt"}Hand the funnel on
Deliver the target list and service matrix as the input to the next phases, and share your source address, tooling and window with the blue team so they can separate your traffic from a real attacker's.
Bring it to your team
Ask these at the recon kickoff, whether you are the tester or the defender reviewing a test.
- Exactly which ranges and hosts are in scope, and what is explicitly excluded?
- Does the engagement authorise OSINT on people and social engineering, or are staff out of bounds?
- What is the rate limit, and which services are fragile enough to need a gentler pass?
- How are we recording evidence and timestamps so every finding is reproducible?
- Have we run this same passive discovery against ourselves, and retired what we found?
- Which of our recon detections would fire on this activity, and who would see the alert?
Red flags
- A scan range copied from DNS results without checking it against the rules of engagement.
- A vulnerability claimed from a banner alone, with no behavioural confirmation.
- Recon findings with no timestamps, so nobody can tell when or whether they were in scope.
- A full-speed scan against a production-like service with no agreed rate limit.
- An organisation that has never run attack surface discovery against itself.
Practice
Build the service matrix from raw scan data
The table recon_host holds one row per open service your in-scope scan confirmed: the host ip, the port, the service name and the version string. Summarise it into a host-level service matrix. For each ip return open_services (how many services it exposes) and sensitive_services (how many of them are a database or admin service, meaning the service is one of postgres, redis, mysql, mongodb or admin). Order the most exposed hosts first: by sensitive_services highest first, then open_services highest first, then ip.
CREATE TABLE recon_host (id int PRIMARY KEY, ip text, port int, service text, version text); INSERT INTO recon_host VALUES (1, '10.10.5.11', 80, 'http', 'nginx 1.24.0'), (2, '10.10.5.11', 443, 'https', 'nginx 1.24.0'), (3, '10.10.5.11', 22, 'ssh', 'OpenSSH 9.6'), (4, '10.10.5.12', 443, 'https', 'nginx 1.24.0'), (5, '10.10.5.12', 22, 'ssh', 'OpenSSH 9.6'), (6, '10.10.5.12', 5432, 'postgres', 'PostgreSQL 16.2'), (7, '10.10.5.13', 5432, 'postgres', 'PostgreSQL 16.2'), (8, '10.10.5.13', 6379, 'redis', 'Redis 7.2'), (9, '10.10.5.13', 22, 'ssh', 'OpenSSH 9.6'), (10, '10.10.5.14', 22, 'ssh', 'OpenSSH 8.2'), (11, '10.10.5.14', 8080, 'admin', 'Grafana 10.1'), (12, '10.10.5.15', 22, 'ssh', 'OpenSSH 9.6');
-- One row per host: open_services and sensitive_services, most exposed first
SELECT ip, count(*) AS open_services
FROM recon_host
GROUP BY ip;
[{"ip": "10.10.5.13", "open_services": 3, "sensitive_services": 2},
{"ip": "10.10.5.12", "open_services": 3, "sensitive_services": 1},
{"ip": "10.10.5.14", "open_services": 2, "sensitive_services": 1},
{"ip": "10.10.5.11", "open_services": 3, "sensitive_services": 0},
{"ip": "10.10.5.15", "open_services": 1, "sensitive_services": 0}]
Show a solution
SELECT ip,
count(*) AS open_services,
count(*) FILTER (WHERE service IN ('postgres','redis','mysql','mongodb','admin'))
AS sensitive_services
FROM recon_host
GROUP BY ip
ORDER BY sensitive_services DESC, open_services DESC, ip;The FILTER clause counts only the rows whose service is sensitive, next to the plain count(*) of all services. Ordering by sensitive services first puts 10.10.5.13 (a Postgres and an unauthenticated Redis) at the top, then the two hosts with one sensitive service each, and leaves the web-and-SSH and SSH-only hosts last. That order is your testing plan: highest-impact exposure first.
Sort the findings: passive or active, in or out of scope
Your engagement is scoped to 10.10.5.0/24, and social engineering is not authorised. For each of these five actions, say whether it is passive or active, whether it is in scope, and in one line what you would do. Then name which single confirmed service you would test first and why.
- Searching certificate transparency logs for the practice domain's subdomains.
- Port-scanning 10.10.5.13, which your matrix shows running Redis with no auth prompt.
- Requesting many guessed paths from the Partner app at 10.10.5.11 to find admin pages.
- Reading a store manager's public social posts to craft a phishing email.
- Scanning 10.19.2.40, a login host you found in DNS that sits outside the range.
- You label each as passive or active: 1 passive, 2 active, 3 active, 4 passive (gathering) but out of bounds, 5 active
- You mark 2 and 3 as in scope and proceed; 4 as not authorised (no social engineering) and stop; 5 as out of scope and park it for the client to confirm
- You pick the unauthenticated Redis on 10.10.5.13 as the first target, because an open cache with no authentication is the highest-impact path in the matrix
Show a model answer
1 Passive and in scope: CT logs are third-party, so read them freely and note any new in-scope hosts. 2 Active and in scope: 10.10.5.13 is in range, so enumerate it within the rate limit. 3 Active and in scope: content discovery against 10.10.5.11 is fine, kept inside the rate limit. 4 This is OSINT on a person for social engineering, which the rules of engagement do not authorise, so do not collect it or use it, regardless of it being public. 5 Active but out of scope: 10.19.2.40 is outside 10.10.5.0/24, so do not scan it; record it and ask the client whether to add it.
First target: the Redis service on 10.10.5.13 with no authentication seen. An open cache often holds session data or secrets and needs no credentials, so it is the highest-impact, lowest-effort path in the matrix, ahead of the web login and the patched services.
Check yourself
After the engagement, Mangrove's blue team asks why your two weeks of testing barely showed up in their logs until day three. What is the most likely reason reconnaissance is so often missed?
Passive recon uses third-party data, so there is genuinely nothing for the target to see. The active part can be spread thin from ordinary addresses, and many teams have so much background scanning that no alert is tuned for it. Encryption, spoofing and blanket firewall blocking are not why the early days were quiet.
A company wants to reduce how much an attacker can learn about it before making contact. Which action shrinks its passive attack surface the most?
Passive sources are public and largely outside the company's control: certificate transparency is append-only by design, and archives and adverts cannot be fully scrubbed. The realistic defence, attack surface management, is to own less exposed surface by finding and retiring your own forgotten assets.
You have enumerated five in-scope hosts into a service matrix. Which host should usually rise to the top of the testing plan?
Prioritisation follows impact and reachability, not a raw port count. A reachable database or admin interface is a direct, high-value path, while the newest versions and the smallest host are weak reasons to lead with them. The service matrix exists precisely to make this choice visible.
Flashcards
Key takeaways
- Reconnaissance aims at an accurate, in-scope inventory of attack surface, not a pile of raw output, and it stays inside the rules of engagement from scoping.
- Passive recon reads public data (DNS, certificate transparency, repositories, job adverts, archives) and touches nothing; defenders should run the same discovery against themselves.
- Active recon (host discovery, port and service enumeration, banners, web content discovery) confirms what is really there, within the agreed rate limits, and every tool gives a lead you must still confirm.
- Organise findings into a target list and a service matrix with evidence and timestamps, and prioritise the hosts exposing sensitive services.
- Recon is quiet but not invisible; consistent, logged, in-scope behaviour lets the blue team reconstruct exactly what you did.
Sources and further reading
- OWASP Web Security Testing Guide, the information-gathering chapters, OWASP Foundation
- Reconnaissance (TA0043), MITRE ATT&CK
- What is Certificate Transparency?, the Certificate Transparency project
- OWASP Amass, attack surface mapping project, OWASP Foundation
- NIST SP 800-115, Technical Guide to Information Security Testing and Assessment, NIST