OSINT — Démonstration guidée
Une cible. Une vraie. On ne va rien lui envoyer. Et à la fin, on saura : ses sous-domaines, ses technologies, ses employés clés, ses fuites, et ses cinq points faibles probables.
On utilise un programme de bug bounty public, où l'entreprise autorise explicitement les tests dans un cadre défini. Vous pouvez faire pareil chez vous en choisissant un programme sur HackerOne ou Bugcrowd. Dans la démo qui suit, on utilise un nom fictif demo-corp.com pour illustrer — mais tout ce que vous voyez est reproductible sur une cible réelle autorisée.
Ce que vous saurez faire après cette leçon
- Passer d'un simple nom de domaine à une carte d'infrastructure en 90 minutes.
- Utiliser
crt.sh,subfinder,amass -passive,dnsx(mode passif),theHarvester,whatweb. - Distinguer les sous-domaines vivants des sous-domaines morts sans les toucher.
- Recouper trois sources indépendantes avant de conclure.
- Produire une fiche cible de 2 pages exploitable dès le module 4.
Étape 0 — Le point de départ
Une simple ligne :
Cible : demo-corp.com
Programme : bug bounty public, scope in-scope = *.demo-corp.com
C'est tout. On part de là.
Créez le dossier de travail :
mkdir -p ~/osint/demo-corp/{dns,subs,tech,people,leaks,archive}
cd ~/osint/demo-corp
Chaque famille de source aura son sous-dossier. Discipline dès le départ.
Étape 1 — DNS de base (2 minutes)
Les enregistrements essentiels, un par un :
for t in A AAAA MX NS TXT SOA CAA; do
echo "=== $t ==="
dig +short demo-corp.com $t
done | tee dns/racine.txt
Sortie typique :
=== A ===
104.21.44.15
172.67.187.219
=== AAAA ===
=== MX ===
1 aspmx.l.google.com.
5 alt1.aspmx.l.google.com.
=== NS ===
ada.ns.cloudflare.com.
kirk.ns.cloudflare.com.
=== TXT ===
"v=spf1 include:_spf.google.com include:mailgun.org -all"
"google-site-verification=abc123def456..."
"MS=ms84726311"
"stripe-verification=xyz789..."
=== SOA ===
ada.ns.cloudflare.com. dns.cloudflare.com. 2354...
=== CAA ===
0 issue "letsencrypt.org"
0 issue "digicert.com"
Lecture :
- A : deux IPs dans le pool Cloudflare (104.21.x et 172.67.x). Le site est derrière Cloudflare — on ne verra pas l'IP réelle sans effort.
- MX : Google Workspace. Aucun serveur mail à eux directement.
- NS :
ada.ns.cloudflare.com— Cloudflare gère le DNS aussi. Cohérent. - TXT :
- SPF autorise Google et Mailgun. Deux services SaaS identifiés.
- google-site-verification : ils utilisent Google Search Console.
- MS= : ils utilisent Microsoft (Bing Webmaster, souvent).
- stripe-verification : ils traitent des paiements Stripe. Ça veut dire du PCI-DSS quelque part.
- CAA : seuls Let's Encrypt et DigiCert peuvent émettre. Bon signe côté hygiène.
En 2 minutes, on sait déjà : Cloudflare, Google Workspace, Mailgun, Stripe. On n'a envoyé aucun paquet à demo-corp.com.
Étape 2 — DMARC et posture email (1 minute)
dig +short _dmarc.demo-corp.com TXT
Sortie :
"v=DMARC1; p=none; rua=mailto:dmarc-reports@demo-corp.com"
Lecture : p=none. La politique DMARC est là mais ne fait rien. Résultat concret : un attaquant peut spoofer des emails prétendument envoyés par demo-corp.com, ces emails passeront chez le destinataire même s'ils échouent DMARC. C'est un vecteur de phishing à noter pour le module 6.
Enregistrez ça dans dns/dmarc.txt.
Étape 3 — Sous-domaines via crt.sh (3 minutes)
Certificate Transparency, la meilleure source pour la première salve de sous-domaines. On interroge en JSON, on nettoie avec jq :
curl -s 'https://crt.sh/?q=%25.demo-corp.com&output=json' \
| jq -r '.[].name_value' \
| tr '[:upper:]' '[:lower:]' \
| sed 's/^\*\.//' \
| sort -u \
> subs/from-crt.txt
wc -l subs/from-crt.txt
Sortie typique :
127 subs/from-crt.txt
Un extrait :
admin.demo-corp.com
api.demo-corp.com
api-dev.demo-corp.com
api-staging.demo-corp.com
beta.demo-corp.com
blog.demo-corp.com
cdn.demo-corp.com
customer.demo-corp.com
demo-corp.com
dev.demo-corp.com
docs.demo-corp.com
help.demo-corp.com
internal.demo-corp.com
jenkins.demo-corp.com
jira.demo-corp.com
mail.demo-corp.com
monitoring.demo-corp.com
old-admin.demo-corp.com
partners.demo-corp.com
prod.demo-corp.com
sso.demo-corp.com
staging.demo-corp.com
status.demo-corp.com
support.demo-corp.com
vpn.demo-corp.com
web.demo-corp.com
www.demo-corp.com
Trois lignes qui font sourire un attaquant :
internal.demo-corp.com— un sous-domaine qui n'aurait pas dû sortir.jenkins.demo-corp.com— un serveur de CI/CD, historiquement mine de failles.old-admin.demo-corp.com— l'ancien panneau d'admin. Ça, ça sent l'oubli.
En 3 minutes, on est passé de 1 nom à 127.
Étape 4 — Recouper avec subfinder et amass -passive
subfinder interroge une vingtaine d'API tierces (Shodan, VirusTotal, SecurityTrails, DNSDumpster…) et rend une liste. Passif à 100 %.
subfinder -d demo-corp.com -silent -all -o subs/from-subfinder.txt
wc -l subs/from-subfinder.txt
143 subs/from-subfinder.txt
Idem, amass en mode passif :
amass enum -passive -d demo-corp.com -o subs/from-amass.txt
Ensuite on fusionne :
cat subs/from-*.txt | sort -u > subs/all-passive.txt
wc -l subs/all-passive.txt
178 subs/all-passive.txt
De 127 à 178. Chaque source a apporté quelques trouvailles. C'est pour ça qu'on recoupe.
Étape 5 — Résolution passive avec dnsx
Attention : dnsx résout les noms. Chaque résolution passe par un résolveur DNS public (Google 8.8.8.8 par défaut). C'est encore passif pour la cible si vous utilisez un résolveur qui n'appartient pas à la cible. Vérifiez que les NS de demo-corp.com ne sont pas vos résolveurs (c'est le cas ici : Cloudflare gère leur DNS, mais votre dnsx va interroger 1.1.1.1 de Cloudflare Public — c'est un service différent).
dnsx -l subs/all-passive.txt -a -resp -silent -r 1.1.1.1,8.8.8.8 \
-o subs/all-resolved.txt
head subs/all-resolved.txt
Sortie :
admin.demo-corp.com [104.21.44.15]
api.demo-corp.com [104.21.44.15]
api-dev.demo-corp.com [3.98.14.202]
api-staging.demo-corp.com [104.21.44.15]
internal.demo-corp.com [192.168.10.5]
jenkins.demo-corp.com [3.98.14.209]
old-admin.demo-corp.com [66.42.11.198]
Trois lignes qui parlent :
internal.demo-corp.comrésout en 192.168.10.5 — une IP privée publiée dans le DNS public. Le sous-domaine est destiné à être accédé via VPN, mais sa présence dans le DNS confirme que ce service existe. À signaler.api-dev.demo-corp.comsur3.98.x.x— bloc AWS ca-central-1, pas derrière Cloudflare. C'est le vrai serveur exposé. Cible prioritaire pour la phase active.old-admin.demo-corp.comsur66.42.x.x— Vultr. Un serveur oublié, hors du CDN principal. Cible prioritaire aussi.
Notez ces trois lignes. Elles orienteront tout le module 4.
Étape 6 — Fingerprinting technologique passif
Attention : whatweb et wappalyzer chargent la page — c'est actif. Pour rester en passif strict, on utilise :
- BuiltWith (via l'interface web depuis votre navigateur — mais votre navigateur va charger BuiltWith, pas la cible).
- Shodan :
shodan host <IP>renvoie ce que Shodan a déjà collecté.
shodan host 3.98.14.202 > tech/shodan-api-dev.txt
cat tech/shodan-api-dev.txt
Sortie type :
3.98.14.202
Hostnames: ec2-3-98-14-202.ca-central-1.compute.amazonaws.com
Country: Canada
City: Montréal
Organization: Amazon.com, Inc.
Open Ports: 22, 80, 443, 8080
22/tcp SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.5
80/tcp nginx/1.18.0
443/tcp nginx/1.18.0 — TLSv1.3 — CN=api-dev.demo-corp.com
8080/tcp Django DEBUG page found
Ligne d'or : Django DEBUG page found. Shodan a déjà vu un mode debug Django exposé sur :8080. Un mode debug Django expose :
- La stack complète en cas d'erreur.
- Les variables d'environnement (donc souvent des clés secrètes).
- Parfois
SECRET_KEYcomplète.
On vient de trouver, sans envoyer un paquet à demo-corp.com, une faille probablement critique. On la confirmera en semaine 4.
Notez la découverte dans tech/decouvertes.md :
- [CRITIQUE] api-dev.demo-corp.com:8080 — Django en DEBUG (source : Shodan)
- [INFO] api-dev.demo-corp.com : Nginx 1.18, OpenSSH 8.2 sur Ubuntu 20
Étape 7 — Personnes clés (theHarvester + LinkedIn)
theHarvester -d demo-corp.com -b linkedin,bing,duckduckgo -l 500 \
-f people/harvester.html
theHarvester interroge des API tierces et LinkedIn (via Bing en général). Sortie type :
[*] Emails found: 34
admin@demo-corp.com
contact@demo-corp.com
j.dupuis@demo-corp.com
m.tremblay@demo-corp.com
...
[*] Hosts found:
(Idem, redondant avec ce qu'on a déjà)
[*] LinkedIn profiles (via Bing):
Marie Tremblay - CTO at Demo Corp
Jean Dupuis - Senior DevOps at Demo Corp
Étienne Roy - Support Lead at Demo Corp
...
Le pattern d'email ressort tout de suite : initiale.nom@demo-corp.com. À partir de LinkedIn, vous pouvez deviner l'email de la majorité des employés du client, sans jamais le leur demander.
Consolidez dans people/personnes.csv :
prenom,nom,titre,email,linkedin
Marie,Tremblay,CTO,m.tremblay@demo-corp.com,https://www.linkedin.com/in/marietremblay
Jean,Dupuis,Senior DevOps,j.dupuis@demo-corp.com,...
Étienne,Roy,Support Lead,e.roy@demo-corp.com,...
Ce fichier sert au module 6 (ingénierie sociale).
Étape 8 — Fuites publiques
# HaveIBeenPwned par domaine — nécessite une clé API (payante mais peu chère).
curl -s -H "hibp-api-key: $HIBP_KEY" \
"https://haveibeenpwned.com/api/v3/breacheddomain/demo-corp.com" \
| jq . > leaks/hibp.json
# Aperçu :
jq -r 'keys[] as $k | "\($k) → \(.[$k] | join(", "))"' leaks/hibp.json | head
Sortie :
j.dupuis → Adobe, Collection#1, MyFitnessPal
support → Collection#1
etienne.roy → LinkedIn, Dropbox
Deux comptes techniques (j.dupuis, etienne.roy) ont déjà fuité dans des dumps publics. Si le client fait du password reuse — et statistiquement, un pentester peut compter là-dessus — on va pouvoir tenter du password spraying en semaine 5.
Complétez avec GitHub Search :
- Aller sur github.com/search?type=commits&q=%22demo-corp.com%22.
- Aller sur
github.com/<employe>?tab=repositoriespour chaque employé listé.
Cherchez des dépôts nommés demo-corp-*, scripts, backups, dotfiles. On y trouve régulièrement :
- Un
.envavec des secrets. - Des scripts avec des mots de passe en dur.
- Des URLs internes.
Dans notre démo, un dotfiles public d'un ex-employé contient un fichier deploy.sh avec :
ssh deploy@old-admin.demo-corp.com -i ~/.ssh/deploy-key
Cible confirmée : old-admin.demo-corp.com, compte deploy. À exploiter en semaine 4.
Étape 9 — Archives (Wayback Machine)
curl -s "https://web.archive.org/cdx/search/cdx?url=demo-corp.com/*&output=json&limit=200" \
| jq -r '.[1:] | .[] | .[2]' \
| sort -u > archive/urls-historiques.txt
wc -l archive/urls-historiques.txt
Sortie :
612 archive/urls-historiques.txt
Un grep sur des mots-clés révélateurs :
grep -iE 'admin|backup|test|debug|swagger|api-doc|internal' archive/urls-historiques.txt
https://demo-corp.com/admin-old/
https://demo-corp.com/api/v1/debug
https://demo-corp.com/backup.sql (2019)
https://demo-corp.com/swagger.json
backup.sql en 2019 — probablement supprimé depuis, mais on vérifiera au module 4 : la Wayback Machine ne garantit pas la suppression côté serveur.
Étape 10 — Consolider la fiche
Ouvrez ~/osint/demo-corp/fiche-cible.md et remplissez avec ce qui précède. Cibles prioritaires à faire remonter en gras.
# Fiche cible — demo-corp.com (2026-04-15)
## 1. Actifs confirmés
- Domaine racine : demo-corp.com (Cloudflare DNS + proxy)
- Sous-domaines : 178 collectés, dont :
- **api-dev.demo-corp.com → AWS ca-central-1 (3.98.14.202), Django DEBUG sur :8080**
- **old-admin.demo-corp.com → Vultr (66.42.11.198), compte deploy présumé**
- internal.demo-corp.com → 192.168.10.5 (privé), publié à tort
- jenkins.demo-corp.com → AWS
- jira.demo-corp.com → Atlassian Cloud (hors périmètre à préciser)
## 2. Périmètre à négocier avec le client
- internal.demo-corp.com (IP privée publiée) : ajouter au RoE ?
- Sous-domaines Atlassian et Google : hors périmètre.
## 3. Technologies
- Front (www) : Next.js derrière Cloudflare
- API prod : inconnu, filtré par Cloudflare
- API dev : Django, Nginx 1.18, Ubuntu 20 (source : Shodan)
- Messagerie : Google Workspace
- SaaS liés : Stripe, Mailgun, Atlassian, Sentry
## 4. Failles probables (à confirmer en semaine 4)
- CRITIQUE : Django DEBUG exposé sur api-dev:8080
- HAUTE : old-admin.demo-corp.com — panneau d'admin hérité
- MOYENNE : DMARC p=none → phishing spoofé possible
- MOYENNE : backup.sql (2019) — présent sur le serveur actuel ?
## 5. Personnes clés (source : LinkedIn + theHarvester)
- Marie Tremblay, CTO — m.tremblay@demo-corp.com
- Jean Dupuis, Sr DevOps — j.dupuis@demo-corp.com [fuite HIBP × 3]
- Étienne Roy, Support Lead — e.roy@demo-corp.com [fuite HIBP × 2]
+ 21 autres dans people/personnes.csv
## 6. Fuites publiques
- HIBP : 2 comptes à haute valeur avec réutilisation probable
- GitHub : dotfiles d'un ex-employé cite old-admin.demo-corp.com et compte deploy
## 7. Prochaine étape (module 4)
1. Confirmer Django DEBUG sur api-dev:8080 — 30 min.
2. Cartographier old-admin.demo-corp.com : ports, versions — 45 min.
3. Vérifier /backup.sql sur www — 5 min.
4. Password spraying prudent sur les 2 comptes HIBP — 30 min.
Bilan
En 90 minutes, sans envoyer aucun paquet à demo-corp.com :
- On a 178 sous-domaines.
- On a une faille critique presque certaine (Django DEBUG exposé).
- On a deux cibles secondaires à haute valeur (
old-admin,internal). - On a un plan d'attaque pour la semaine 4.
- On a des comptes fuités exploitables plus tard.
- La cible ne sait rien.
Voilà la puissance de l'OSINT bien menée. C'est le module qui rapporte le plus par minute investie.
Prochaine leçon : à vous. Vous choisissez un programme de bug bounty et vous refaites la même chose, en autonomie.