
유출된 자격 증명으로 회사 구성원을 탐지하는 데 도움을 주는 OSINT 도구
EmploLeaks는 CLI 인터페이스를 갖춘 OSINT(오픈 소스 인텔리전스) 도구로, 대상 회사 직원에 대한 정보를 발견하고 상호 연관시키기 위해 설계되었습니다. LinkedIn 프로필 수집, 잠재적인 회사 이메일 생성, 유출 데이터베이스(내부적으로 ClickHouse 사용)에서 유출된 자격 증명 검색, HaveIBeenPwned를 통한 알려진 침해 사항 확인, 회사 인프라 발견, 소셜 미디어에서 직원 프로파일링을 수행할 수 있습니다. 모든 정보는 후속 분석을 위해 로컬 SQLite에 저장됩니다.
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
## 요구 사항
- Python 3.10+
- pip
- 인터넷 연결
- **선택 사항:** 로컬에서 ClickHouse를 실행하기 위한 Docker 및 Docker Compose
- **선택 사항:** 저장소 비밀 검색을 위한 [gitleaks](https://github.com/gitleaks/gitleaks)
- **선택 사항:** [HaveIBeenPwned](https://haveibeenpwned.com/API/Key) API 키
- LinkedIn 플러그인을 위한 LinkedIn 세션 쿠키 (`JSESSIONID` 및 `li_at`)
## 설치
1. 저장소를 클론합니다:```bash
git clone https://github.com/yourusername/emploleaks.git
cd emploleaks
3. (선택 사항) Docker로 ClickHouse를 실행하여 leaks 데이터베이스 설정:```bash
cd clickhouse-docker
docker compose up -d
cd ..
도구 실행:```bash python emploleaks.py
디버그 모드:```bash
python emploleaks.py -d
| 명령어 | 설명 |
|---|---|
help | 일반 도움말 표시 |
help <comando> | 특정 명령어의 도움말 표시 |
quit | 애플리케이션 종료 |
| 명령어 | 설명 |
|---|---|
add_company --name <nombre> | 새 회사 추가 |
select_company --name <nombre> | 작업할 회사 선택 |
list_companies |
ClickHouse 연결은 config/tokens.ini에 구성됩니다:```ini
[clickhouse]
host = localhost
port = 9000
user = default
passwd =
dbname = credentials_db
ClickHouse가 `tokens.ini`에 구성되어 있으면 시작 시 연결이 자동으로 설정됩니다.
### 자격 증명 및 침해 사고 검색
| Comando | Descripción |
|---------|-------------|
| `find_passwords <modo>` | ClickHouse + [ProxyNova COMB](https://www.proxynova.com/tools/comb/) (32억 개의 자격 증명)에서 자격 증명을 검색합니다. 모드: `find_all`, `only_usernames`, `only_emails` |
| `find_passwords <modo> --no-proxynova` | 로컬 ClickHouse에서만 검색 |
| `find_passwords <modo> --no-clickhouse` | ProxyNova COMB에서만 검색 (ClickHouse 불필요) |
| `find_passwords <modo> --email <email>` | 특정 이메일에 대한 자격 증명 검색 |
| `find_breaches` | 회사의 모든 이메일에 대해 HIBP에서 침해 사고 검색 (`hibp` 플러그인 활성화 필요) |
**ProxyNova COMB**는 32억 개의 유출된 자격 증명(Combination Of Many Breaches)을 포함하는 공개 데이터베이스입니다. API 키가 필요 없으며 각 검색 시 자동으로 조회됩니다. 비활성화하려면 `--no-proxynova`를 사용하세요.
### 인프라 발견
| Comando | Descripción |
|---------|-------------|
| `add_domain <dominio>` | 선택한 회사에 도메인을 연결합니다 (예: `add_domain faradaysec.com`) |
| `discover` | `assetfinder`를 사용하여 회사의 모든 도메인에 대해 서브도메인 열거를 실행하고 DNS를 확인합니다 (선택적으로 SecurityTrails 포함) |
| `print --data domains` | 등록된 도메인과 발견된 서브도메인 수를 표시합니다 |
| `print --data subdomains` | 모든 서브도메인을 IP, 소스 및 발견 날짜와 함께 표시합니다 |
Discovery 모듈은 수동 열거를 [`assetfinder`](https://github.com/tomnomnom/assetfinder)에 위임하며, 내부적으로 crt.sh, HackerTarget, BufferOver 및 기타 소스의 결과를 API 키 없이 수집합니다. 바이너리가 `$PATH`에 있어야 합니다 (설치: `go install github.com/tomnomnom/assetfinder@latest`).
선택적으로 SecurityTrails API 키를 구성하면 해당 서브도메인이 assetfinder의 결과와 병합됩니다.```ini
[discovery]
# securitytrails_key = your_key_here
Holehe (이메일 조회): '비밀번호 찾기' 기술을 사용하여 각 플랫폼에 이메일이 등록되어 있는지 확인하며, 소유자에게 알리지 않습니다. 플랫폼은 tokens.ini에 구성됩니다:```ini
[holehe]
platforms = google, discord, github, instagram, twitter, spotify, ...
**Maigret** (username lookup): username이 500개 이상의 소셜 미디어 플랫폼에 존재하는지 검색합니다. Username은 웹앱에서 직원이 수동으로 추가합니다. 플랫폼은 선택적으로 `tokens.ini`에서 필터링됩니다.```ini
[maigret]
# platforms = instagram, twitter, facebook, tiktok, reddit, github
| 명령어 | 설명 |
|---|---|
set_ai --endpoint <url> --key <key> --model <model> | AI 제공자 구성 |
classify | AI를 사용하여 직원을 부서로 분류 (DB에 저장됨) |
classify --force | 이미 부서가 할당된 경우에도 재분류 |
AI 분류는 직원의 직함/역할을 분석하여 부서(Engineering, Security, Sales 등)별로 그룹화합니다. 부서 정보는 SQLite에 유지되며 HTML 보고서와 웹앱에서 확인할 수 있습니다.
지원되는 제공자 (OpenAI 호환 API 사용):
set_ai --endpoint http://localhost:11434/v1 --model llama3set_ai --endpoint https://api.openai.com/v1 --key sk-... --model gpt-4o-miniTelegram 개인 계정(Telethon 사용)을 이용해 승인된 채널/그룹에 가입하여 .txt/.csv/.dat/.zip/.gz 파일을 다운로드하고 leaks_data/telegram/<chat>/ 경로에 저장하는 독립형 데몬입니다. 이후 import_leaks가 이를 수집하여 에이전트 파서를 사용해 ClickHouse로 가져옵니다. CLI에서 분리되어 별도 프로세스로 실행되므로 CLI가 열려 있지 않아도 24시간 작동 가능합니다.
초기 설정 (최초 1회):
api_id와 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
하위 명령어:
data/emploleaks.db의 새 테이블:
| 테이블 | 설명 |
|---|---|
telegram_groups | 채팅 스냅샷 (chat_id, title, username, approved, backfill_limit, last_sync_at) |
telegram_files | 중복 제거된 다운로드 파일: (chat_id, message_id) 및 콘텐츠 SHA-256 기준 |
백그라운드 데몬:```bash nohup python3.13 telegram_sync.py run --watch >> logs/telegram.log 2>&1 & echo $! > /tmp/telegram_daemon.pid
### Parser de Leaks 100% Agéntico
El módulo `utils/leak_parser.py` usa **únicamente un agente de IA** para parsear cada archivo. No hay regex hardcodeadas (fueron eliminadas porque cada formato nuevo introducía bugs sutiles de extracción).
**Pipeline del agente:**```
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 — 교차 검증:
/ : \ space 없음, http/android/ftp//로 시작하지 않음./ 없음, 최대 하나의 :, 공백 없음, URL 접두사로 시작하지 않음.결정론적: 모든 호출에서 temperature=0 + 동일한 실행 내에서 메모리 내 캐싱. 동일한 파일은 실행 간 동일한 스키마를 생성 → import_leaks는 멱등적입니다.
일반 비용: 파일당 API 호출 1-3회, gpt-4o-mini 기준 ~$0.0001-$0.0005. 12개 파일: ~$0.005 = 0.5센트.
| 명령 | 설명 |
|---|---|
python emploleaks.py --webapp | 웹앱 실행 (백엔드 :8421, 프론트엔드 :3421) |
웹앱을 통해 다음을 수행할 수 있습니다:
브라우저 세션 쿠키를 사용하여 LinkedIn에서 회사 직원을 검색하고 잠재적인 회사 이메일을 생성할 수 있습니다. 자동으로 회사 로고를 캡처합니다.
옵션:
| 옵션 | 설명 |
|---|---|
JSESSIONID | LinkedIn 세션 쿠키 JSESSIONID |
li-at | LinkedIn 세션 쿠키 li_at |
hide | 표시 시 JSESSIONID 값 숨기기 (기본값: yes) |
플러그인 내 사용 가능한 명령:
| 명령 | 설명 |
|---|---|
run impersonate | 설정된 쿠키를 사용하여 인증 |
run find <company_linkedin> <dominio_email> [--email-format FORMAT] | 직원 검색 및 이메일 생성 |
사용 가능한 이메일 형식:
f_last (예: [email protected]) 및 f.last (예: [email protected])--email-format 사용자 정의: 플레이스홀더 {n} (이름 이니셜), {s} (성), {name} (전체 이름), {l} (성 이니셜) 사용
--email-format {n}.{s}는 [email protected]을 생성합니다.전체 예시:``` 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
GitHub 프로필 정보를 가져오고, 리포지토리를 나열하며, gitleaks를 사용하여 리포지토리에서 시크릿을 스캔할 수 있습니다.
**옵션:**
| 옵션 | 설명 |
|--------|-------------|
| `token` | GitHub 개인 액세스 토큰 |
| `blur` | 표시 시 토큰 난독화 |
| `gitleaks_path` | gitleaks 바이너리 경로 (기본값: PATH 내 `gitleaks`) |
| `max_repo_size` | 분석할 최대 리포지토리 크기(MB) (기본값: `15`) |
**플러그인 내 사용 가능한 명령어:**
| 명령어 | 설명 |
|---------|-------------|
| `run stalk <username>` | GitHub 계정 이메일 가져오기 |
| `run get_repos <username>` | 사용자의 공개 리포지토리 나열 |
| `run find_secrets` | 회사 직원의 리포지토리에서 시크릿 스캔 |
| `run find_secrets --download-all` | 동일하지만 크기 제한 없음 |
**전체 예시:**```
emploleaks(miempresa)> use --plugin github
emploleaks(miempresa)(github)> setopt token ghp_xxxxxxxxxxxx
emploleaks(miempresa)(github)> run find_secrets
emploleaks(miempresa)(github)> print --data secrets
회사 이메일이 알려진 데이터 유출에 포함되어 있는지 HIBP API를 통해 확인합니다.
옵션:
| 옵션 | 설명 |
|---|---|
apikey | HaveIBeenPwned의 API 키 |
rate_limit | API 호출 간 지연 시간(초) (기본값: 2.0) |
플러그인 내에서 사용 가능한 명령어:
| 명령어 | 설명 |
|---|---|
run find_breaches | 회사 모든 이메일에 대한 데이터 유출 검색 |
find_breaches | 직접 명령어 (동일 기능, hibp 플러그인 활성화 필요) |
전체 예제:``` emploleaks(miempresa)> use --plugin hibp emploleaks(miempresa)(hibp)> setopt apikey <tu_api_key> emploleaks(miempresa)(hibp)> find_breaches emploleaks(miempresa)(hibp)> print --data breaches
## 유출 데이터베이스 (ClickHouse)
EmploLeaks는 자체 ClickHouse 데이터베이스에 연결하여 유출된 자격 증명을 통해 발견된 직원의 이메일/사용자 이름과 연결된 비밀번호를 검색할 수 있습니다.
### Docker로 ClickHouse 실행하기```bash
cd clickhouse-docker
docker compose up -d
ClickHouse가 다음 포트에서 노출됩니다:
9000 (기본 TCP 프로토콜)8123 (HTTP 인터페이스)leaks_data/ 폴더는 컨테이너 내에서 읽기 전용 볼륨으로 마운트됩니다.
.txt, .csv, .dat, .zip, .gz)을 leaks_data/ 폴더에 넣습니다.파서는 가장 일반적인 형식을 자동으로 감지합니다:
- `email:password`
- `email:password:url`
- `email;password`
- `email|password`
- `url,email,password`
알 수 없는 형식의 경우, 설정된 AI(OpenAI/Ollama)를 사용하여 파일 샘플을 분석하고 파싱 방법을 결정합니다. AI 감지를 생략하려면 `--no-ai`를 사용하세요.
`.zip` 및 `.gz` 파일은 파싱 전에 자동으로 압축이 풀립니다.
### 자격 증명 검색```
emploleaks(miempresa)> find_passwords only_emails
emploleaks(miempresa)> find_passwords find_all
emploleaks(miempresa)> print --data passwords
Si ClickHouse está configurado en tokens.ini, la conexión es automática al iniciar la herramienta.
credentials 테이블 구조## 면책 조항
이 도구는 교육, 보안 연구 및 승인된 침투 테스트 목적으로만 설계되었습니다. 악의적이거나 승인되지 않은 활동에 이 도구를 사용하는 것은 엄격히 금지됩니다. 사용자는 모든 법률 및 프로젝트 서비스 약관을 준수할 책임이 있습니다.
| 모든 회사 표시 |
delete_company --name <nombre> | 회사 및 모든 데이터 삭제 |
| 명령어 | 설명 |
|---|
use --plugin <nombre> | 플러그인 활성화 (linkedin, github, hibp) |
deactivate | 현재 플러그인 비활성화 |
show options | 활성 플러그인의 옵션 표시 |
setopt <option> [value] | 플러그인 옵션 설정 (값이 전달되지 않으면 숨겨진 프롬프트로 입력) |
autosave --enable / --disable | config/tokens.ini에 설정 자동 저장 활성화/비활성화 |
autoload --enable / --disable | config/tokens.ini에서 설정 자동 로드 활성화/비활성화 |
| 명령어 | 설명 |
|---|
connect_leaks | tokens.ini에 저장된 구성으로 ClickHouse 연결 |
connect_leaks --host <host> --port <port> --save | 특정 매개변수로 연결하고 향후 세션을 위해 저장 |
disconnect_leaks | ClickHouse 데이터베이스 연결 해제 |
import_leaks [directory] | 자격 증명 파일을 ClickHouse로 가져오기 (기본값: leaks_data/) |
import_leaks --no-ai | AI를 사용하지 않고 알려진 형식의 파일만 가져오기 |
create_db --user <user> --passwd <pass> --dbname <db> [--import-data <dir>] | 수동으로 ClickHouse 데이터베이스 생성 (레거시) |
| 명령어 | 설명 |
|---|
lookup_emails | Holehe를 사용해 ~120개 플랫폼에서 확인된 이메일 검색 |
lookup_emails --include-potential | 생성된 이메일도 포함 |
lookup_emails --email [email protected] | 특정 이메일 검색 |
lookup_emails --all | 120개 이상의 플랫폼에서 검색(설정된 것만 아님) |
lookup_emails --list-platforms | 사용 가능한 모든 플랫폼 나열 |
lookup_profiles | Maigret로 사용자명으로 프로필 검색(로드된 사용자명 필요) |
lookup_profiles --employee "Juan" | 특정 직원에 대해서만 검색 |
| 명령어 | 설명 |
|---|
print --data emails | 확인된 이메일 및 잠재적 이메일 표시 |
print --data passwords | 발견된 자격 증명 표시 |
print --data breaches | HIBP 유출 정보 표시 |
print --data gits | GitHub 계정 표시 |
print --data twitters | Twitter/X 계정 표시 |
print --data phones | 전화번호 표시 |
print --data websites | 웹사이트 표시 |
print --data secrets | 저장소에서 발견된 비밀 정보 표시 |
print --data domains | 등록된 도메인 표시 |
print --data subdomains | 발견된 서브도메인 표시 |
print --data all | 직원별로 통합된 모든 정보 표시 |
print --data all --html | 사진이 포함된 대화형 HTML 보고서 생성 |
print --data all --html --ai | AI를 사용하여 부서별로 직원을 그룹화한 HTML 보고서 생성 |
print --data <type> --export | 타임스탬프가 포함된 CSV 파일로 데이터 내보내기 |
| 명령어 | 설명 |
|---|
login | 초기 인증. config/telegram.session에 세션 유지 |
list_groups | 계정이 속한 모든 채팅/채널을 나열하고 SQLite에 스냅샷 저장 |
approve <chat_id> [--limit N] | 채팅을 승인으로 표시하고 최근 N개 메시지의 백필 실행 |
unapprove <chat_id> | 승인 제거 |
list_approved | 승인된 채팅 테이블 (다운로드된 파일 수 포함) |
backfill <chat_id> [--limit N] | 승인된 채팅의 최근 N개 메시지를 다시 다운로드 |
run [--watch] | 모든 승인된 채팅 백필; --watch 옵션으로 NewMessage 이벤트 수신 대기 |
status | 요약: 승인됨 / 다운로드된 파일 / 사용된 디스크 |
| Campo | Tipo | Descripción |
|---|
mail_username | String | 이메일 사용자 부분 |
mail_domain | String | 이메일 도메인 (TLD 제외) |
mail_tld | String | 이메일 TLD |
password | String | 유출된 비밀번호 |
uri_subdomain | String | 유출된 사이트의 서브도메인 |
uri_domain | String | 사이트 도메인 |
uri_tld | String | 사이트 TLD |
| Tabla | Descripción |
|---|
companies | 등록된 회사 (이름, 로고) |
employees | 발견된 직원 (이름, 직책, 사진, 회사, 부서) |
emails | 확인된 이메일 (LinkedIn의 contact_info에서 획득) |
potential_emails | 형식에 따라 생성된 잠재적 이메일 |
passwords | 이메일에 연결된 발견된 비밀번호 |
username_passwords | 사용자 이름으로 발견된 비밀번호 |
breaches | 이메일에 연결된 HIBP 유출 정보 |
githubs | GitHub 프로필/저장소 URL |
twitters | Twitter/X 프로필 URL |
phones | 전화번호 |
websites | 개인 웹사이트 |
secrets_repos | gitleaks를 사용하여 저장소에서 발견된 비밀 |
social_profiles | 소셜 미디어 프로필 (Holehe + Maigret) |
domains | 디스커버리용 회사 도메인 |
subdomains | 발견된 서브도메인 (IP, 소스, 날짜) |
usernames | Maigret을 위한 직원과 연결된 사용자 이름 |