
PhishCollector ist ein Forschungsframework zum Sammeln, Analysieren und Verfolgen von Phishing-Websites.
PhishCollector ist ein Forschungs-Framework zum Sammeln, Analysieren und Verfolgen von Phishing-Seiten. Es ist bewusst als Ausgangspunkt konzipiert – die Erkennungsregeln, Technologiesignaturen, Wortlisten und Plugins sind alles einfache Datenstrukturen, die Forscher lesen, erweitern und an ihre eigene Bedrohungslandschaft anpassen sollen.
Reichen Sie eine verdächtige URL ein und PhishCollector wird:
Alle Ergebnisse sind über eine REST-API, ein Web-Dashboard und eine CLI zugänglich.


cp .env.example .env # configure (see below)
docker compose up --build # starts db + app + frontend
| Dienst | URL |
|---|---|
| GUI | http://localhost:3000 |
| API-Dok | http://localhost:8000/docs |
| DB | localhost:5432 |
Alle Einstellungen sind Umgebungsvariablen mit dem Präfix PHISH_. Kopieren Sie .env.example in .env und passen Sie sie an.
Das Weiterleiten des gesamten ausgehenden Datenverkehrs über einen Proxy hält Ihre Analysten-IP vor dem Phishing-Server verborgen.
PHISH_PROXY_URL=socks5://127.0.0.1:9050
PHISH_PROXY_SSL_VERIFY=true # Tor intercepts TLS nicht
Burp fungiert als TLS-Man-in-the-Middle und präsentiert für jede HTTPS-Verbindung sein eigenes CA-Zertifikat. Ohne Deaktivierung der SSL-Verifikation schlägt jede HTTPS-Anfrage über den Proxy fehl.
PHISH_PROXY_URL=http://127.0.0.1:8080
PHISH_PROXY_SSL_VERIFY=false # erforderlich für Burp / abhörbereite Proxys
Hinweis:
PHISH_PROXY_SSL_VERIFY=falsebetrifft nur ausgehende HTTPS-Verbindungen des Python-Backends (Plugins, Fingerprinter, Spider). Der Playwright-Browser arbeitet ohnehin mitignore_https_errors=trueunabhängig von dieser Einstellung.
Warnung: Setzen Sie
PHISH_PROXY_SSL_VERIFY=falseniemals ohne einen konfigurierten Proxy – dies würde die Zertifikatsprüfung für alle externen API-Aufrufe (URLhaus, VirusTotal) deaktivieren.
Basis-Pfad: /api/v1
Vollständige interaktive Dokumentation unter /docs (Swagger UI).
curl -X POST http://localhost:8000/api/v1/collections \
-H 'Content-Type: application/json' \
-d '{"url": "https://suspicious-site.example.com", "use_wordlist": true}'
# Installieren (im Container oder lokalem venv mit requirements.txt)
pip install -e .
# Eine URL übermitteln und auf Abschluss warten
phishcollector collect https://target.example.com --wait
# Mit Wortlisten-Fuzzing
phishcollector collect https://target.example.com --wordlist --wait
# Letzte Aufträge auflisten
phishcollector list
# Vollständige Details anzeigen
phishcollector detail <job-id>
# Screenshot herunterladen
phishcollector screenshot <job-id> -o capture.png
# Suche nach Technologie-Stack / Favicon-Hash / Land
phishcollector search --tech WordPress --country RU
phishcollector search --favicon-hash -1234567890
Erfordert einen kostenlosen Auth-Key von auth.abuse.ch.
PHISH_URLHAUS_ENABLED=true
PHISH_URLHAUS_API_KEY=<ihr-auth-key>
Erfordert einen kostenlosen oder kostenpflichtigen API-Key von virustotal.com.
PHISH_VIRUSTOTAL_API_KEY=<ihr-key>
Wenn eine URL noch nicht von VT analysiert wurde, übermittelt PhishCollector sie zum Scannen und ruft das Ergebnis automatisch alle 30 Sekunden erneut ab, bis es aufgelöst ist.
Jedes Plugin ist eine einzelne Datei in phishcollector/plugins/, die eine asynchrone Funktion bereitstellt:
# phishcollector/plugins/myplugin.py
from . import CheckResult
async def check(url: str, proxy_url=None, ssl_verify=True) -> CheckResult:
# Ihre Feed-/API-Abfrage hier
return CheckResult(
plugin_name="myplugin",
status="malicious", # malicious | suspicious | clean | unknown | error
score=0.95, # 0.0–1.0, oder None
result={"raw": ...}, # wird als JSONB gespeichert, im GUI angezeigt
)
Dann registrieren Sie es in phishcollector/plugins/runner.py:
from .myplugin import check as myplugin_check
tasks.append(myplugin_check(url, proxy_url=settings.proxy_url, ssl_verify=settings.proxy_ssl_verify))
Es sind keine weiteren Änderungen erforderlich – das Ergebnis wird automatisch gespeichert, im Dashboard angezeigt und in den Bedrohungswert einbezogen.
Die Erkennungsengine ist bewusst als einfache, lesbare Daten gehalten, damit Forscher sie an die Kits und Kampagnen anpassen können, die sie verfolgen. Alles befindet sich in einer Datei:
phishcollector/collector/fingerprint.py
PHISHING_PATTERNS — Regex-Regeln, die gegen gerendertes HTML + JS geprüft werdenJeder Eintrag ist ein (regex, human_readable_label)-Tupel, gruppiert in Kategorien. Ein Treffer in einer beliebigen Kategorie wird im Tab Indikatoren angezeigt und zählt zum Bedrohungswert hinzu.
PHISHING_PATTERNS: dict[str, list[tuple[str, str]]] = {
"credential_harvest": [
(r"document\.getElementById\(['\"]password['\"]", "JS reads password field by ID"),
(r"btoa\s*\(.*password", "Base64-encoding a password"),
# add your own rules here …
],
"obfuscation": [
(r"\beval\s*\(", "eval() usage"),
(r"atob\s*\(", "Base64 decoding at runtime"),
],
"exfiltration": [
(r"api\.telegram\.org/bot", "Telegram bot exfiltration"),
(r"@(?:gmail|yahoo|hotmail|outlook)\.com", "Freemail address in code"),
],
"antibot": [
(r"navigator\.webdriver", "WebDriver property check"),
(r"ipqualityscore|ipqs\.com", "IPQS anti-bot service"),
],
"kit_indicators": [
(r"office365|microsoft365", "Office 365 phishing theme"),
(r"paypal.*limit|limit.*paypal", "PayPal limitation theme"),
# brand-new kit you spotted? add a rule here:
(r"docusign.*sign|e.?sign.*document", "DocuSign lure"),
(r"(?:dhl|fedex|ups).*track", "Parcel delivery lure"),
],
}
So fügen Sie eine Regel hinzu: Fügen Sie ein Tupel zur entsprechenden Kategorieliste hinzu. So fügen Sie eine Kategorie hinzu: Fügen Sie einen neuen Schlüssel hinzu – der Kategoriename erscheint automatisch als Abschnittsüberschrift im Tab „Indikatoren“.
# Beispiel: Verfolgen eines neu entdeckten Kit-Fingerabdrucks
"my_campaign_2024": [
(r"panel\.php\?cmd=send", "Known C2 panel path"),
(r"X-Mailer:\s*PHPMailer\s*5\.2\.1", "Specific PHPMailer version used by kit"),
],
TECH_SIGNATURES — TechnologieerkennungSignaturen, die gegen HTML, Antwort-Header, Cookies und die endgültige URL abgeglichen werden. Erkannte Technologien erscheinen im Panel Technologien und sind über alle Sammlungen hinweg durchsuchbar.
TECH_SIGNATURES: dict[str, dict] = {
"WordPress": {
"html": [r"wp-content", r"wp-includes"],
"url": [r"/wp-login\.php"],
"cookies": ["wordpress_"],
},
# Fügen Sie alles hinzu, was Sie verfolgen möchten:
"GoPhish": {
"html": [r"rid=[a-zA-Z0-9]{20}"],
"url": [r"/track\?rid="],
},
"Evilginx": {
"url": [r"phishlets"],
"html": [r"__utmz.*evilginx"],
},
}
Jeder Signaturschlüssel (der Technologiename) wird über GET /search?technology=GoPhish zu einem durchsuchbaren String.
Die Standard-Spider-Wortliste befindet sich unter wordlists/phishing_paths.txt – ein Pfad pro Zeile, # für Kommentare. Sie enthält häufige Phishing-Kit-Pfade (gate.php, send.php, result.php, Admin-Panels usw.). Fügen Sie Pfade für Kits hinzu, die Sie regelmäßig antreffen:
# Neu beobachtete Kit-Pfade
/panel/send.php
/b374k.php
/uploads/gate.php
Content-Type: text/plain und Content-Disposition: attachment ausgeliefert – der Browser lädt es herunter, anstatt es darzustellen.hmac.compare_digest, um Timing-Angriffe zu verhindern.X-Frame-Options: DENY, und Referrer-Policy: no-referrer bereit.Artefakte werden in PHISH_DATA_DIR (Standard /data, per Docker gemountetes Volume) geschrieben:
/data/
screenshots/ <collection-id>.png
html/ <collection-id>.html
assets/
<collection-id>/
<sha256-prefix>.js
<sha256-prefix>.css
Alles andere (Fingerabdrücke, HTTP-Protokolle, Spider-Ergebnisse, Plugin-Ergebnisse, Tags, Notizen) lebt in PostgreSQL.
phishcollector/
collector/
browser.py # Playwright Capture, Stealth-JS, UA-Rotation
fingerprint.py # Alle Fingerprinting-Proben + PHISHING_PATTERNS + TECH_SIGNATURES
spider.py # Link-Extraktion, robots.txt, Sitemap, Wortlisten-Fuzzing
orchestrator.py # Job-Lebenszyklus: verbindet alle Module
plugins/
__init__.py # CheckResult-Dataclass
urlhaus.py # abuse.ch URLhaus-Plugin
virustotal.py # VirusTotal v3 Plugin
runner.py # Führt aktivierte Plugins parallel aus
api/
routes.py # FastAPI-Endpunkte
main.py # App-Einstiegspunkt, CORS, Auth-Middleware
models.py # SQLAlchemy ORM-Modelle
config.py # Pydantic-Einstellungen (Umgebungsvariablen)
database.py # Engine, Session-Factory, Schema-Migrationen
frontend/
app.js # Vanilla-JS SPA
style.css # Cyber-Terminal-UI
nginx.conf # Reverse-Proxy + Sicherheitsheader
wordlists/
phishing_paths.txt # Standard-Spider-Wortliste
# Nur die Datenbank starten
docker compose up db -d
# API lokal ausführen
pip install -r requirements.txt
playwright install chromium
uvicorn phishcollector.main:app --reload
# Tests ausführen (falls vorhanden)
pytest
| Variable | Standard | Beschreibung |
|---|
PHISH_DATABASE_URL | postgres://… | PostgreSQL-DSN |
PHISH_API_KEY | (leer) | Falls gesetzt, erfordern alle Anfragen X-API-Key: <value> |
PHISH_DATA_DIR | /data | Speicherort für Screenshots, HTML, Assets |
PHISH_BROWSER_TIMEOUT | 30000 | Seitenlade-Timeout in ms |
PHISH_REQUEST_TIMEOUT | 15 | HTTP-Subrequest-Timeout in Sekunden |
PHISH_MAX_SPIDER_PAGES | 50 | Maximale Anzahl von URLs, die der Spider pro Auftrag besucht |
PHISH_MAX_ASSET_SIZE | 10485760 | Maximale JS/CSS-Dateigröße zum Speichern (Bytes) |
PHISH_PROXY_URL | (leer) | Ausgehender Proxy – siehe unten |
PHISH_PROXY_SSL_VERIFY | true | Setzen Sie false für abhörbereite Proxys – siehe unten |
PHISH_URLHAUS_ENABLED | false | Aktiviert die URLhaus-Reputationsprüfung |
PHISH_VIRUSTOTAL_API_KEY | (leer) | VirusTotal v3 API-Key (leer lassen zum Deaktivieren) |
| Methode | Pfad | Beschreibung |
|---|
POST | /collections | Eine URL zur Sammlung einreichen |
GET | /collections | Alle Sammlungen auflisten |
GET | /collections/{id} | Vollständige Details + Fingerabdruck |
GET | /collections/{id}/screenshot | Ganzseitiges PNG |
GET | /collections/{id}/html | Erfasstes HTML (als Klartext heruntergeladen) |
GET | /collections/{id}/requests | Netzwerkanfragen-Protokoll |
GET | /collections/{id}/spider | Spider-Ergebnisse |
GET | /collections/{id}/plugins | Ergebnisse der Bedrohungsanalyse-Plugins |
POST | /collections/{id}/plugins/refresh | Plugins erneut ausführen (z. B. ausstehendes VT-Ergebnis abrufen) |
POST | /collections/{id}/rescan | Dieselbe URL erneut sammeln (Original bleibt erhalten) |
PATCH | /collections/{id} | Tags und Notizen aktualisieren |
GET | /collections/{id}/export?format=json|csv | Sammlungsdaten exportieren |
DELETE | /collections/{id} | Eine Sammlung und alle ihre Artefakte löschen |
GET | /search | Fingerabdrücke nach IP, Favicon-Hash, Technologie, Land, Titel durchsuchen |