PhishGuard AI è un sistema avanzato di rilevamento phishing che combina tecniche di machine learning, analisi strutturale, elaborazione del linguaggio naturale e visione artificiale per identificare siti web malevoli con elevata precisione.
Obiettivi:
- Sviluppare un sistema multi-livello per il rilevamento automatico di siti phishing
- Combinare analisi di URL, contenuto HTML e aspetto visivo per una valutazione completa
- Minimizzare i falsi positivi mantenendo un'elevata capacità di identificazione delle minacce
- Creare un sistema scalabile ed efficiente per la protezione in tempo reale
Funzionamento: Il nostro approccio si basa su tre pilastri fondamentali:
- Analisi strutturale - Estrazione di 98 caratteristiche dagli URL e dal codice HTML
- Analisi semantica - Elaborazione del contenuto testuale con modelli BERT per rilevare anomalie linguistiche
- Analisi visiva - Utilizzo di reti neurali convoluzionali per identificare elementi visivi tipici del phishing
Questi tre livelli di analisi vengono integrati attraverso un sistema di ensemble ottimizzato che bilancia i punteggi di ciascun modello per massimizzare precisione e recall.
Utilizzo: PhishGuard AI è progettato per funzionare sia come sistema di monitoraggio continuo che per analisi puntuali:
- Può essere integrato in soluzioni di sicurezza esistenti per la protezione di organizzazioni
- Consente l'analisi di URL sospetti in tempo reale
- Fornisce report dettagliati con spiegazione delle caratteristiche più significative
- Si puo' auto-aggiornare con nuovi pattern di phishing grazie all'apprendimento continuo
Caratteristiche principali:
- 🤖 Multi-Model Ensemble: Combinazione ottimizzata di 7+ algoritmi ML (Random Forest, XGBoost, LightGBM, CatBoost, LSTM, BERT, CNN)
- 🔍 98 Feature Estratte: Analisi completa di URL, HTML e caratteristiche visive
- 🌐 API REST: Interfaccia web per analisi batch e singoli URL
- ⚡ Task Paralleli: Sistema asincrono con Celery per elaborazioni concurrent
- 📊 Dashboard Interattiva: Visualizzazione risultati e metriche di performance
- 🔄 Auto-Aggiornamento: Capacità di apprendimento continuo con nuovi pattern
Risultati: Le nostre valutazioni mostrano che l'approccio ensemble supera significativamente i singoli modelli, raggiungendo metriche di performance elevate anche su dataset complessi e siti di phishing sofisticati.
File: clean_phishing, data_collection, screenshot_capture, clean
Siti legittimi:
- Scaricamento da Tranco del dataset con il milione dei siti più visitati.
- Estrazione dei primi 10.000 siti per assicurarsi della loro legittimità.
- Per ogni sito selezionato casualmente, estrazione di 3 URL unici tramite CommonCrawl, con controllo degli errori (es. 404) e passaggio al successivo se necessario.
- Implementazione di delays tra le richieste per rispettare le policy dei server.
- Pulizia degli URL per prevenire eventuali problematiche nel download degli HTML.
- Salvataggio degli HTML nella cartella
raw/legite creazione del CSV legit_sites (inresults) contenente: nome del dominio, URL e percorso dell'HTML.
Siti di phishing:
- Download regolare dei CSV aggiornati da PhishStats.
- Pulizia dei dati con selezione dei siti aventi uno Score superiore a 5 (scala 1-10).
- Estrazione di informazioni quali data, punteggio, URL e indirizzo IP (data, punteggio e IP mantenuti per possibili utilizzi futuri).
- Automatizzazione del processo per aggiornare il CSV esistente con i nuovi dati.
- Salvataggio degli HTML nella cartella
raw/phishinge creazione di un CSV phish_sites (inresults) con: nome del dominio, URL e percorso dell'HTML.
Screenshot e Verifica Dati:
- Cattura parallela degli screenshot di tutti i siti usando screenshot_capture con multi-threading.
- Verifica dell'integrità dei dati scaricati tramite clean per garantire la coerenza tra i file HTML e i record nei CSV.
- Ridimensionamento degli screenshot per standardizzare le dimensioni per l'addestramento dei modelli visivi.
File: merge_results_csvs, feature_extraction, parsing, train_csv_creation
1. Feature basate su URL (feature_extraction): Estratte 55 feature dagli URL, tra cui:
- Statistiche di Base:
- Lunghezza URL
- Lunghezza hostname (
f1-f2)
- Caratteri Speciali:
- Conteggio di punti, trattini
- Presenza di @, ?, &, ecc. (
f4-f19)
- Termini Comuni:
- Presenza di www, .com, http(s) (
f21-f25)
- Presenza di www, .com, http(s) (
- Analisi Numerica:
- Rapporto cifre nell'URL
- Rapporto cifre nell'hostname (
f26-f27)
- Analisi del Dominio:
- Rilevamento Punycode (
f28) - Presenza di porte (
f29) - Analisi TLD (
f30-f31) - Analisi sottodomini (
f32-f33)
- Rilevamento Punycode (
- Indicatori di Sicurezza:
- URL basati su IP (
f3) - TLD sospetti (
f55) - Rilevamento abuso nomi brand (
f52-f54) - Servizi di URL shortening (
f36)
- URL basati su IP (
- Analisi Lessicale:
- Statistiche parole in URL, hostname e percorso (
f40-f50) - Rilevamento keyword di phishing (
f51)
- Statistiche parole in URL, hostname e percorso (
2. Analisi del Contenuto HTML (parsing):
- Analisi delle Risorse:
- Conteggio risorse HTTPS/HTTP
- Rilevamento e conteggio domini esterni
- Calcolo rapporti tra risorse
- Analisi Struttura DOM:
- Profondità DOM e conteggio nodi
- Rapporto foglie DOM
- Rilevamento form
- Elementi di Sicurezza:
- Presenza sigilli SSL
- Rilevamento input password
- Campi input nascosti
- Conteggio IFrame
- Analisi Contenuti:
- Rilevamento lingua e incongruenze
- Struttura heading (conteggio h1, h2)
- Analisi link e immagini
- Elementi JavaScript (script inline ed esterni)
- Rilevamento uso cookie
- Indicatori di Brand e Affidabilità:
- Rilevamento logo
- Presenza copyright
- Analisi favicon
3. Elaborazione Dati (merge_results_csvs, train_csv_creation):
- Unione dataset legittimi e phishing (sites)
- Combinazione delle feature (URL + HTML), normalizzazione e preprocessing (train_csv_creation)
- Generazione dataset finale con etichette binarie (
phishing/legittimo) (features)
File: ml_models, merge_text_data, clean_text_data, bert_model, cnn_model
-
Modelli Strutturali (ml_models):
- Random Forest/XGBoost/LightGBM/CatBoost/Logistic Regression/Linear SVM/Multi-layer Perceptron
- Addestramento su features numeriche estratte da HTML/URL
- Ottimizzazione tramite cross-validation e grid search
-
NLP (bert_model, merge_text_data, clean_text_data):
- Preparazione del testo HTML con merge e pulizia dedicati
- Fine-tuning di BERT per classificazione di phishing testuale
- Analisi del contenuto semantico delle pagine web
-
Deep Learning (cnn_model):
- CNN specializzata per analisi degli screenshot
- Identificazione di pattern visivi caratteristici del phishing
- Riconoscimento di clonazioni di siti legittimi
Riguardo ai Modelli presi da HuggingFace credo che ottengano risultati così bassi perché addestrati su dataset con siti legittimi facilmente distinguibili da quelli di phishing, mentre il nostro dataset tende ad essere molto vario e complesso. Credo questo perché tendono entrambi a classificare anche molti siti legittimi come siti di phishing.
Inoltre riguardo al primo, oltre all'HTML stesso, è stato addestrato anche su questi:
- rec_id - record number
- url - URL of the webpage
- website - Filename of the webpage (i.e. 1635698138155948.html)
- result - Indicates whether a given URL is phishing or not (0 for legitimate and 1 for phishing).
- created_date - Webpage downloaded date
e questo avrebbe potuto minare la capacità del modello di lavorare solo ed esclusivamente su file HTML (dargli l'url non avrebbe senso perché abbiamo già altri modelli per quello e la data abbiamo deciso in precedenza di non darla ai modelli per non rischiare che fossero eccessivamente influenzati da questa feature).
-
Ensemble di modelli:
- Combinazione ottimizzata dei punteggi dai diversi classificatori
- Sistema di voting pesato con threshold configurabile
- Implementazione di regole di decisione personalizzate
-
Test e validazione:
- Valutazione su dataset indipendente
- Test real-time su URL forniti dall'utente
- Generazione di report dettagliati con analisi delle feature critiche
Per finire abbiamo implementato le API necessarie all'utilizzo di questo sistema. Aggiunt celery come task manager per permettere il lancio di più richieste in parallelo.
- REPERIMENTO DEI SITI
-
Scarichiamo a mano da Tranco un csv con il primo milione di siti più visitati negli ultimi 30 giorni e ci limitiamo a tenere i primi 10mila (csv in data/external: top10k.csv)
-
Una volta al giorno scarichiamo a mano da PhishStats un csv con i siti di phishing rilevati negli ultimi 30 giorni che viene aggiornato ogni 90 minuti.
Il csv viene scaricato in external e nella cella 9 del main, richiamando le funzioni in clean_phishing.py, i nuovi record vengono aggiunti al vecchio csv phish_score_cleaned.csv che viene aggiornato e, una volta finito questo processo, il file appena scaricato viene rimosso. -
I siti che utilizziamo per testare i risultati dei nostri modelli li prendiamo da un'altra fonte rispetto agli altri. Utilizziamo un csv preso da HuggingFace e scarichiamo anch'esso in external: test.csv.
- ESTRAZIONE DEI DATI DAI SITI
-
Nella cella 7 del main richiamando la funzione
download_legit_datain data_collection.py, per ogni esecuzione, scarichiamo casualmente gli HTML di 1000 dei siti legittimi indicati in top10k.csv che finiscono in raw/legit. Di ciascun sito scarichiamo gli HTML di 3 sue diverse pagine.
In results creiamo in tempo reale legit_sites.csv con il nome del dominio, gli url e il percorso del file HTML appena salvato.
Facciamo attenzione a ricevere output comprensivi così da visualizzare immediatamente se l'HTML di un sito è stato scaricato correttamente, il numero di siti scaricati ed eventuali eccezioni o errori.
Inoltre ci assicuriamo subito che non provi a scaricare dati dai domini dei siti di cui abbiamo già gli HTML e che sono salvati in legit_sites.csv. -
Nella cella 10 del main richiamando la funzione
download_phishing_datain data_collection.py scarichiamo gli HTML dei siti di phishing indicati in phish_score_cleaned.csv che finiscono in raw/phishing.
In results ci salviamo phish_sites.csv che è stato creato in tempo reale con il nome del dominio, gli url e il percorso del file HTML appena salvato.
Facciamo attenzione a ricevere output comprensivi così da visualizzare immediatamente se l'HTML è stato scaricato correttamente, se era già stato scaricato (di conseguenza facendo in modo che non lo riscarichi), se il sito risulta irraggiungibile o se il browser restituisce altri errori.
In caso un sito risulti irraggiungibile rimuoviamo il record corrispondente da phish_score_cleaned.csv in modo che, se dovesse essere aggiornato il dataset, non consideri questi siti ( generalmente i siti di phishing risultano irraggiungibili perché bloccati, di conseguenza provare una nuova volta a scaricare dati che li riguardano non avrebbe senso ). -
Nella cella 15 del main richiamando la funzione
batch_capture_screenshots_parallelin screenshot_capture.py scarichiamo gli screenshot di tutti i siti presenti in sites.csv ( bisognerà assicurarsi che questo file sia stato aggiornato con eventuali nuovi record prima di poter eseguire questa cella ).
Gli screenshot vengono scaricati in data/raw/screenshots /legit e /phishing mentre in results viene creato in tempo reale screenshot_results.csv.
Qui usiamo 8 threads ( potrebbe dover essere necessario modificarne il numero in base alle prestazioni del proprio computer - in caso modificare il parametromax_workersnella funzionebatch_capture_screenshots_parallelin screenshot_capture.py ) contemporaneamente per poter catturare il maggior numero di screenshot il più velocemente possibile, riprovando 2 volte in caso di errori nella cattura dello screenshot del dominio, incrementando ogni volta il tempo di attesa per assicurarsi che lo screenshot venga catturato correttamente.
Nel main, dopo aver stampato il numero di siti ancora da processare, visualizziamo in modo distinto se gli screenshot di ciascun dominio sono stati scaricati correttamente o se ci sono stati degli errori.
- PREPROCESSING DEI DATI SCARICATI
-
Nelle celle 12 e 13 del main, grazie anche alla funzione
verify_data_integrityin clean.py, ci assicuriamo che tutti gli HTML scaricati siano anche presenti in phish_sites.csv e che se ci sono dei record nel csv di cui non abbiamo l'HTML vengano rimossi. -
Nelle celle 17 e 19 del main ripuliamo gli screenshot e screenshot_results.csv, innanzitutto eliminando quelli di dimensioni troppo ridotte e, in seguito, ridimensionandoli tutti alla definizione media di tutti gli screenshot scaricati (per facilitare il successivo addestramento della CNN).
Poi controlliamo anche che tutti gli screenshot scaricati siano anche presenti in screenshot_results.csv e che se ci sono dei record nel csv di cui non abbiamo lo screenshot vengano rimossi.
- ESTRAZIONE DELLE FEATURE
-
Nella cella 21 del main richiamiamo la funzione
process_directorydi parsing.py, iniziamo il parsing degli HTML estraendo le varie feature per creare html_phishing_numeric.csv, html_phishing_text.csv, html_legit_numeric.csv, html_legit_text.csv in processed.
I csv "numerici" verranno usati insieme a quelli con le feature degli url per addestrare Random Forest, XGBoost, LightGBM, CatBoost, Logistic Regression, Linear SVM e un Multi-Layer Perceptron. I csv "testuali" verranno usati per addestrare il modello BERT. -
Nelle celle 23 e 24 del main, tramite le funzioni
merge_and_save_sitesemerge_and_save_html_featuresin merge_results_csvs.py, mergiamo i file legit_sites.csv e phish_sites.csv in sites.csv nella cartella results e tutti i file "numerici" creati in precedenza in html_features.csv nella cartella trainingdata. -
Nella cella 25 del main richiamiamo le funzioni
create_features_dataframeesave_featuresdel file feature_extraction.py per creare url_features.csv da tutti i siti presenti in sites.csv. -
Nella cella 27 del main utilizzando la funzione
create_final_csvdel file train_scv_creation.py creiamo merged_features.csv.
Il file viene creato direttamente tramite l'utilizzo delle funzioni usate nelle celle precedenti e non dai file appena creati.
- ADDESTRAMENTO DEI MODELLI
-
Dalla cella 30 alla cella 50 del main impieghiamo le varie funzioni presenti in ml_models.py per addestrare i modelli (Random Forest, XGBoost, LightGBM, CatBoost, Logistic Regression, Linear SVM, Multi-Layer Perceptron) sulle features degli URL e su quelle numeriche degli HTML, predire e visualizzare i loro risultati sul test.csv e infine salvarli nella cartella models.
-
Dalla cella 52 alla cella 64 del main, richiamando la funzione
merge_text_featuresdi merge_text_data.py uniamo i file con le features testuali degli HTML (html_phishing_text.csv e html_legit_text.csv), grazie aclean_text_featuresdi clean_text_data.py facciamo un leggero preprocessing di ciò che otteniamo e con ilBertPhishingClassifierda bert_model.py, addestriamo il nostro modello BERT.
Infine facciamo le predizioni su html_test_text_labeled.csv, stampiamo risultati e statistiche finali e salviamo il modello nella cartella bert all'interno di models. Il file html_test_text_labeled.csv in trainingdata che creiamo in seguito corrisponde ai dati finali su cui viene addestrato il BERT. -
Dalla cella 66 alla cella 71 del main utilizziamo cnn_model.py per addestrare una Rete Neurale Convoluzionale (CNN) sugli screenshot delle pagine web catturati in precedenza. Il processo include:
- Caricamento degli screenshot dalle cartelle legit e phishing utilizzando screenshot_results.csv
- Salvataggio delle predizioni nella cartella "cnn" in "models"
- Valutazione sugli screenshot dei siti presenti in test_screenshots.csv (salvati in test_legit e test_phishing) e generazione di metriche (accuracy, precision, recall, F1-score)
- Visualizzazione delle performance tramite curve ROC e confusion matrix
- Salvataggio del modello addestrato come cnn_model.h5 nella cartella cnn all'interno di models
-
AGGREGAZIONE DEI RISULTATI DEI DATI Nelle celle 73-81 del main, dedicate all'Aggregazione dei Risultati e al Decision Engine, implementiamo il sistema completo:
-
CARICAMENTO DEI MODELLI ADDESTRATI
Utilizzo di joblib per caricare il modello random_forest.pkl addestrato.
Caricamento del modello BERT dalla cartella bert.
Importazione della CNN da cnn_model.h5.
Importazione delle reference hash ID da test.csv per il tracciamento coerente delle predizioni. -
GENERAZIONE DELLE PROBABILITÀ PER MODELLO
Estrazione delle feature specifiche per ciascun modello dai file test_features.csv e hash_id&text_for_bert.csv (quest'ultimo creato apposta per il funzionamento delll'Ensemble).
Creazione di un DataFrame temporaneo per ogni modello contenente le probabilità di phishing. -
DECISION ENGINE CON REGOLE COMPOSITE
Implementazione di 2 approcci di ensemble (simple averaging, weighted averaging).
Test sistematico delle combinazioni di pesi per ciascun modello:- Valutazione di ogni combinazione tramite F1-score
Applicazione di regole di decisione personalizzate:
- Rule 1: Se RF > 0.8 → phishing
- Rule 2: Se CNN > 0.99 & RF > 0.5 → phishing
- Rule 3: Se BERT > 0.99 & RF > 0.5 → phishing
Ottimizzazione della soglia per il massimo bilanciamento tra precisione e richiamo.
Conclusione: la combinazione di threshold 0.6 con le regole definite fornisce i risultati migliori.
Generazione delle predizioni finali. -
ANALISI E VALUTAZIONE
Creazione di model_predictions_comparison.csv con tutte le probabilità e predizioni finali.
Calcolo di metriche di performance (accuracy, precision, recall, F1-score).
Visualizzazione della confusion matrix per l'ensemble finale.
Esportazione della configurazione del modello di ensemble finale in ensemble_model_config.json.
-
-
TEST SUL DATASET DI VALIDAZIONE
Dalla cella 83 alla 97 del main abbiamo scaricato e preprocessato i dati relativi ai siti presenti nel dataset di test, e infine abbiamo fatto le predizioni ottenendo un risultato che indica un gran numero di siti di phishing in confronto a quelli legittimi.
1️⃣ Un nuovo URL sospetto viene scaricato e analizzato
2️⃣ Ogni livello fornisce un punteggio di rischio
3️⃣ Il sistema aggrega i risultati e decide se è phishing o no
4️⃣ Se il sito è sospetto → alert.
- Python 3.10+
- Conda o pip per la gestione dei pacchetti
- Redis server (per task asincroni)
- Chrome/Chromium browser (per screenshot)
# Clona il repository
git clone https://github.com/tuousername/PhishGuard-AI.git
cd PhishGuard-AI
# Crea ambiente conda
conda env create -f environment.yml
conda activate phish_env10Il progetto utilizza Redis come broker per i task asincroni con Celery. È necessario avere Redis in esecuzione:
Opzione 1 - Installazione locale nel progetto:
# Scarica Redis per Windows da: https://github.com/microsoftarchive/redis/releases
# Estrai il contenuto in una cartella del progetto (es: redis/, Redis-5.0.14/, ecc.)
# Avvia Redis server dalla cartella estratta
cd redis # o il nome della tua cartella Redis
redis-server.exe redis.windows.conf # Windows
# oppure
redis-server redis.conf # Linux/MacOpzione 2 - Installazione di sistema:
# Windows (usando Chocolatey)
choco install redis-64
# Linux (Ubuntu/Debian)
sudo apt-get install redis-server
# Mac (usando Homebrew)
brew install redis
# Avvia Redis
redis-serverUtilizzo nel progetto: Redis viene configurato in celery_worker.py come broker per gestire:
- Task di predizione su URL singoli (
predict_single_url_task) - Task di predizione batch su file CSV (
predict_from_csv_task) - Elaborazione asincrona delle richieste API
# Terminale 1: Avvia Redis server
redis-server # Se installato globalmente
# oppure dalla cartella locale:
# cd redis && redis-server.exe redis.windows.conf
# Terminale 2: Avvia worker Celery
celery -A celery_worker worker --loglevel=info
# Terminale 3: Avvia l'applicazione Flask
python app.py💡 Configurazione personalizzata: Se Redis è installato su host/porta diversi, modifica le impostazioni in configs/config.yaml:
redis:
host: "localhost"
port: 6379
db: 0Modifica il file configs/config.yaml per personalizzare:
- Soglie di classificazione
- Parametri modelli ML
- Configurazioni API
- Path datasets
PhishGuard-AI/
├── src/ # Codice sorgente principale
│ ├── Idontcarecookies/ # Estensione browser (generata automaticamente)
│ ├── screenshot_capture.py
│ ├── phishing_classifier.py
│ └── ...
├── data/ # Dataset e file dati
│ ├── raw/ # Dati grezzi (HTML, screenshot)
│ ├── processed/ # Dati preprocessati
│ ├── results/ # Output e risultati
│ └── trainingdata/ # Dati per addestramento
├── models/ # Modelli ML salvati
├── configs/ # File di configurazione
├── templates/ # Template HTML Flask
├── redis/ # Server Redis (opzionale, se installato localmente)
├── app.py # Applicazione Flask principale
├── celery_worker.py # Worker per task asincroni
└── main.ipynb # Notebook principale per training
POST /predict_url
Content-Type: application/json
{
"url": "https://example-suspicious-site.com"
}POST /predict_csv
Content-Type: multipart/form-data
file: urls.csvGET /task_status/<task_id>| Modello | Accuracy | Precision (0) | Precision (1) | Recall (0) | Recall (1) |
|---|---|---|---|---|---|
| Random Forest | 87% | 95% | 69% | 88% | 84% |
| BERT | 87% | 94% | 69% | 89% | 82% |
| CNN | 77% | 79% | 74% | 79% | 74% |
| Ensemble | 94% | 95% | 88% | 97% | 84% |
- Fork del progetto
- Crea feature branch (
git checkout -b feature/AmazingFeature) - Commit changes (
git commit -m 'Add AmazingFeature') - Push al branch (
git push origin feature/AmazingFeature) - Apri una Pull Request
-
Errore "ConnectionError: Redis connection failed":
- Verifica che Redis sia in esecuzione con
redis-cli ping - Controlla che la porta 6379 sia disponibile
- Su Windows, usa
redis-server.exe redis.windows.conf
- Verifica che Redis sia in esecuzione con
-
Errore "redis-server non riconosciuto":
- Installa Redis globalmente o aggiungi la cartella Redis al PATH di sistema
- Oppure avvia dalla cartella Redis:
cd redis && redis-server.exe - Modifica le impostazioni in
configs/config.yamlse necessario
- Worker non si avvia:
- Controlla che Redis sia raggiungibile
- Verifica le dipendenze Python con
pip list | grep celery - Su Windows potrebbe essere necessario usare
eventlet:pip install eventlet
Questo progetto è sotto licenza AGPL v3 - vedi il file LICENSE per i dettagli.
- Tranco per i dataset di siti legittimi
- PhishStats per i dati di phishing
- HuggingFace per i modelli BERT pre-addestrati
- La community open-source per le librerie utilizzate