Outil CLI Python pour l'analyse rapide d'IOC (IPs, Domaines, CVE) via 6 API gratuites de Threat Intel. Sorties : Excel coloré, JSON, CSV. Utilise : VT, Shodan, AbuseIPDB.
Analysez les IP, domaines, hachages et CVE sur 6 API gratuites de renseignement sur les menaces — sans changer d'onglet de navigateur.
Démarrage rapide · Utilisation · Architecture · Clés API · Captures d'écran · Contribution
🚀 Fièrement mis en avant dans le dépôt officiel Awesome OSINT.
ThreatLens est un outil en ligne de commande unique qui unifie les recherches de renseignement sur les menaces à travers les sources OSINT gratuites les plus fiables. Au lieu de coller une IP dans cinq sites web différents, ThreatLens les interroge tous en parallèle, normalise les résultats et vous donne un verdict clair — dans le terminal, ou dans un rapport Excel/JSON/CSV soigné et coloré.
Conçu pour les analystes SOC, les intervenants en cas d'incident, les chasseurs de menaces et toute personne souhaitant un enrichissement rapide et fiable des IOC sans quitter le shell.
|
Pourquoi ThreatLens
|
Pas pour
|
| Fonctionnalité | Détails |
|---|---|
| 🎯 Types d'IOC | IP, Domaine, URL, Hachage de fichier (MD5 / SHA1 / SHA256), CVE |
| 🔌 API intégrées | AbuseIPDB, VirusTotal, AlienVault OTX, Shodan, URLScan.io, NVD |
| 📄 Analyse de journaux | Extrait automatiquement chaque type d'IOC depuis n'importe quel journal ou fichier texte |
| 📊 Rapports | Excel (coloré), JSON, CSV |
| 💾 Cache local | Cache SQLite avec TTL configurable — évite de réinterroger les IOC connus |
| 🛡️ Sécurité | Blocage des redirections, liste blanche d'hôtes, masquage des clés API dans les journaux, neutralisation des formules de tableur |
| 🔒 Fichier de verrouillage | requirements.lock avec hachages SHA-256 pour des installations reproductibles |
| 💻 Expérience CLI | Barres de progression Rich, tableaux colorés et résumé de verdict clair |
| 🧩 Architecture | Enrichisseurs modulaires, modèles typés, séparation stricte des responsabilités |
| ✅ Testé | 60 tests unitaires et d'intégration avec pytest ; CI via GitHub Actions |
| ⚡ Résilient | Une API défaillante ne bloque jamais les autres — les erreurs sont isolées et journalisées |
# 1. Clone & install
git clone https://github.com/AbdaullahAG/threatlens.git
cd threatlens
pip install -r requirements.txt
# 2. Configure your API keys
cp config/keys.env.example config/keys.env
# → edit config/keys.env and fill in your keys
# 3. Run your first scan
python main.py -i 45.33.32.156
💡 NVD (recherches CVE) fonctionne immédiatement sans clé API. Toutes les autres API offrent un niveau gratuit dont l'inscription prend moins de 2 minutes — voir Clés API ci-dessous.
pip install --require-hashes -r requirements.lock
| Recherche simple d'un seul IOC |
| Combinez plusieurs types d'IOC en une seule exécution |
| Analyse en masse directement depuis des journaux bruts |
| Sortie lisible par machine pour les pipelines |
| Restreindre l'enrichissement aux sources sélectionnées |
| Excel + JSON + CSV en une seule exécution |
| Enrichissement CVE via NIST NVD (gratuit, sans clé) |
| Journalisation complète des requêtes/réponses pour le dépannage |
| Indicateur | Description |
|---|---|
-i, --ip | Adresse(s) IP à analyser |
-d, --domain | Domaine(s) à analyser |
-s, --hash | Hachage(s) de fichier — MD5 / SHA1 / SHA256 |
-c, --cve | ID(s) CVE, ex. CVE-2021-44228 |
--file | Chemin vers un fichier journal/texte pour extraire automatiquement les IOC |
--apis | Restreindre l'enrichissement à un ensemble spécifique d'API |
--format | Format de sortie : excel (par défaut) | json | csv | all |
--output | Répertoire de sauvegarde des rapports (par défaut : ./output) |
--no-report | Afficher les résultats uniquement dans le terminal, sans sauvegarder de fichier |
--cache-path | Chemin SQLite pour le cache local (par défaut : .threatlens/investigations.db) |
--cache-ttl | Durée de vie du cache en secondes (par défaut : 3600) |
--no-cache | Contourner entièrement le cache local |
--max-requests | Plafond des appels API externes par exécution (par défaut : 250) |
--max-iocs | Nombre maximum d'IOC uniques par exécution (par défaut : 1000) |
--allow-private-iocs | Autoriser les IP privées/loopback (désactivé par défaut) |
--delay | Délai entre les appels API, pour ajuster les limites de débit |
-v, --verbose | Activer la journalisation de débogage |
threat_intel_tool/
├── main.py # CLI entry point & argument parser
├── requirements.txt # Runtime dependencies
├── requirements-dev.txt # Dev/CI tooling (ruff, bandit, pip-audit, pip-tools)
├── requirements.lock # Pinned lockfile with SHA-256 hashes
├── pytest.ini # pytest configuration (marks, etc.)
├── config/
│ └── keys.env # API keys (copy from keys.env.example)
├── output/ # Generated reports land here
├── src/
│ ├── engine.py # Main orchestrator (collect → enrich → report)
│ ├── models.py # IOC & EnrichmentResult dataclasses
│ ├── storage.py # SQLite cache & investigation history
│ ├── parsers/
│ │ └── ioc_parser.py # Regex-based IOC extractor with validation
│ ├── enrichers/
│ │ ├── base.py # Abstract base — safe HTTP client (redirect-block, budget, retry)
│ │ ├── registry.py # Enricher dispatcher
│ │ ├── abuseipdb.py # AbuseIPDB (IP)
│ │ ├── virustotal.py # VirusTotal (IP / Domain / URL / Hash)
│ │ ├── otx.py # AlienVault OTX (IP / Domain / URL / Hash)
│ │ ├── shodan.py # Shodan (IP)
│ │ ├── urlscan.py # URLScan.io (URL / Domain)
│ │ └── nvd.py # NVD / NIST (CVE — no key required)
│ ├── reporters/
│ │ ├── excel_reporter.py # Color-coded Excel reports
│ │ ├── other_reporters.py # JSON & CSV output
│ │ └── terminal_display.py # Rich terminal tables
│ └── utils/
│ ├── config.py # API key loader & runtime config
│ ├── logger.py # Rich logging setup
│ ├── banner.py # ASCII banner
│ ├── quota.py # Per-run request budget (thread-safe)
│ └── security.py # IOC validation, formula neutralisation, secret redaction
└── tests/
├── conftest.py # pytest fixtures & --run-e2e flag
├── test_core.py # IOC parser, verdict logic, cache round-trip (34 tests)
├── test_enrichers.py # BaseEnricher HTTP edge-cases — mock only (9 tests)
├── test_reporters.py # Excel/CSV formula protection + SQLite integration (17 tests)
└── test_cli_e2e.py # Full CLI run against real NVD API (opt-in, --run-e2e)
Principes de conception
src/enrichers/ qui hérite de BaseEnricher. Aucune modification ailleurs n'est nécessaire.BaseEnricher.get() impose HTTPS uniquement, la liste blanche d'hôtes, le blocage des redirections, la gestion des 429/Retry-After et le plafonnement du budget de requêtes en un seul endroit.config/keys.env avec un repli sur les variables d'environnement système.--delay) vous maintient dans les limites du niveau gratuit de chaque API.result.errors ; une API défaillante ne fait jamais échouer l'ensemble de l'analyse.=, +, -, @).| Fournisseur | Inscription | Niveau gratuit |
|---|---|---|
| AbuseIPDB | Gratuit | 1 000 vérifications/jour |
| VirusTotal | Gratuit | 4 req/min · 500 req/jour |
| AlienVault OTX | Gratuit | Illimité (flux public) |
| Shodan | Gratuit | Recherches limitées |
| URLScan.io | Gratuit | 5 000 req/jour (la recherche est gratuite) |
| NVD / NIST | Facultatif | Aucune clé requise |
# Run all unit and integration tests (no network required)
pytest tests/ -v --ignore=tests/test_cli_e2e.py
# With coverage report
pytest tests/ -v --ignore=tests/test_cli_e2e.py --cov=src --cov-report=term-missing
# Run the end-to-end CLI test (makes a real NVD request)
pytest tests/test_cli_e2e.py --run-e2e -v
| Fichier de test | Couverture |
|---|---|
test_core.py | Analyseur d'IOC (tous les types + cas limites), logique de verdict, aller-retour du cache SQLite |
test_enrichers.py | BaseEnricher.get() — blocage des redirections, épuisement du budget, 429+Retry-After, masquage des clés API dans les journaux, réponse non-JSON, JSON invalide, liste blanche d'hôtes, blocage du schéma HTTP |
test_reporters.py | Neutralisation de l'injection de formules Excel & CSV (7 variantes de préfixes), transmission des valeurs numériques, expiration du TTL SQLite, upsert, enregistrement des investigations |
test_cli_e2e.py | Exécution complète en sous-processus : python main.py -c CVE-2021-44228 --apis nvd --format json → sortie 0, JSON valide, verdict correct |
| Contrôle | Implémentation |
|---|---|
| HTTPS uniquement | BaseEnricher.get() rejette toute URL non https:// avant d'effectuer une requête |
| Liste blanche d'hôtes | Chaque enrichisseur déclare allowed_hosts ; les requêtes vers des hôtes inconnus sont silencieusement abandonnées |
| Blocage des redirections | Toutes les requêtes utilisent allow_redirects=False |
| 429 / Retry-After | Une seule nouvelle tentative automatique respectant l'en-tête Retry-After (plafonnée à 15 s) |
| Budget de requêtes | --max-requests plafonne strictement le total des appels API par exécution |
| Masquage des clés API | Les exceptions et lignes de journal voient les valeurs de clés brutes remplacées par [REDACTED] |
| Injection de formules | Toutes les valeurs de cellules Excel et CSV sont assainies avec spreadsheet_value() |
| Validation des IOC | Chaque IOC fourni en CLI est validé et normalisé avant enrichissement |
| Protection des IP privées | Les adresses privées/loopback sont rejetées par défaut (--allow-private-iocs pour les autoriser) |
| Audit des dépendances | pip-audit s'exécute en CI ; requirements.lock épingle tous les hachages pour des installations reproductibles |
Terminal :
╭──────────────────────────── IOC Collection ─────────────────────────────╮
│ Found 4 IOCs to investigate │
│ CVE: 1 Domain: 1 Hash: 1 IP: 1 │
╰──────────────────────────────────────────────────────────────────────────╯
✓ Active APIs: abuseipdb, virustotal, otx, shodan, urlscan, nvd
🌐 IP Address Results
┌─────────────────┬──────────────┬──────────┬─────────┬────────────────────┐
│ IP Address │ Verdict │ Abuse % │ Country │ ISP / Org │
├─────────────────┼──────────────┼──────────┼─────────┼────────────────────┤
│ 45.33.32.156 │ Suspicious │ 42 │ US │ Linode │
└─────────────────┴──────────────┴──────────┴─────────┴────────────────────┘
⚠️ CVE Results
┌──────────────────┬──────────┬──────┬──────────────┐
│ CVE ID │ Severity │ CVSS │ Published │
├──────────────────┼──────────┼──────┼──────────────┤
│ CVE-2021-44228 │ Critical │ 10.0 │ 2021-12-10 │
└──────────────────┴──────────┴──────┴──────────────┘
Rapport Excel : Classeur multi-feuilles avec verdicts colorés (🔴 malveillant · 🟡 suspect · 🟢 propre), enregistré dans output/ThreatLens_Report_<timestamp>.xlsx
Une idée ? Ouvrez une issue — les contributions et suggestions sont les bienvenues.
Les contributions sont les bienvenues et appréciées !
git checkout -b feature/my-featurepytest tests/ -v --ignore=tests/test_cli_e2e.py passe et que ruff check . est propreLes nouveaux enrichisseurs, corrections de bugs, améliorations de la documentation et couverture de tests sont tous d'excellentes premières contributions — voir Architecture pour comprendre la structure des enrichisseurs.
Ce projet est sous licence PolyForm Noncommercial License 1.0.0.
Vous êtes libre d'utiliser, d'étudier, de modifier et de partager ce code à des fins personnelles, éducatives ou de recherche. L'utilisation commerciale n'est pas autorisée sans autorisation écrite préalable de l'auteur ([email protected]).
Cet outil est destiné à des fins éducatives et de tests de sécurité autorisés uniquement. L'utilisateur est seul responsable du respect des conditions d'utilisation des API intégrées et de toutes les lois applicables. L'auteur décline toute responsabilité et n'est pas responsable de toute utilisation abusive, activité illégale ou dommage causé par ce programme.
Si ThreatLens vous a fait gagner du temps, envisagez de lui donner une ⭐ — cela aide les autres à découvrir le projet.