Challenge Lab 02 — SSH & Paramiko


⚠️ Avertissement légal & éthique — Tout essai d’authentification doit être réalisé exclusivement sur vos propres machines/VMs ou un lab explicitement autorisé. Ne lancez jamais ces scripts sur des systèmes tiers.


Exercice 1 — Installation & vérification de Paramiko

Objectif : vérifier l’environnement Python/Paramiko.

Énoncé :

  1. Installez Paramiko.
  2. Affichez sa version.

Indices : pip install paramiko; python3 -c "import paramiko; print(paramiko.__version__)".

Exercice 2 — Sonde d’authentification SSH minimaliste

Objectif : distinguer success / failure / error.

Énoncé : Écrivez try_ssh_login(host, port, username, password, timeout=3.0) qui retourne un dict {outcome: 'success'|'failure'|'error', ...} en utilisant paramiko.SSHClient.

Indices : allow_agent=False, look_for_keys=False, AuthenticationException vs SSHException/OSError.

Exercice 3 — Lecture du banner SSH

Objectif : récupérer la version distante pour enrichir les rapports.

Énoncé : Après une tentative de connexion, récupérez client.get_transport().remote_version et affichez‑la.

Indices : la bannière SSH est visible même si le mot de passe est faux (après handshake).

Exercice 4 — Chargeur de wordlist (sécurisé)

Objectif : lire un fichier de mots de passe lab‑safe.

Énoncé : Écrivez load_wordlist(path) qui retourne une liste sans lignes vides ni commentaires #. Limitez‑vous à une petite liste (≤ 10 entrées) pour le lab.

Indices : encoding='utf-8', errors='ignore'.

Exercice 5 — Boucle séquentielle avec garde‑fous

Objectif : exécuter au plus N essais, localement.

Énoncé : Implémentez brute_sequential(...) qui : (a) refuse toute IP hors 127.0.0.1 ou 192.168.56.0/24; (b) n’essaie pas plus de 10 mots de passe; (c) dort 1s entre tentatives.

Indices : ipaddress.ip_network; time.sleep(1).

Exercice 6 — Gestion d’erreurs & backoff

Objectif : réagir proprement aux erreurs et verrouillages.

Énoncé : Si error survient, affichez le message et dormez 2s avant de continuer. Si ≥ 3 erreurs d’affilée, dormez 30s (verrouillage probable) puis reprenez.

Indices : compteur d’erreurs consécutives; temporisation progressive.

Exercice 7 — Rate limiting & jitter (fonction utilitaire)

Objectif : produire un délai aléatoire réaliste.

Énoncé : Écrivez sleep_with_jitter(min_s, max_s) qui dort un temps uniforme entre min_s et max_s. Intégrez‑la à la boucle séquentielle.

Indices : random.uniform(a,b); time.sleep(...).

Exercice 8 — Concepts de threading

Objectif : préparer une version multi‑thread lab‑safe.

Énoncé : Écrivez un squelette worker(host, port, username, queue, event, lock) qui : (a) ne traite au plus que 3 mots de passe par thread; (b) stoppe si event.is_set().

Indices : queue.Queue distribue le travail, threading.Event signale l’arrêt, Lock protège les sorties.

Exercice 9 — Queue vs. split manuel

Objectif : équilibrage de charge correct.

Énoncé : En pseudo‑code, expliquez pourquoi Queue.get() évite les doublons et répartit mieux le travail que le découpage en morceaux statiques.

Indices : pattern producteur/consommateur; évite les race conditions sur la liste.

Exercice 10 — Journalisation contrôlée (anonymisation)

Objectif : tracer les essais sans révéler les mots de passe en clair.

Énoncé : Configurez logging (fichier brute_scan.log) et logguez chaque tentative sous forme masquée (p******23).

Indices : logging.FileHandler, masquage simple : garder 1–2 derniers caractères.

Exercice 11 — Détection côté défenseur (théorique)

Objectif : relier éthique et détection.

Énoncé : Citez 3 mécaniques qui détectent/bloquent : fail2ban, 2FA, désactivation du password auth, port knocking… Expliquez comment votre jitter influe (ou pas) sur ces défenses.

Indices : fail2ban surveille /var/log/auth.log; 2FA rend le mot de passe seul insuffisant.

Exercice 12 — Rapport final (plain‑text)

Objectif : donner un retour propre et pédagogique.

Énoncé : Écrivez print_summary(stats) qui affiche : hôte, nb d’essais, durée, moyenne tentatives/s, succès/échec, bannière SSH si disponible, et rappelle les garde‑fous appliqués (IP locales, limites, délais).

Indices : f‑strings; chronométrage time.time().


By Wahid Hamdi