Pentest Methodology & Recon · beginner · ~11 min
**What you will learn** - Explain what OSINT (open-source intelligence) is and why gathering only *public* data keeps most of it passive. - Build safe search-engine *dork* queries with `site:`, `filetype:`, and `inurl:` to find material an organization forgot was indexed. - Detect exposed secrets (API keys, credentials) in public code and document metadata, and describe how to remediate and rotate them. - Query internet-scan databases (Shodan, Censys) to review a target's exposed services without touching the target yourself. - Apply an authorization and privacy standard: stay in scope, focus on organizational assets, avoid profiling individuals, and log what you did.
Security objective. The asset you are protecting is an organization's exposed public footprint: forgotten documents, leaked API keys, revealing metadata, and internet-facing services that were never meant to be found. The threat is an attacker assembling this scattered public data into a map of where to strike next — before they ever send a single packet at the target. In this lesson you learn to detect what is leaking so a defender can shut it down, and to do so within an authorized engagement.
What OSINT is. OSINT means open-source intelligence: information that anyone can collect from public sources — search engines, code repositories, published documents, and pre-collected scan databases. No login to the target, no exploit, no special access. You are reading data the world already published.
Where it fits. This lesson builds directly on your prerequisite, Passive vs active reconnaissance. There you learned the dividing line: passive recon reads data without touching the target's systems, while active recon sends traffic to the target. OSINT is the flagship example of passive recon. When you query Shodan, Shodan scanned the target, not you — so reading its results stays passive. When you type a target's IP into your own scanner, that is active. Keep that distinction in mind throughout; it determines what you are allowed to do and when.
Where it leads. Your next lesson, Technology detection and attack-surface mapping, takes the raw footprint you gather here and organizes it into a structured attack surface. OSINT feeds that map.
Why a beginner should care. OSINT is cheap, quiet, and legal when scoped correctly — and it is the single best way to find out what your own organization is leaking. Every technique here is also a defensive audit you can run on yourself.
In authorized professional work, OSINT is almost always the first phase of an engagement, and it pays for itself:
Done carelessly, OSINT crosses legal and ethical lines: pulling data on individuals, testing hosts that turn out to be third-party (a cloud provider, a partner), or acting on leaked credentials outside scope. The professional skill is not just finding — it is finding within authorization and turning findings into remediation.
OSINT is a collection of separate techniques that share one property: the data is already public. Learn each one on its own.
Definition. Dorking (a.k.a. Google dorking) means using a search engine's advanced operators to narrow results to material that is exposed but not meant to be prominent.
Plain explanation. Search engines index far more than an organization intends — old documents, directory listings, login portals, backup files. Operators let you filter for exactly those.
How it works. Common operators:
| Operator | Meaning | Example |
|---|---|---|
site: |
Restrict to one domain | site:example.com |
filetype: |
Restrict to a file extension | filetype:pdf |
inurl: |
Term must appear in the URL | inurl:admin |
intitle: |
Term must appear in the page title | intitle:"index of" |
- |
Exclude a term | -www |
You combine them: site:example.com filetype:pdf finds indexed PDFs on that domain.
When / when not. Use it against domains that are in your authorized scope, or against your own organization. Do not use it to hunt for exposed material on out-of-scope third parties, and never act on something like an exposed login just because a dork found it — finding is passive, logging in is not.
Pitfall. Dorks find what the search engine cached. Absence of a result does not prove absence of the file; the file may exist but be un-indexed. Dorking is a detection aid, not proof of security.
Definition. Secrets (API keys, passwords, tokens, private keys) accidentally committed to public repositories.
Plain explanation. Developers sometimes hard-code a key to "make it work," then push the repo public. Even after deleting the key, it often remains in the repository's commit history.
How it works. Automated scanners look for high-entropy strings and known key formats (e.g., a string shaped like AKIA… for one cloud provider). The key stays valid until someone rotates (revokes and re-issues) it.
When / when not. In scope, a live leaked secret is a real, often high-severity finding — you report it; you do not use it to access systems unless the rules of engagement explicitly authorize proving impact. Out of scope, you stop and report responsibly.
Pitfall. A found key may be a placeholder, expired, or a decoy. Never assume validity, and never test validity by logging in outside authorization.
Definition. Hidden fields embedded in files (PDF, Office documents, images) — authors, usernames, software versions, sometimes internal file paths or GPS coordinates.
Plain explanation. When someone saves a document, the tool stamps in metadata that the reader never sees in the body. Published publicly, that metadata leaks internal details.
How it works. Tools read the file's embedded fields. From a batch of an organization's public PDFs you might learn its username convention (jsmith), its software stack, and internal server names in file paths.
When / when not. Extract metadata from documents already published by the in-scope organization. Defensively, advise clients to strip metadata before publishing.
Pitfall. Metadata can be stale or spoofed. Treat it as a lead, not a fact.
Definition. Services that continuously scan the whole internet and let you query their stored results — open ports, service banners, TLS certificates, exposed devices.
Plain explanation. Instead of you scanning a target (active), these services already scanned everything. You search their database. That keeps your action passive.
How it works. You query by IP, domain, port, or product. Results show what services a host exposes and often the software version from the banner.
When / when not. Reading Shodan/Censys about an in-scope target is passive and generally fine. Connecting to a device you found is active and needs authorization.
Pitfall. Scan data can be hours or days stale, and an IP may belong to a shared cloud host, not your target. Confirm ownership before treating a result as "the target."
OSINT aggregates already-public data, but aggregation itself is sensitive — compiling a dossier on an individual is invasive even from public pieces. Stay focused on the organization's assets. Do not profile people beyond what the engagement's scope requires.
PUBLIC INTERNET (untrusted)
+--------------------------------------------------+
| Entry points an attacker reads (all passive): |
| - Search-engine index (dorks) |
| - Public code repos + commit history (secrets) |
| - Published documents (metadata) |
| - Shodan / Censys scan databases (services) |
+--------------------------------------------------+
|
| aggregation (attacker builds a map)
v
============ TRUST BOUNDARY: authorized scope =====
| ORG ASSETS you are allowed to assess: |
| - Owned domains / IP ranges |
| - Org-published documents |
| - Org's own repositories |
| |
| OUT OF SCOPE (do not touch): third parties, |
| cloud-shared IPs, individuals' personal data |
+--------------------------------------------------+
The attacker never crosses the boundary during OSINT — that is what makes it passive. The danger is that aggregated public data tells them exactly where to cross it later.
Knowledge check
There is no single language here — the "syntax" is query operators and safe command shapes. Annotated examples:
Search dork (type into a search engine):
site:example.com filetype:pdf
| |
| +-- restrict to PDF files
+-- restrict to this authorized domain only
Combine and exclude:
site:example.com intitle:"index of" -github
| | |
| | +-- drop noisy results mentioning github
| +-- pages whose title suggests a directory listing
+-- scope to the domain you are authorized to assess
Read internet-scan data (conceptual query, run against the scan service, not the target):
hostname:example.com
+-- returns services the scan DB already recorded for this host
Key rule reflected in the syntax: every query is anchored to a scope you are authorized for (site:/hostname: your target), and every query reads a public index — none of them send traffic to the target.
OSINT stands for open-source intelligence — anything you can find from public sources. It makes up most of passive reconnaissance (gathering information without interacting with the target's systems).
Advanced search operators narrow your results to exposed material. Common ones are site:, filetype:, intitle:, and inurl:.
Used legally, dorking surfaces material an organization forgot was indexed by search engines, such as:
Public code repositories sometimes leak sensitive data in their source or commit history, including:
This matters both ways. Offensively, leaked secrets are findings (when in scope). Defensively, advise clients to scan their own repositories and rotate any leaked keys.
Office files and PDFs embed extra details that are not visible in the document body, such as authors, usernames, software versions, and sometimes internal file paths.
Extracting this metadata from public documents can reveal:
Shodan and Censys continuously scan the internet and let you query their results. You can look up exposed services, banners, certificates, and devices using default credentials.
Reading this data is passive: these services performed the scanning, not you.
OSINT compiles data that is already public. Even so, compiling it about individuals raises privacy concerns.
Stay focused on the authorized organization and its assets. Do not profile people.
OSINT itself is mostly querying, but the defensive side is automatable. Below is the INSECURE → SECURE → VERIFY shape applied to the most common OSINT finding: a secret leaked in a file. Everything runs locally on files you own.
(1) The insecure pattern — a config file with a hard-coded secret
WARNING: intentionally vulnerable — use only in a local, isolated, authorized lab. Do not deploy.
# config.ini -- INSECURE: secret committed in plaintext, would leak if pushed public
[api]
endpoint = https://api.internal.example
api_key = sk_live_51H8xQeReAlLoOkInGpLaCeHoLdEr
If this file is committed to a public repo, a dork or secret scanner finds api_key, and the key stays valid until rotated. That is the vulnerability.
(2) The secure fix — keep secrets out of source, load from the environment, ignore secret files
# config.ini -- SECURE: no secret in the file, only a reference
[api]
endpoint = https://api.internal.example
api_key_env = APP_API_KEY # value lives in the environment, never in git
# .gitignore -- prevent real secret files from ever being committed
.env
secrets.*
*.pem
# supply the secret at runtime, in the lab, via a placeholder
export APP_API_KEY="<development-placeholder>"
(3) VERIFY — a local scanner that must REJECT the insecure file and ACCEPT the secure one
#!/usr/bin/env bash
# scan_for_secrets.sh -- lab-only pre-commit style check on files you own.
# Exits non-zero if a likely live secret is found. No network calls.
set -euo pipefail
target="${1:?usage: scan_for_secrets.sh <file>}"
# Patterns that indicate a REAL secret value (not an env-var reference).
# 'sk_live_' + long token, or a private key header.
if grep -Eq 'sk_live_[A-Za-z0-9]{16,}|-----BEGIN [A-Z ]*PRIVATE KEY-----' "$target"; then
echo "REJECT: possible live secret in $target"
exit 1
fi
echo "ACCEPT: no live secret pattern in $target"
exit 0
Expected behavior.
./scan_for_secrets.sh config_insecure.ini prints REJECT: possible live secret in config_insecure.ini and exits 1../scan_for_secrets.sh config_secure.ini prints ACCEPT: no live secret pattern in config_secure.ini and exits 0.The scanner proves the fix: bad input (a real key) is rejected; good input (an env reference) is accepted. Wiring this into a pre-commit hook stops the leak at the source — the strongest remediation, because the secret never becomes public in the first place.
Walking through the verification script, which is the load-bearing part:
| Line / part | What happens | Why it matters |
|---|---|---|
set -euo pipefail |
Abort on any error, undefined variable, or failed pipe stage | A security check that silently fails open is worse than none — this makes failures loud |
target="${1:?usage: ...}" |
Read the first argument; error out with a usage message if missing | Forces the caller to name the file; no accidental scan of nothing |
grep -Eq '...pattern...' |
Extended-regex, quiet match: exit 0 if the pattern is found, non-zero if not | This is the detection core; -q means we branch on the exit status, not the text |
sk_live_[A-Za-z0-9]{16,} |
Matches a provider-style live key: the sk_live_ prefix plus 16+ token chars |
Targets a real value shape, so an env reference like api_key_env = APP_API_KEY does not match |
-----BEGIN [A-Z ]*PRIVATE KEY----- |
Matches a PEM private-key header | Private keys are a frequent, high-impact leak |
echo "REJECT..."; exit 1 |
On match, report and fail | Non-zero exit lets a pre-commit hook or CI block the commit |
echo "ACCEPT..."; exit 0 |
On no match, report and pass | Clear positive signal that the file looks clean |
Trace with the two inputs:
| Input file contains | grep finds pattern? |
Script output | Exit code |
|---|---|---|---|
api_key = sk_live_51H8xQe... |
Yes | REJECT: possible live secret ... |
1 |
api_key_env = APP_API_KEY |
No | ACCEPT: no live secret pattern ... |
0 |
The key insight: the secure file references a secret by name rather than embedding its value, so the value-shaped regex cannot match it. That is exactly the property we want the fix to have, and the script proves it.
Real mistakes beginners make with OSINT, and how to correct them:
1. Treating a dork hit as permission to log in.
inurl:admin, then try credentials.2. Assuming a found secret is fake — or assuming it is real and using it.
3. Assuming a Shodan/dork result belongs to the target.
4. Profiling individuals.
5. Believing "no dork results" means "nothing is exposed."
When OSINT work does not go as expected:
site: alone), then add filters. Different search engines index differently — try more than one. Remember: no result is not proof of absence.- exclusions (-www, -blog) and combine operators (site: + filetype:) to narrow.key.Questions to ask when something fails:
Security & safety: detection and logging.
OSINT is quiet by nature, which cuts both ways — the defender may not see it happening. If you run OSINT tooling (secret scanners, dork automation, scan-DB pulls) as part of an authorized engagement or as a defender auditing your own org, log it properly.
What to log (for every automated OSINT/scan action):
What to NEVER log:
Which events signal abuse (from a defender's view):
intitle:"index of" on your domain) appearing in search results.How false positives arise: placeholder/test keys, env-var references mistaken for values, shared-host IPs attributed to your org, and stale scan data. Tune detections to require value-shaped matches and to verify asset ownership, and always let a human confirm before acting on a flagged secret.
Authorized use case. A company hires a security firm for an external assessment. Before any active scanning, the tester runs OSINT against the authorized domains only: dorks surface a forgotten filetype:xls budget sheet and an intitle:"index of" directory listing; a secret scan of the company's public repos finds an old cloud key in commit history; document metadata reveals the jsmith-style username convention; Shodan shows a database port exposed on an owned IP. None of this touches the target's systems. The tester reports each item with remediation: remove/deindex the files, rotate the key, strip metadata before publishing, and firewall the exposed port. The client then adopts these scans as a recurring self-audit.
Professional best-practice habits.
| Habit | Beginner | Advanced |
|---|---|---|
| Validation | Confirm every host is on the authorized asset list before treating it as in-scope | Automate asset-ownership checks (WHOIS/ASN) against a maintained inventory |
| Least privilege | Read public sources only; never log in with found credentials | Scope tooling to specific domains; separate read-only recon accounts |
| Secure defaults | Assume out-of-scope until proven in-scope | Default-deny asset lists; explicit allow-lists per engagement |
| Logging | Note what you queried and when | Structured, correlated logs with redacted references; feed into the report |
| Error handling | Stop and ask when a result looks like a third party | Alerting for scope violations; automatic exclusion of shared/CDN ranges |
Defensive framing. The most valuable real-world application is turning OSINT inward: attack-surface management is scheduled, institutionalized OSINT against your own organization so you find and fix leaks before an attacker aggregates them.
All tasks are lab-only: use domains you own, files you create, or intentionally-vulnerable practice environments. Each ends in a defensive conclusion — remediate and verify.
Authorization checklist (do this before any task):
Beginner 1 — Dork operator drill (no target).
www subdomain — all templated with example.com as a placeholder domain.site:, filetype:, intitle:, inurl:, and -.Beginner 2 — Metadata awareness on your own file.
Intermediate 1 — Build and test a secret scanner.
scan_for_secrets.sh to detect one additional key format (a placeholder shape you define). Create one file with a fake live-shaped secret and one with only an env reference.key.Intermediate 2 — Passive vs active classifier.
Challenge — Self-audit playbook.
site:, filetype:, inurl:, intitle:, -), leaked secrets in public code and commit history, document metadata (authors, usernames, paths), and internet-scan databases (Shodan, Censys — they scanned, so reading is passive)..gitignore → a scanner that rejects the value and accepts the reference.