
Un outil OSINT qui aide à détecter les membres d'une entreprise ayant des identifiants divulgués
EmploLeaks est un outil OSINT (Open Source Intelligence) avec une interface CLI, conçu pour découvrir et corréler des informations sur les employés d'une entreprise cible. Il permet de collecter des profils LinkedIn, générer des adresses e-mail professionnelles potentielles, rechercher des identifiants divulgués dans des bases de données de fuites (ClickHouse en interne), vérifier les violations connues via HaveIBeenPwned, découvrir l'infrastructure de l'entreprise et profiler les employés sur les réseaux sociaux. Toutes les informations sont stockées localement dans SQLite pour une analyse ultérieure.
emploleaks/ ├── emploleaks.py # Script principal (CLI interactiva con cmd2) ├── telegram_sync.py # Daemon userbot de Telegram (Telethon, standalone) ├── requirements.txt # Dependencias de Python ├── README.md ├── .gitignore ├── plugins/ │ ├── linkedin.py # Plugin de LinkedIn (scraping de empleados) │ ├── github.py # Plugin de GitHub (repos, stalk, secrets) │ └── hibp.py # Plugin de HaveIBeenPwned (brechas) ├── utils/ │ ├── logging_format.py # Configuración de logging con colores │ ├── ai_classifier.py # Clasificación de roles con IA (OpenAI/Ollama) │ ├── leak_parser.py # Parser de leaks 100% agéntico (loop de IA, sin regex) │ ├── email_lookup.py # Búsqueda de emails en redes sociales (Holehe) │ ├── profile_lookup.py # Búsqueda de usernames en redes sociales (Maigret) │ └── discovery.py # Enumeración de subdominios (assetfinder + SecurityTrails opcional) ├── clickhouse-docker/ # Docker Compose para levantar ClickHouse │ ├── docker-compose.yml │ └── config/ │ └── users.xml ├── leaks_data/ # Carpeta para archivos de leaks a importar (no en git) ├── config/ # Configuración (autogenerado) │ └── tokens.ini # Tokens y credenciales de plugins (no en git) ├── data/ # Base de datos local (autogenerado) │ └── emploleaks.db # SQLite con toda la información recopilada ├── webapp/ # Webapp administrativa │ ├── backend/ # FastAPI (Python) │ └── frontend/ # Next.js (React/TypeScript) └── logs/ # Archivos de log (autogenerado) └── log.txt
## Prérequis
- Python 3.10+
- pip
- Connexion Internet
- **Optionnel :** Docker et Docker Compose (pour lancer ClickHouse localement)
- **Optionnel :** [gitleaks](https://github.com/gitleaks/gitleaks) (pour le scan de secrets dans les dépôts)
- **Optionnel :** clé API de [HaveIBeenPwned](https://haveibeenpwned.com/API/Key)
- Cookies de session LinkedIn (`JSESSIONID` et `li_at`) pour le plugin LinkedIn
## Installation
1. Cloner le dépôt :```bash
git clone https://github.com/yourusername/emploleaks.git
cd emploleaks
3. (Optionnel) Lancer ClickHouse avec Docker pour la base de données de fuites :```bash
cd clickhouse-docker
docker compose up -d
cd ..
Exécuter l'outil :```bash python emploleaks.py
Avec le mode debug :```bash
python emploleaks.py -d
| Commande | Description |
|---|---|
help | Affiche l'aide générale |
help <comando> | Affiche l'aide d'une commande spécifique |
quit | Quitte l'application |
| Commande | Description |
|---|---|
add_company --name <nombre> | Ajoute une nouvelle entreprise |
La connexion à ClickHouse se configure dans config/tokens.ini :```ini
[clickhouse]
host = localhost
port = 9000
user = default
passwd =
dbname = credentials_db
Si ClickHouse est configuré dans `tokens.ini`, la connexion s'établit automatiquement au démarrage.
### Recherche d'Identifiants et de Violations de Données
| Commande | Description |
|---------|-------------|
| `find_passwords <modo>` | Recherche des identifiants dans ClickHouse + [ProxyNova COMB](https://www.proxynova.com/tools/comb/) (3,2 milliards d'identifiants). Modes : `find_all`, `only_usernames`, `only_emails` |
| `find_passwords <modo> --no-proxynova` | Recherche uniquement dans ClickHouse local |
| `find_passwords <modo> --no-clickhouse` | Recherche uniquement dans ProxyNova COMB (ne nécessite pas ClickHouse) |
| `find_passwords <modo> --email <email>` | Recherche des identifiants pour un email spécifique |
| `find_breaches` | Recherche les violations de données dans HIBP pour tous les emails de l'entreprise (nécessite le plugin `hibp` actif) |
**ProxyNova COMB** est une base de données publique contenant 3,2 milliards d'identifiants divulgués (Combination Of Many Breaches). Elle ne nécessite pas de clé API et est interrogée automatiquement à chaque recherche. Utilisez `--no-proxynova` pour la désactiver.
### Découverte d'Infrastructure
| Commande | Description |
|---------|-------------|
| `add_domain <dominio>` | Associe un domaine à l'entreprise sélectionnée (ex : `add_domain faradaysec.com`) |
| `discover` | Exécute l'énumération des sous-domaines pour tous les domaines de l'entreprise à l'aide de `assetfinder` (+ SecurityTrails optionnel), avec résolution DNS |
| `print --data domains` | Affiche les domaines enregistrés et le nombre de sous-domaines trouvés |
| `print --data subdomains` | Affiche tous les sous-domaines avec leur IP, leur source et la date de découverte |
Le module de découverte délègue l'énumération passive à [`assetfinder`](https://github.com/tomnomnom/assetfinder), qui agrège en interne les résultats de crt.sh, HackerTarget, BufferOver et d'autres sources sans clé API. Le binaire doit être dans `$PATH` (installation : `go install github.com/tomnomnom/assetfinder@latest`).
Optionnellement, si vous configurez une clé API SecurityTrails, ses sous-domaines sont fusionnés avec ceux d'assetfinder :```ini
[discovery]
# securitytrails_key = your_key_here
Holehe (recherche d'e-mail) : utilise la technique du 'mot de passe oublié' pour déterminer si un e-mail est enregistré sur chaque plateforme, sans alerter le propriétaire. Les plateformes sont configurées dans tokens.ini :```ini
[holehe]
platforms = google, discord, github, instagram, twitter, spotify, ...
**Maigret** (recherche de nom d'utilisateur) : cherche si un nom d'utilisateur existe sur plus de 500 plateformes de réseaux sociaux. Les noms d'utilisateur sont ajoutés manuellement par un employé depuis l'application web. Les plateformes sont optionnellement filtrées dans `tokens.ini`:```ini
[maigret]
# platforms = instagram, twitter, facebook, tiktok, reddit, github
| Commande | Description |
|---|---|
set_ai --endpoint <url> --key <key> --model <modelo> | Configure le fournisseur d'IA |
classify | Classe les employés dans des départements avec IA (sauvegardé dans la BDD) |
classify --force | Re-classe même s'ils ont déjà un département attribué |
La classification par IA analyse les titres/rôles des employés et les regroupe par département (Engineering, Security, Sales, etc.). Les départements sont persistés dans SQLite et visibles dans le rapport HTML et dans l'application web.
Fournisseurs pris en charge (toute API compatible OpenAI) :
set_ai --endpoint http://localhost:11434/v1 --model llama3set_ai --endpoint https://api.openai.com/v1 --key sk-... --model gpt-4o-miniDaemon autonome qui utilise un compte Telegram personnel (via Telethon) pour rejoindre des canaux/groupes approuvés, télécharger des fichiers .txt/.csv/.dat/.zip/.gz et les déposer dans leaks_data/telegram/<chat>/. Le import_leaks ultérieur les ingère dans ClickHouse en utilisant le parser agentique. Découplé du CLI — il s'exécute comme un processus séparé, il peut donc fonctionner 24h/24 sans que le CLI soit ouvert.
Configuration initiale (one-time) :
api_id et api_hash.config/tokens.ini : ```ini
[telegram]
api_id = 12345678
api_hash = abcd1234...
session = config/telegram.session
download_root = leaks_data/telegram
allowed_extensions = txt, csv, dat, zip, gz
default_backfill_limit = 10
Sous-commandes :
Nouvelles tables dans data/emploleaks.db :
| Table | Description |
|---|---|
telegram_groups | Capture des chats (chat_id, title, username, approved, backfill_limit, last_sync_at) |
telegram_files | Fichiers téléchargés avec déduplication par (chat_id, message_id) et par SHA-256 du contenu |
Démon en arrière-plan :```bash nohup python3.13 telegram_sync.py run --watch >> logs/telegram.log 2>&1 & echo $! > /tmp/telegram_daemon.pid
### Parser de Fuites 100% Agentique
Le module `utils/leak_parser.py` utilise **uniquement un agent d'IA** pour parser chaque fichier. Il n'y a pas de regex codées en dur (elles ont été supprimées car chaque nouveau format introduisait des bugs subtils d'extraction).
**Pipeline de l'agent:**```
1. Auto-detectar encoding (BOM sniffing): utf-8 / utf-8-sig / utf-16 / utf-32.
2. Sampling inteligente: tomar las primeras 80 líneas que parezcan credenciales
(con separadores típicos, alfanumérico >50%) — skipea banners ASCII art.
3. La IA recibe 50 líneas + system prompt con familias comunes de formato y
propone {separator, fields, skip_lines}.
4. Aplicamos el schema a la muestra SIN filtros → list of tuples.
5. Validamos con _is_clean_credential → score = % rows válidas.
6. Si score ≥ 0.8 y ≥ 5 rows → aplicar al archivo completo.
7. Si no → mandar al agente la (source_line ↔ extracción mala) en pares,
más checklist de errores típicos. Goto 3.
8. Hasta 7 iteraciones. Si no converge a 0.8: fallback al mejor schema si
alcanzó ≥ 0.7. Bajo eso → skip con warning (nunca ingerimos basura).
_is_clean_credential — validation transversale :
/ : \ espace, ne commence pas par http/android/ftp//./, maximum un :, sans espace, ne commence pas par préfixe URL.Déterminisme : temperature=0 dans tous les appels + mise en cache en mémoire dans un même run. Le même fichier produit le même schéma entre les runs → import_leaks est idempotent.
Coût typique : 1-3 appels API par fichier, ~$0.0001-$0.0005 avec gpt-4o-mini. Pour 12 fichiers : ~$0.005 = un demi-centime.
| Commande | Description |
|---|---|
python emploleaks.py --webapp | Lance l'application web (backend sur :8421, frontend sur :3421) |
L'application web permet :
Permet de rechercher des employés d'une entreprise sur LinkedIn en utilisant les cookies de session du navigateur, et de générer des emails professionnels potentiels. Capture automatiquement le logo de l'entreprise.
Options :
| Option | Description |
|---|---|
JSESSIONID | Cookie de session JSESSIONID de LinkedIn |
li-at | Cookie de session li_at de LinkedIn |
hide | Masquer la valeur de JSESSIONID lors de l'affichage (par défaut : yes) |
Commandes disponibles dans le plugin :
| Commande | Description |
|---|---|
run impersonate | S'authentifier en utilisant les cookies configurés |
run find <company_linkedin> <domaine_email> [--email-format FORMAT] | Rechercher des employés et générer des emails |
Formats d'email disponibles :
f_last (ex : [email protected]) et f.last (ex : [email protected])--email-format : utilise des espaces réservés {n} (initiale du prénom), {s} (nom de famille), {name} (nom complet), {l} (initiale du nom)
--email-format {n}.{s} génère [email protected]Exemple complet :``` emploleaks> add_company --name miempresa emploleaks> select_company --name miempresa emploleaks(miempresa)> use --plugin linkedin emploleaks(miempresa)(linkedin)> setopt JSESSIONID JSESSIONID: emploleaks(miempresa)(linkedin)> setopt li-at li-at: emploleaks(miempresa)(linkedin)> run impersonate emploleaks(miempresa)(linkedin)> run find miempresa miempresa.com --email-format {n}.{s}
### GitHub
Permet d'obtenir des informations sur les profils GitHub, de lister les dépôts et de scanner les secrets dans les dépôts avec gitleaks.
**Options :**
| Option | Description |
|--------|-------------|
| `token` | Jeton d'accès personnel GitHub |
| `blur` | Offusquer le jeton lors de l'affichage |
| `gitleaks_path` | Chemin vers le binaire gitleaks (par défaut : `gitleaks` dans PATH) |
| `max_repo_size` | Taille maximale du dépôt à analyser en Mo (par défaut : `15`) |
**Commandes disponibles dans le plugin :**
| Commande | Description |
|---------|-------------|
| `run stalk <username>` | Obtenir l'email d'un compte GitHub |
| `run get_repos <username>` | Lister les dépôts publics d'un utilisateur |
| `run find_secrets` | Scanner les secrets dans les dépôts des employés de l'entreprise |
| `run find_secrets --download-all` | Identique mais sans limite de taille |
**Exemple complet :**```
emploleaks(miempresa)> use --plugin github
emploleaks(miempresa)(github)> setopt token ghp_xxxxxxxxxxxx
emploleaks(miempresa)(github)> run find_secrets
emploleaks(miempresa)(github)> print --data secrets
Vérifie si les e-mails de l'entreprise apparaissent dans des fuites connues en utilisant l'API de HIBP.
Options :
| Option | Description |
|---|---|
apikey | Clé API de HaveIBeenPwned |
rate_limit | Délai entre les appels à l'API en secondes (par défaut: 2.0) |
Commandes disponibles dans le plugin :
| Commande | Description |
|---|---|
run find_breaches | Rechercher des fuites pour tous les e-mails de l'entreprise |
find_breaches | Commande directe (équivalent, nécessite le plugin hibp actif) |
Exemple complet :``` emploleaks(miempresa)> use --plugin hibp emploleaks(miempresa)(hibp)> setopt apikey <tu_api_key> emploleaks(miempresa)(hibp)> find_breaches emploleaks(miempresa)(hibp)> print --data breaches
## Base de données de fuites (ClickHouse)
EmploLeaks peut se connecter à sa propre base de données ClickHouse contenant des identifiants divulgués pour rechercher des mots de passe associés aux e-mails/noms d'utilisateur des employés découverts.
### Lancer ClickHouse avec Docker```bash
cd clickhouse-docker
docker compose up -d
Cela expose ClickHouse sur :
9000 (protocole natif TCP)8123 (interface HTTP)Le dossier leaks_data/ est monté en tant que volume en lecture seule dans le conteneur.
.txt, .csv, .dat, .zip, .gz) dans le dossier leaks_data/.Le parser détecte automatiquement les formats les plus courants :
- `email:password`
- `email:password:url`
- `email;password`
- `email|password`
- `url,email,password`
Pour les formats inconnus, utilise l'IA configurée (OpenAI/Ollama) pour analyser un échantillon du fichier et déterminer comment le parser. Utilisez `--no-ai` pour omettre la détection par IA.
Les fichiers `.zip` et `.gz` sont décompressés automatiquement avant d'être parsés.
### Rechercher des identifiants```
emploleaks(miempresa)> find_passwords only_emails
emploleaks(miempresa)> find_passwords find_all
emploleaks(miempresa)> print --data passwords
Si ClickHouse est configuré dans tokens.ini, la connexion est automatique au démarrage de l'outil.
credentials dans ClickHouse## Disclaimer
Cet outil est conçu uniquement à des fins éducatives, de recherche en sécurité et de tests de pentesting autorisés. L'utilisation de cet outil pour des activités malveillantes ou non autorisées est strictement interdite. Les utilisateurs sont responsables du respect de toutes les lois et conditions de service du projet.
select_company --name <nombre> |
| Sélectionne une entreprise pour travailler |
list_companies | Affiche toutes les entreprises |
delete_company --name <nombre> | Supprime une entreprise et toutes ses données |
| Commande | Description |
|---|
use --plugin <nombre> | Active un plugin (linkedin, github, hibp) |
deactivate | Désactive le plugin actuel |
show options | Affiche les options du plugin actif |
setopt <opción> [valor] | Configure une option du plugin (si aucune valeur n'est fournie, elle est demandée via une invite cachée) |
autosave --enable / --disable | Active/désactive la sauvegarde automatique de la configuration dans config/tokens.ini |
autoload --enable / --disable | Active/désactive le chargement automatique de la configuration depuis config/tokens.ini |
| Commande | Description |
|---|
connect_leaks | Connecter à ClickHouse en utilisant la configuration sauvegardée dans tokens.ini |
connect_leaks --host <host> --port <port> --save | Connecter avec des paramètres spécifiques et les sauvegarder pour les sessions futures |
disconnect_leaks | Déconnecter de la base de données ClickHouse |
import_leaks [directorio] | Importer des fichiers de credentials dans ClickHouse (par défaut: leaks_data/) |
import_leaks --no-ai | Importer uniquement les fichiers au format connu, sans utiliser IA |
create_db --user <user> --passwd <pass> --dbname <db> [--import-data <dir>] | Créer la base de données ClickHouse manuellement (legacy) |
| Commande | Description |
|---|
lookup_emails | Recherche les e-mails confirmés sur ~120 plateformes avec Holehe |
lookup_emails --include-potential | Inclut également les e-mails générés |
lookup_emails --email [email protected] | Recherche un e-mail spécifique |
lookup_emails --all | Recherche sur les 120+ plateformes (pas seulement celles configurées) |
lookup_emails --list-platforms | Liste toutes les plateformes disponibles |
lookup_profiles | Recherche des profils par nom d'utilisateur avec Maigret (nécessite des noms d'utilisateur chargés) |
lookup_profiles --employee "Juan" | Recherche uniquement pour un employé spécifique |
| Commande | Description |
|---|
print --data emails | Affiche les e-mails confirmés et potentiels |
print --data passwords | Affiche les identifiants trouvés |
print --data breaches | Affiche les brèches HIBP |
print --data gits | Affiche les comptes GitHub |
print --data twitters | Affiche les comptes Twitter/X |
print --data phones | Affiche les numéros de téléphone |
print --data websites | Affiche les sites web |
print --data secrets | Affiche les secrets trouvés dans les dépôts |
print --data domains | Affiche les domaines enregistrés |
print --data subdomains | Affiche les sous-domaines découverts |
print --data all | Affiche tout consolidé par employé |
print --data all --html | Génère un rapport HTML interactif avec photos |
print --data all --html --ai | Génère un rapport HTML regroupant les employés par département avec IA |
print --data <tipo> --export | Exporte les données vers un fichier CSV avec horodatage |
| Commande | Description |
|---|
login | Authentification initiale. Persiste la session dans config/telegram.session |
list_groups | Liste tous les chats/canaux où se trouve votre compte, et les capture dans SQLite |
approve <chat_id> [--limit N] | Marque un chat comme approuvé et exécute le backfill des N derniers messages |
unapprove <chat_id> | Retire l'approbation |
list_approved | Tableau des chats approuvés avec le comptage des fichiers téléchargés |
backfill <chat_id> [--limit N] | Retélécharge les N derniers messages d'un chat approuvé |
run [--watch] | Backfill de tous les approuvés ; avec --watch reste à écouter les événements NewMessage |
status | Résumé : approuvés / fichiers téléchargés / disque utilisé |
| Champ | Type | Description |
|---|
mail_username | String | Partie du nom d'utilisateur de l'email |
mail_domain | String | Domaine de l'email (sans TLD) |
mail_tld | String | TLD de l'email |
password | String | Mot de passe divulgué |
uri_subdomain | String | Sous-domaine du site où la fuite a eu lieu |
uri_domain | String | Domaine du site |
uri_tld | String | TLD du site |
| Table | Description |
|---|
companies | Entreprises enregistrées (nom, logo) |
employees | Employés découverts (nom, titre, photo, entreprise, département) |
emails | Emails confirmés (obtenus depuis contact_info de LinkedIn) |
potential_emails | Emails potentiels générés par format |
passwords | Mots de passe trouvés associés à des emails |
username_passwords | Mots de passe trouvés par nom d'utilisateur |
breaches | Fuites HIBP associées à des emails |
githubs | URLs de profils/dépôts GitHub |
twitters | URLs de profils Twitter/X |
phones | Numéros de téléphone |
websites | Sites web personnels |
secrets_repos | Secrets trouvés dans des dépôts avec gitleaks |
social_profiles | Profils sur réseaux sociaux (Holehe + Maigret) |
domains | Domaines de l'entreprise pour le discovery |
subdomains | Sous-domaines découverts (IP, source, date) |
usernames | Noms d'utilisateur associés aux employés pour Maigret |