---
jupytext:
  text_representation:
    extension: .md
    format_name: myst
    format_version: 0.13
    jupytext_version: 1.16.0
kernelspec:
  name: python3
  display_name: Python 3
---

# Pentest et reconnaissance

```{admonition} Avertissement légal et éthique
:class: important
Tout test de pénétration requiert une **autorisation écrite préalable** du propriétaire du système cible. Les outils et techniques présentés dans ce chapitre sont légaux dans un cadre professionnel autorisé ou sur des environnements de test dédiés (labs, machines virtuelles, plateformes CTF). L'exécution de ces techniques sans autorisation explicite constitue une infraction pénale dans la plupart des pays (CFAA aux États-Unis, articles 323-1 à 323-7 du Code pénal en France). Ce chapitre est **exclusivement pédagogique**.
```

Le test de pénétration (*pentest*) est une activité de sécurité offensive consistant à évaluer la résistance d'un système en simulant les actions d'un attaquant réel. Contrairement à un audit de conformité, un pentest produit des preuves d'exploitation concrètes et mesure l'impact réel des vulnérabilités.

La phase de **reconnaissance** est la première étape de toute opération offensive. Elle détermine la qualité de l'ensemble de l'engagement : plus les informations collectées sont précises, plus les étapes suivantes (exploitation, post-exploitation) seront efficaces.

```{code-cell} python
:tags: [hide-input]

import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import matplotlib.dates as mdates
import numpy as np
import pandas as pd
import seaborn as sns
import networkx as nx
import random
import string
from datetime import datetime, timedelta
```

## Éthique et cadre légal

### Bug bounty

Les programmes de **bug bounty** permettent à des chercheurs indépendants de soumettre des vulnérabilités à des organisations en échange d'une récompense financière. Ils opèrent dans un cadre contractuel précis.

**Plateformes principales :**

- **HackerOne** : héberge des programmes publics et privés pour des entreprises comme Google, Microsoft, ou des agences gouvernementales. Utilise un système de réputation (*signal*, *impact*) pour qualifier les chercheurs.
- **Bugcrowd** : positionnement similaire, avec un accent sur les tests en crowdsourcing structuré. Propose des *VRT* (Vulnerability Rating Taxonomy) pour uniformiser la sévérité.

**Éléments clés d'un programme de bug bounty :**
- Périmètre (*in scope* / *out of scope*) : domaines, applications, types de vulnérabilités acceptées
- Tableau de récompenses selon la sévérité (CVSS)
- Délais de réponse garantis par l'organisation
- Clause de *safe harbor* protégeant le chercheur agissant de bonne foi

### Pentest autorisé

Un engagement de pentest professionnel repose sur trois documents contractuels :

**Statement of Work (SoW)** : définit le périmètre technique (adresses IP, domaines, applications), les dates d'exécution, et les livrables attendus.

**Rules of Engagement (RoE)** : précisent les contraintes opérationnelles — heures d'intervention autorisées, techniques interdites (DoS, destruction de données), procédure d'escalade en cas d'incident, contacts d'urgence.

**Non-Disclosure Agreement (NDA)** : protège la confidentialité des informations découvertes.

### Responsible disclosure

La divulgation responsable (*responsible disclosure* ou *coordinated vulnerability disclosure*) est le processus par lequel un chercheur notifie l'organisation concernée avant toute publication publique, laissant un délai raisonnable pour corriger la vulnérabilité (typiquement 90 jours, standard Google Project Zero).

### CVSS et scoring

Le **Common Vulnerability Scoring System (CVSS v3.1)** fournit un score numérique (0.0–10.0) basé sur trois groupes de métriques :

- **Base score** : exploitabilité (vecteur d'accès, complexité, privilèges requis, interaction utilisateur) + impact (confidentialité, intégrité, disponibilité)
- **Temporal score** : maturité du code d'exploitation, niveau de correction disponible
- **Environmental score** : adaptation au contexte de l'organisation cible

| Score | Sévérité |
|-------|----------|
| 0.0 | Aucune |
| 0.1–3.9 | Faible |
| 4.0–6.9 | Moyenne |
| 7.0–8.9 | Haute |
| 9.0–10.0 | Critique |

## PTES — Penetration Testing Execution Standard

Le **PTES** (Penetration Testing Execution Standard) définit un cadre en sept phases couvrant l'intégralité d'un engagement offensif.

```{code-cell} python
phases_ptes = [
    ("1. Pré-engagement",        ["Définition du périmètre", "Signature des RoE", "Collecte d'informations initiales"]),
    ("2. Collecte d'informations", ["OSINT passif", "Reconnaissance active", "Cartographie infrastructure"]),
    ("3. Modélisation des menaces", ["Identification des actifs critiques", "Analyse des vecteurs d'attaque", "Priorisation"]),
    ("4. Analyse de vulnérabilités", ["Scans automatisés", "Vérification manuelle", "Évaluation CVSS"]),
    ("5. Exploitation",           ["Exploitation des vulnérabilités", "Bypass des contrôles", "Preuve de concept"]),
    ("6. Post-exploitation",      ["Pivot réseau", "Élévation de privilèges", "Persistance"]),
    ("7. Rapport",                ["Executive Summary", "Findings techniques", "Recommandations"]),
]

activites = {
    phase: acts for phase, acts in phases_ptes
}

# Construction d'une heatmap artificielle phases × catégories d'activités
categories = ["OSINT", "Scan", "Exploitation", "Persistance", "Rapport", "Validation"]
phases_labels = [p for p, _ in phases_ptes]

np.random.seed(42)
data = np.array([
    [5, 0, 0, 0, 0, 3],
    [5, 4, 0, 0, 0, 2],
    [3, 2, 1, 0, 0, 4],
    [1, 5, 2, 0, 0, 3],
    [0, 2, 5, 3, 1, 4],
    [0, 1, 3, 5, 2, 3],
    [0, 0, 0, 0, 5, 5],
])

sns.set_theme(style="whitegrid", palette="muted", font_scale=1.1)
fig, ax = plt.subplots(figsize=(10, 6))
sns.heatmap(
    data,
    xticklabels=categories,
    yticklabels=[p.split(". ")[1] for p, _ in phases_ptes],
    annot=True,
    fmt="d",
    cmap="YlOrRd",
    linewidths=0.5,
    ax=ax,
    cbar_kws={"label": "Intensité (0–5)"}
)
ax.set_title("Heatmap PTES : phases × catégories d'activités", fontsize=13, pad=12)
ax.set_xlabel("Catégorie d'activité")
ax.set_ylabel("Phase PTES")
plt.show()
```

## Reconnaissance passive (OSINT)

La reconnaissance **passive** n'émet aucun paquet vers la cible directement. Elle exploite des sources publiques ou des tiers pour collecter des informations sans alerter les systèmes de détection.

### Shodan et Censys

**Shodan** est un moteur de recherche qui indexe les services réseau exposés sur Internet. Il scanne en continu les plages d'adresses IP mondiales et enregistre les bannières de services.

**Syntaxe de requêtes Shodan :**
```
hostname:alkimya.fr
org:"OVH SAS" port:443
product:"Apache httpd" version:"2.4"
ssl.cert.subject.cn:*.alkimya.fr
vuln:CVE-2021-44228
```

**Censys** adopte une approche similaire avec une emphase sur les certificats TLS et l'analyse des protocoles :
```
services.tls.certificates.leaf_data.subject.common_name: alkimya.fr
services.port=8443 AND services.software.product=nginx
```

### WHOIS et DNS passif

Le protocole **WHOIS** expose les informations d'enregistrement d'un domaine : registrant, dates de création/expiration, serveurs de noms, contacts administratifs. Les registrars modernes permettent la confidentialité via des services proxy, mais les données historiques restent souvent accessibles.

```{admonition} Outil : theHarvester
:class: note
theHarvester agrège automatiquement les données OSINT depuis de multiples sources (moteurs de recherche, certificats, DNS passif) pour un domaine cible. Il collecte e-mails, sous-domaines, adresses IP, URLs et noms d'employés.
```

### Certificate Transparency

Le programme **Certificate Transparency (CT)** impose aux autorités de certification (CA) de publier chaque certificat TLS émis dans des journaux publics et vérifiables. Ces journaux constituent une source OSINT de premier plan pour découvrir des sous-domaines.

**crt.sh** est une interface de recherche sur ces journaux :
```
https://crt.sh/?q=%.alkimya.fr
https://crt.sh/?q=alkimya.fr&output=json
```

```{code-cell} python
# Simulation OSINT : Certificate Transparency
random.seed(2024)

domaine_racine = "alkimya.fr"
sous_domaines_synthetiques = [
    "www", "mail", "smtp", "api", "docs", "dev", "staging",
    "admin", "vpn", "git", "ci", "monitoring", "static", "cdn"
]

def generer_san(sous_domaine):
    """Génère des SANs synthétiques pour un sous-domaine."""
    sans = [f"{sous_domaine}.{domaine_racine}"]
    if random.random() > 0.6:
        sans.append(f"*.{sous_domaine}.{domaine_racine}")
    return sans

def generer_certificat(sous_domaine):
    date_emission = datetime(2023, 1, 1) + timedelta(days=random.randint(0, 500))
    return {
        "cn": f"{sous_domaine}.{domaine_racine}",
        "sans": generer_san(sous_domaine),
        "issuer": random.choice(["Let's Encrypt", "DigiCert", "ZeroSSL"]),
        "not_before": date_emission.strftime("%Y-%m-%d"),
        "not_after": (date_emission + timedelta(days=90)).strftime("%Y-%m-%d"),
    }

certificats = [generer_certificat(sd) for sd in sous_domaines_synthetiques]

# Graphe networkx des sous-domaines découverts
G = nx.DiGraph()
G.add_node(domaine_racine, type="root")

for cert in certificats:
    cn = cert["cn"]
    G.add_node(cn, type="subdomain", issuer=cert["issuer"])
    G.add_edge(domaine_racine, cn, label="CT")
    for san in cert["sans"]:
        if san != cn and san not in G.nodes:
            G.add_node(san, type="wildcard")
            G.add_edge(cn, san, label="SAN")

color_map = []
for node in G.nodes:
    t = G.nodes[node].get("type", "subdomain")
    if t == "root":
        color_map.append("#e74c3c")
    elif t == "wildcard":
        color_map.append("#3498db")
    else:
        color_map.append("#2ecc71")

sns.set_theme(style="whitegrid", palette="muted", font_scale=1.0)
fig, ax = plt.subplots(figsize=(14, 8))
pos = nx.spring_layout(G, seed=42, k=0.7)
nx.draw_networkx_nodes(G, pos, node_color=color_map, node_size=500, ax=ax, alpha=0.9)
nx.draw_networkx_labels(G, pos, font_size=7, ax=ax)
nx.draw_networkx_edges(G, pos, ax=ax, arrows=True, arrowsize=12,
                       edge_color="#95a5a6", alpha=0.7)
legende = [
    mpatches.Patch(color="#e74c3c", label="Domaine racine"),
    mpatches.Patch(color="#2ecc71", label="Sous-domaine (CN)"),
    mpatches.Patch(color="#3498db", label="Wildcard (SAN)"),
]
ax.legend(handles=legende, loc="upper left", fontsize=9)
ax.set_title(f"Graphe OSINT — Certificate Transparency pour {domaine_racine}", fontsize=13)
ax.axis("off")
plt.show()

print(f"Sous-domaines découverts via CT : {len(sous_domaines_synthetiques)}")
print(f"Nœuds total dans le graphe : {G.number_of_nodes()}")
print(f"Relations découvertes : {G.number_of_edges()}")
```

### Google Dorks

Les **Google Dorks** exploitent les opérateurs avancés du moteur de recherche pour trouver des informations sensibles indexées :

| Opérateur | Usage | Exemple |
|-----------|-------|---------|
| `site:` | Restreindre à un domaine | `site:alkimya.fr` |
| `filetype:` | Filtrer par extension | `filetype:pdf confidential` |
| `inurl:` | Terme dans l'URL | `inurl:admin login` |
| `intitle:` | Terme dans le titre | `intitle:"index of" passwd` |
| `intext:` | Terme dans le contenu | `intext:"DB_PASSWORD"` |
| `cache:` | Version en cache | `cache:alkimya.fr` |

La base de données **Google Hacking Database (GHDB)** du projet Exploit-DB répertorie des milliers de dorks classés par catégorie (fichiers sensibles, webshells, erreurs de configuration, etc.).

### Maltego

**Maltego** est une plateforme de visualisation OSINT qui représente les relations entre entités (domaines, IPs, personnes, organisations, emails) sous forme de graphe. Il s'appuie sur des *transforms* — des requêtes API vers des sources de données tierces — pour enrichir automatiquement le graphe.

## Reconnaissance active

La reconnaissance **active** émet des paquets vers la cible, ce qui la rend détectable par les systèmes IDS/IPS et les logs réseau.

```{admonition} Rappel légal
:class: warning
L'émission de paquets vers des systèmes sans autorisation écrite est illégale dans la plupart des juridictions, même si l'intention est uniquement de découvrir des services ouverts. Les commandes Nmap présentées ci-dessous sont données à titre pédagogique et ne doivent être exécutées que sur des systèmes pour lesquels vous disposez d'une autorisation explicite.

Exemples de commandes Nmap (non exécutables ici) :
- Scan SYN furtif : `nmap -sS -T4 -p- 192.168.1.0/24`
- Détection d'OS et de versions : `nmap -sV -O --version-intensity 9 cible.local`
- Scripts NSE de vulnérabilités : `nmap --script vuln -sV cible.local`
- Scan UDP : `nmap -sU --top-ports 200 cible.local`
- Traceroute et timing agressif : `nmap -sS -T5 --traceroute -p 80,443 cible.local`
```

### Nmap — phases de scan

**Nmap** (Network Mapper) est l'outil de référence pour la cartographie réseau. Il implémente plusieurs techniques de scan aux sémantiques différentes :

**Scan SYN (half-open, -sS)** : envoie un paquet SYN sans compléter le handshake TCP. La réponse SYN/ACK indique un port ouvert ; RST indique un port fermé ; absence de réponse indique un port filtré (firewall). C'est la technique la plus utilisée car elle génère peu de logs applicatifs.

**Scan Connect (-sT)** : effectue un handshake TCP complet. Plus détectable mais ne nécessite pas de privilèges root.

**Scan FIN/NULL/XMAS (-sF/-sN/-sX)** : techniques d'évasion exploitant des comportements définis par la RFC 793 pour les systèmes Unix. Elles échouent généralement contre Windows qui répond RST dans tous les cas.

**Détection de versions (-sV)** : après avoir identifié les ports ouverts, Nmap envoie des sondes (*probes*) et compare les réponses à une base de données de *nmap-service-probes* pour identifier le service et sa version.

**NSE (Nmap Scripting Engine)** : moteur de scripts Lua permettant d'exécuter des vérifications avancées — détection de vulnérabilités spécifiques, brute-force d'authentification, collecte d'informations applicatives.

### Banner grabbing et service fingerprinting

Le **banner grabbing** consiste à lire les messages d'accueil envoyés par les services réseau lors d'une connexion. Ces bannières contiennent souvent le nom du logiciel et sa version :

```
SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.6
220 mail.alkimya.fr ESMTP Postfix (Ubuntu)
Server: nginx/1.24.0
X-Powered-By: PHP/8.1.12
```

```{code-cell} python
# Simulation probabiliste : états de ports selon le type de scan
np.random.seed(2024)

ports_courants = [21, 22, 23, 25, 53, 80, 110, 143, 443, 445,
                  3306, 3389, 5432, 5900, 6379, 8080, 8443, 9200, 27017, 6443]

types_scan = ["SYN (-sS)", "Connect (-sT)", "FIN (-sF)", "UDP (-sU)"]

# Matrice de probabilité d'observation selon le type de scan
# Valeurs : 0=closed, 1=filtered, 2=open (encodage numérique)
def simuler_etats(n_ports, scan_type, seed):
    rng = np.random.RandomState(seed)
    if scan_type == "SYN (-sS)":
        probs = [0.45, 0.35, 0.20]   # closed, filtered, open
    elif scan_type == "Connect (-sT)":
        probs = [0.45, 0.30, 0.25]
    elif scan_type == "FIN (-sF)":
        probs = [0.30, 0.55, 0.15]   # FIN génère plus de filtered
    else:  # UDP
        probs = [0.30, 0.60, 0.10]   # UDP majoritairement filtered/open|filtered
    return rng.choice([0, 1, 2], size=n_ports, p=probs)

matrice = np.array([
    simuler_etats(len(ports_courants), t, 42 + i)
    for i, t in enumerate(types_scan)
])

etiquettes_etats = {0: "Fermé", 1: "Filtré", 2: "Ouvert"}
cmap_custom = plt.cm.get_cmap("RdYlGn", 3)

sns.set_theme(style="whitegrid", palette="muted", font_scale=1.1)
fig, ax = plt.subplots(figsize=(14, 5))
im = ax.imshow(matrice, cmap=cmap_custom, aspect="auto", vmin=0, vmax=2)

ax.set_xticks(range(len(ports_courants)))
ax.set_xticklabels([str(p) for p in ports_courants], rotation=45, ha="right", fontsize=9)
ax.set_yticks(range(len(types_scan)))
ax.set_yticklabels(types_scan, fontsize=10)
ax.set_title("Simulation Nmap : états de ports (open/filtered/closed) par type de scan", fontsize=12, pad=10)
ax.set_xlabel("Port TCP/UDP")

cbar = fig.colorbar(im, ax=ax, ticks=[0, 1, 2], shrink=0.8)
cbar.ax.set_yticklabels(["Fermé", "Filtré", "Ouvert"])

for i in range(len(types_scan)):
    for j in range(len(ports_courants)):
        val = matrice[i, j]
        ax.text(j, i, ["F", "?", "O"][val], ha="center", va="center",
                fontsize=8, color="black", fontweight="bold")
plt.show()
```

## Scanning de vulnérabilités

Le scanning de vulnérabilités automatise la détection de failles connues (CVE) sur les services découverts lors de la reconnaissance active.

### Nessus

**Nessus** (Tenable) est le scanner de vulnérabilités commercial le plus répandu. Il utilise une base de données de plus de 190 000 *plugins* (vérifications individuelles) couvrant CVE, mauvaises configurations, audits de conformité (PCI-DSS, CIS Benchmarks).

**Architecture :** client/serveur — le serveur Nessus effectue les scans, le client web affiche les résultats. Chaque finding inclut le CVSS score, la description, la preuve d'exploitation (*proof of concept*) et les recommandations.

### OpenVAS / Greenbone

**OpenVAS** (Open Vulnerability Assessment Scanner) est l'alternative open-source. Il s'intègre dans la plateforme **Greenbone Vulnerability Management (GVM)** qui fournit un orchestrateur, une base de *Network Vulnerability Tests (NVTs)*, et une interface de reporting.

### Nuclei

**Nuclei** (ProjectDiscovery) est un scanner de vulnérabilités basé sur des templates YAML. Chaque template décrit une vérification spécifique : requête HTTP, expression régulière de correspondance, condition de déclenchement.

```yaml
# Exemple de template Nuclei (non exécutable)
id: apache-status-exposed
info:
  name: Apache Server Status Exposed
  severity: medium
  tags: apache,config
requests:
  - method: GET
    path:
      - "{{BaseURL}}/server-status"
    matchers:
      - type: word
        words:
          - "Apache Server Status"
```

## Framework Metasploit

**Metasploit Framework** (Rapid7) est la plateforme d'exploitation la plus utilisée dans l'industrie du pentest. Son architecture modulaire permet de composer des chaînes d'exploitation flexibles.

```{admonition} Architecture Metasploit (conceptuelle)
:class: note
Les modules Metasploit sont organisés en catégories :

- **Exploit** : code qui exploite une vulnérabilité spécifique (ex. `exploit/multi/handler`)
- **Payload** : code exécuté sur la cible après exploitation (Meterpreter, shell reverse, bind shell)
- **Auxiliary** : modules de reconnaissance, scan, fuzzing, brute-force
- **Post** : modules exécutés après compromission (collecte d'identifiants, énumération réseau, pivot)
- **Encoder** : transformations du payload pour contourner les détections
- **Evasion** : génération de code d'exploitation bypassing les antivirus

Le workflow type dans `msfconsole` :
1. `search` pour trouver un module adapté
2. `use <module>` pour le sélectionner
3. `show options` pour voir les paramètres requis
4. `set RHOSTS / LHOST / PAYLOAD` pour configurer
5. `check` pour vérifier la vulnérabilité sans exploitation
6. `run` ou `exploit` pour exécuter
```

## Résumé

1. **Cadre légal** : tout pentest requiert une autorisation écrite (RoE, SoW, NDA). Les programmes bug bounty offrent un cadre légal pour les chercheurs indépendants ; le scoring CVSS standardise la communication des sévérités.

2. **PTES** : le standard en 7 phases (pré-engagement → rapport) structure les engagements offensifs et garantit la complétude et la traçabilité des actions.

3. **Reconnaissance passive (OSINT)** : Shodan/Censys indexent les services exposés ; Certificate Transparency révèle les sous-domaines ; les Google Dorks exploitent les opérateurs avancés des moteurs de recherche. Aucun paquet n'est émis vers la cible.

4. **Reconnaissance active** : Nmap implémente plusieurs techniques de scan (SYN, Connect, FIN, UDP) aux caractéristiques de détectabilité différentes. La détection de versions (-sV) et les scripts NSE enrichissent le profil de la cible.

5. **Scanning de vulnérabilités** : Nessus, OpenVAS et Nuclei automatisent la détection de CVE connus. Nuclei se distingue par son approche template-as-code, adaptée à l'intégration CI/CD.

6. **Metasploit** : son architecture modulaire (exploit/payload/auxiliary/post) et son interface `msfconsole` en font la plateforme de référence pour la démonstration et la validation d'exploits dans les engagements autorisés.
