Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
sshfinder — Rilevamento parallelo di servizi SSH e strumento di audit di sicurezza che esegue scansioni su qualsiasi porta, valida i banner SSH e verifica i metodi di autenticazione, la crittografia debole, la vulnerabilità Terrapin e le chiavi host riutilizzate tra host e intervalli CIDR. | Kitploit
Strumenti/GitHubGitHub/kabiri-labs/sshfinder
RicognizioneScanner di VulnerabilitàScansione PorteAnalisi delle VulnerabilitàRaccolta InformazioniSicurezza di ReteCrittografiaPenetration Testing
GitHubkabiri-labs/sshfinder

sshfinder

Rilevamento parallelo di servizi SSH e strumento di audit di sicurezza che esegue scansioni su qualsiasi porta, valida i banner SSH e verifica i metodi di autenticazione, la crittografia debole, la vulnerabilità Terrapin e le chiavi host riutilizzate tra host e intervalli CIDR.

331 mese faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Vedi Repository
Condividi

sshfinder

CI version

Trova ogni servizio SSH sulla tua rete, valuta se soddisfa i tuoi standard e ricevi una notifica quando qualcosa cambia.

sshfinder è un singolo file Python senza dipendenze richieste. Puntalo su un intervallo CIDR e scopre SSH ovunque sia effettivamente in ascolto — non solo sulla porta 22 — conferma che ciascuno parli davvero SSH, valuta la sua postura crittografica e restituisce un codice di uscita non zero quando qualcosa viola la tua policy.


Il problema che risolve

La maggior parte dei team non riesce a rispondere a tre domande sul proprio parco SSH:

  1. Quanti servizi SSH abbiamo e dove? Non quante macchine — quanti servizi SSH in ascolto, incluso quello sulla porta 2222 che un appaltatore ha configurato nel 2019.
  2. Soddisfano tutti il nostro standard? Login con password disabilitato, nessun cifrario compromesso, non esposti a Terrapin. In modo dimostrabile, non per asserzione.
  3. Cosa è cambiato da ieri sera? Una chiave host che si è spostata. Un servizio che è apparso. L'autenticazione con password che è tornata attiva dopo una ricostruzione.

Gli strumenti esistenti rispondono ciascuno a parte di questo e si fermano:

Questo divario — scoperta e valutazione e un verdetto, in un unico artefatto — è ciò che questo strumento esiste per colmare. Se devi solo controllare un singolo host che già conosci, usa ssh-audit; va più in profondità su un singolo servizio di quanto faccia questo.

A chi è destinato

  • Sicurezza interna e inventario degli asset. Costruisci e mantieni un registro di ogni servizio SSH nel parco, esportato in CSV o JSON.
  • Team di piattaforma e SRE con un obbligo di conformità. Dimostra, su base programmata e con un codice di uscita, che nessun host in una VPC accetta il login con password o offre crittografia debole.
  • Chiunque gestisca una migrazione post-quantistica. Un numero per quanto del parco non riesca ancora a negoziare lo scambio di chiavi post-quantistico, e esattamente quali servizi siano quelli.

I penetration tester troveranno utili l'audit e il pivot SOCKS, ma lo strumento è modellato attorno all'esecuzione ripetuta della stessa scansione contro un parco che possiedi, non attorno a un impegno una tantum.


Avvio rapido

root@kitploit:~
git clone https://github.com/kabiri-labs/sshfinder.git
cd sshfinder
python sshfinder.py 10.0.0.0/24 -p 22,2222

Nessuna installazione, nessuna dipendenza. Richiede Python 3.9+.

Le tre cose che fa, in tre comandi:

root@kitploit:~
# 1. INVENTARIO — che SSH c'è in giro?
python sshfinder.py 10.0.0.0/24 --audit --format csv -o ssh-inventory.csv

# 2. VERDETTO — soddisfa il nostro standard? (esce con 3 se no)
python sshfinder.py 10.0.0.0/24 -p 22,2222 --policy baseline

# 3. DERIVA — cosa è cambiato da ieri sera?
python sshfinder.py 10.0.0.0/24 -p 22,2222 --baseline yesterday.json \
    --fail-on-drift

1. Inventario

La scansione di tutte le 65535 porte è l'impostazione predefinita, perché un servizio SSH su una porta non standard è esattamente quello che nessuno ha annotato. Ogni porta aperta viene etichettata, quindi una porta aperta non viene mai contata silenziosamente come SSH:

root@kitploit:~
=== 10.0.0.5 ===
  open: 10.0.0.5:22 [SSH], 10.0.0.5:8080 [not ssh]
  SSH  10.0.0.5:22  (SSH-2.0-OpenSSH_7.4)

La conferma è un vero scambio di identificazione RFC 4253, non uno sguardo ai primi byte sul filo. I server che stampano prima un banner legale, che aspettano che il client si identifichi, o il cui banner arriva suddiviso tra segmenti TCP vengono tutti riconosciuti correttamente — ciascuno di questi è un falso negativo in un'implementazione ingenua.

Aggiungi --audit per il quadro completo di ogni servizio:

root@kitploit:~
  SSH  10.0.0.5:22  (SSH-2.0-OpenSSH_7.4)
       host key: ssh-ed25519 SHA256:T/ZM4jOL4amTsO5K3AaCdg2...
       auth: publickey, password  [!] password auth enabled
       [!] Terrapin (CVE-2023-48795): VULNERABLE
       [!] weak ciphers: aes128-cbc
           aes128-cbc [weak]: CBC mode is vulnerable to the SSH plaintext-recovery attack (CVE-2008-5161) and, …

Chiavi host SSH condivise (possibili host condivisi/clonati):
  SHA256:T/ZM4jOL4amTsO5K3AaCdg2...
    -> 10.0.0.5:22, 10.0.0.9:22

Quell'ultimo blocco merita attenzione: una chiave host riutilizzata tra macchine di solito significa VM clonate o un'immagine condivisa, e significa che compromettere un host compromette l'identità di tutti.

Prontezza post-quantistica

OpenSSH 10.0 ha reso mlkem768x25519-sha256 lo scambio di chiavi predefinito, e 10.1 avverte che le sessioni classiche sono aperte alla cattura store now, decrypt later. --pq-report risponde direttamente alla domanda a livello di parco, usando solo il KEXINIT — quindi non richiede librerie di terze parti:

root@kitploit:~
python sshfinder.py 10.0.0.0/24 -p 22,2222 --pq-report
root@kitploit:~
Post-quantum readiness:
  1/3 service(s) negotiate post-quantum key exchange with a current client
  [!] no PQ key exchange offered (1):
        10.0.0.2:22
  [!] pre-standard PQ only (1) - looks post-quantum but is not:
        10.0.0.3:22
  2 service(s) exposed to store-now-decrypt-later capture; upgrade to OpenSSH 9.0+

La categoria pre-standard è quella che coglie di sorpresa. Un server che pubblicizza [email protected] o una bozza Kyber sembra post-quantistico in un dump di algoritmi, ma OpenSSH ha eliminato quel set di parametri ritirato nel 2020 — quindi un client attuale non trova alcun metodo comune e ripiega sulla crittografia classica. Contato come pronto, sarebbe peggio che non guardare affatto.

2. Verdetto

Un report descrive un problema. Una policy asserisce un problema e può far fallire una build:

root@kitploit:~
python sshfinder.py 10.0.0.0/24 -p 22,2222 --policy baseline; echo "exit $?"
root@kitploit:~
Policy 'baseline':
  No password login, no Terrapin exposure, no weak algorithms.
  1/3 service(s) pass
  [FAIL] 1 service(s):
        10.0.0.3:22
          - password_auth: password login accepted: publickey, password
          - terrapin: vulnerable to Terrapin (CVE-2023-48795)
          - post_quantum (warn): post-quantum readiness is absent, ready required
  [warn] 1 service(s):
        10.0.0.2:22
          - post_quantum (warn): post-quantum readiness is absent, ready required
exit 3

Tre policy sono incluse — baseline, strict e pq — denominate per il risultato che impongono piuttosto che per una distribuzione. Le regole portano una severità fail o warn e --fail-on decide quali soglie, quindi un team può adottare uno standard più severo prima come avviso e promuoverlo in seguito senza modificare nulla.

Scrivi le tue come JSON:

root@kitploit:~
{
  "name": "house-rules",
  "description": "What we expect of every SSH service.",
  "rules": [
    {"check": "password_auth", "severity": "fail"},
    {"check": "terrapin", "severity": "fail"},
    {"check": "post_quantum", "require": "ready", "severity": "warn"},
    {"check": "forbid", "field": "ciphers",
     "algorithms": ["3des-cbc", "arcfour"], "severity": "fail"},
    {"check": "require", "field": "kex_algorithms",
     "algorithms": ["curve25519-sha256"], "severity": "fail"}
  ]
}

Controlli: password_auth, terrapin, weak_algorithms, post_quantum (con require: ready, legacy o absent), e forbid / require su un field di kex_algorithms, host_key_algorithms, ciphers o macs.

Qualsiasi altra cosa è un errore grave quando la policy viene caricata, prima che la scansione inizi. Una soglia che salta silenziosamente una regola che non comprende è peggio di nessuna soglia: l'esecuzione diventa verde e nessuno scopre che il controllo non è mai stato eseguito.

root@kitploit:~
$ sshfinder 10.0.0.0/24 --policy house.json
sshfinder: error: rule 1: unknown check 'pasword_auth'
  (known: forbid, password_auth, post_quantum, require, terrapin, weak_algorithms)

3. Deriva

Eseguilo ogni notte contro il report di ieri e vedi solo ciò che si è mosso:

root@kitploit:~
# Notturno, in cron:
python sshfinder.py 10.0.0.0/24 -p 22,2222 --audit --json -o today.json
python sshfinder.py 10.0.0.0/24 -p 22,2222 --baseline yesterday.json \
    --fail-on-drift
root@kitploit:~
Baseline drift (vs yesterday.json):
  [alert] 2 change(s):
        10.0.0.5:22  SHA256:T/ZM4jO... -> SHA256:9aKm2Qx...; expected only after a rebuild or key rotation
        10.0.0.3:22  password login is now accepted
  [added] 1 change(s):
        10.0.0.9:2222  new SSH service (SSH-2.0-OpenSSH_9.6)
  [improved] 1 change(s):
        10.0.0.7:22  post-quantum readiness rose from absent to ready

Una chiave host che è cambiata è il segnale più importante qui — prevista solo dopo una ricostruzione o una rotazione delle chiavi, e merita un'occhiata ogni altra volta.

Solo alert controlla --fail-on-drift. Un host dismesso è normale avvicendamento, e far fallire un lavoro notturno su questo addestrerebbe tutti a ignorare il risultato.

Il confronto è attento a non inventare cambiamenti. Un campo che nessuna scansione ha misurato non viene mai segnalato come cambiato, vengono confrontati solo gli host presenti in entrambe le scansioni, e una baseline che contiene le impronte delle chiavi host fa eseguire anche la sonda profonda a questa scansione — quindi una riscansione superficiale non viene mai letta come se ogni chiave fosse sparita.


Formati di output

--format text|json|sarif|csv, opzionalmente scritto su un file con -o.

  • csv — una riga per ogni servizio SSH confermato. La forma in cui un inventario degli asset viene effettivamente ordinato e filtrato.
  • json — il report nativo e il formato di input per --baseline.
  • sarif — SARIF 2.1.0, validato contro lo schema OASIS. I risultati sono ancorati a posizioni logiche host:port e portano impronte stabili, quindi un consumatore tiene traccia dello stesso risultato tra esecuzioni notturne piuttosto che aprire un nuovo avviso ogni volta.
  • --stream — eventi JSON delimitati da nuove righe emessi mentre ogni porta si apre e ogni servizio viene confermato, quindi una pipeline può agire sul primo risultato mentre la scansione è ancora in esecuzione:
root@kitploit:~
python sshfinder.py 10.0.0.0/24 --stream -q | jq -c 'select(.event=="ssh")'
root@kitploit:~
{"event":"ssh","elapsed":0.164,"host":"10.0.0.5","port":22,"banner":"SSH-2.0-OpenSSH_9.6"}
{"event":"ssh","elapsed":0.881,"host":"10.0.0.9","port":2222,"banner":"SSH-2.0-dropbear"}

Su SARIF e GitHub code scanning. I risultati SARIF devono portare una posizione dell'artefatto non vuota o upload-sarif rifiuta il file, quindi viene emesso un URI sintetico ssh://host:port accanto alla posizione logica. Non risolve a un file nel tuo repository, quindi gli avvisi appaiono senza un'ancora di codice. Trattalo come SARIF per gli strumenti di sicurezza in generale — il visualizzatore SARIF di VS Code, Azure DevOps, archiviazione — non come un modo per annotare una diff.

Codici di uscita

Il punto centrale delle funzionalità di policy e deriva, quindi vale la pena dichiararli con precisione:

Un errore grave supera un verdetto di policy, e un verdetto di policy supera la deriva. Se nulla era raggiungibile, la scansione non ha dimostrato nulla sulla conformità in entrambi i casi, quindi ottieni 1 piuttosto che un pass o fail fuorviante; e fallire uno standard dichiarato è un risultato più specifico di "qualcosa è cambiato".


Installazione

La scansione principale, la validazione del banner e le parti senza dipendenze di --audit (inventario degli algoritmi, flag di crittografia debole, Terrapin, prontezza post-quantistica) non richiedono altro che Python 3.9+.

root@kitploit:~
# Consigliato: sblocca le impronte delle chiavi host, l'enumerazione dei metodi di autenticazione e
# la correlazione delle chiavi condivise in --audit, oltre a --validate paramiko.
pip install -r requirements.txt

# Opzionale, solo per scansioni SYN a metà apertura (richiede root):
pip install scapy>=2.5

Opzioni

--scan-method auto seleziona la scansione SYN quando viene eseguita come root con Scapy installato, altrimenti ripiega sulla scansione connect senza privilegi. SOCKS non può essere combinato con una scansione SYN — SOCKS5 trasporta flussi TCP, non pacchetti grezzi.

Scansione tramite un host di salto

root@kitploit:~
python sshfinder.py 10.0.0.0/24 -p 22 --socks user:[email protected]:1080

La scoperta, lo scambio di banner e l'audit attraversano tutti il pivot, quindi i risultati non sono mai mezzo-tunnelizzati. Un proxy non raggiungibile viene segnalato come errore di scansione, mai come "nessun SSH trovato".

Scansione della produzione in sicurezza

--max-rate limita le sonde al secondo nell'intera scansione. La concorrenza limita quante connessioni sono aperte contemporaneamente; questo limita la velocità con cui se ne avviano di nuove, che è il tetto che devi poter promettere prima di scansionare qualsiasi cosa sotto regole di ingaggio.


Come funziona

Note di implementazione, per quando il comportamento sopra richiede una spiegazione.

Il motore di scansione. Ogni connessione in volo è guidata da un singolo thread tramite un loop di eventi del sistema operativo (epoll/kqueue/select), quindi la concorrenza costa un descrittore di file piuttosto che un thread del sistema operativo, e ogni host viene risolto una volta piuttosto che una volta per porta. Una scansione completa 1–65535 gira circa 6× più veloce di un design a thread pool.

Porte SSH per prime. Le poche porte su cui SSH vive realmente (22, 2222, 22222, …) vengono sondate all'inizio di ogni scansione. In una scansione completa, il primo servizio SSH confermato appare in circa 0,2 secondi invece di 16.

Una stretta di mano per servizio. Il socket che ha scoperto una porta aperta viene passato direttamente allo scambio di banner, quindi un servizio SSH confermato costa una stretta di mano TCP piuttosto che due.

Timeout adattivo. Le sonde attendono quanto il percorso giustifica, usando lo stimatore del tempo di andata e ritorno smussato di RFC 6298 — quello che TCP stesso usa — alimentato da ogni sonda risposta e condiviso nell'intera scansione. --timeout diventa un tetto piuttosto che un costo fisso: su un host vivo ma per lo più filtrato questo vale circa 5× con risultati identici. Solo una risposta definitiva gli insegna qualcosa; un timeout non dice nulla sul percorso e non viene mai reimmesso.

Due punti mantengono deliberatamente l'intero tetto. Lo scambio di banner e l'audit non si adattano mai, perché la velocità con cui un host completa una stretta di mano TCP non dice nulla sulla velocità con cui il suo demone SSH compone un saluto. Nemmeno la ri-sonda finale delle porte usuali di SSH, poiché un SYN perso lì è l'unica perdita che costa davvero a questo strumento un risultato.

Uscita anticipata. Un host che non risponde affatto nelle sue prime poche centinaia di sonde viene segnalato come non reattivo piuttosto che consumare un timeout per ogni porta rimanente. Poiché le porte di SSH vengono scansionate per prime, un servizio vivo viene sempre visto prima che questo possa scattare; --no-early-exit forza l'intero intervallo.

Limitato per progettazione. Un budget di socket a livello di processo derivato dal limite dei descrittori di file impedisce a una scansione di grandi dimensioni di esaurire i descrittori e segnalare erroneamente servizi vivi come filtrati. L'espansione dei target controlla la dimensione di una rete prima di materializzarla, quindi un /8 fuori posto viene rifiutato in millisecondi piuttosto che consumare un gigabyte di memoria.

Giudizi algoritmici curati. Ogni algoritmo segnalato proviene da una tabella esplicita con una severità e una motivazione dichiarata, non da una catena di test di sottostringhe. I nomi vengono normalizzati prima, quindi un suffisso del fornitore non può sfuggire a un controllo — [email protected] è CBC a prescindere da chi lo fornisce — e i marcatori di negoziazione come [email protected] non vengono mai valutati come algoritmi. Questa tabella è ciò su cui poggiano in ultima analisi la soglia di policy e il confronto di deriva.

Ctrl+C robusto. Onorato anche su Windows, dove un'attesa di thread illimitata normalmente lo inghiotte: la prima pressione si ferma con grazia e restituisce risultati parziali, una seconda forza un'uscita immediata.


Cosa deliberatamente non fa

  • Inferire CVE dalle versioni dei banner. Le distribuzioni applicano backport delle correzioni senza toccare la stringa di versione, quindi OpenSSH_9.6p1 su Ubuntu 24.04 è patchato contro la maggior parte di ciò che i database pubblici attribuiscono a 9.6p1. Questa è una macchina di falsi positivi — è il motivo per cui ssh-audit ha rimosso il proprio rilevamento CVE basato sulla versione, e perché Tenable fornisce un plugin il cui intero lavoro è rilevare il backporting che lo rompe. Viene valutato solo ciò che un server pubblicizza effettivamente.
  • Forzare le credenziali. Strumento diverso, scopo diverso, postura legale diversa.
  • Competere con nmap sulla scansione delle porte in generale, o con masscan e zmap a scala internet. Quei problemi sono risolti.

Sviluppo

La suite di test usa solo la libreria standard, quindi gira su un interprete nudo:

root@kitploit:~
python -m unittest discover -s tests

Installa le dipendenze runtime per esercitare anche i test di audit basati su Paramiko, che si saltano da soli quando Paramiko manca:

root@kitploit:~
pip install -r requirements-dev.txt
python -m unittest discover -s tests

Legale

Scansiona solo sistemi che possiedi o per cui sei esplicitamente autorizzato a fare test. La scansione non autorizzata potrebbe essere illegale nella tua giurisdizione.

Scarica lo strumento
StrumentoScopre SSHLo valutaSu un intero parco
nmapsìsuperficiale, tramite script NSEsì
ssh-auditno — gli fornisci un singolo hostin profonditàno
masscan / zmapa scala internetnosì
sshfindersìsìsì
CodiceSignificato
0Successo. Non trovare nulla è comunque successo — un parco vuoto non è un errore.
1Errore grave: ogni target non è riuscito a essere scansionato, o il file di output non ha potuto essere scritto.
2Invocazione non valida (flag sconosciuto, specifica porta non valida, policy o proxy malformato).
3Violazione della policy a o sopra --fail-on. Solo con --policy.
4Avviso di deriva dalla baseline. Solo con --baseline --fail-on-drift.
130Interrotto con Ctrl+C.
OpzioneDescrizione
targetsUno o più IP, hostname o reti CIDR.
-iL, --target-file FILELeggi i target da un file (uno per riga, commenti # consentiti).
-p, --ports SPECPorte da scansionare, es. 22,80,1000-2000 (predefinito: 1-65535).
--auditControlla ogni servizio SSH: algoritmi, chiave host, metodi di autenticazione, Terrapin, prontezza post-quantistica, correlazione delle chiavi condivise.
--pq-reportSegnala la prontezza post-quantistica nell'intero parco. Non richiede librerie di terze parti.
--policy NAME_OR_PATHControlla ogni servizio contro baseline, strict, pq o un file di policy JSON. Esce con 3 in caso di violazione.
--fail-on {fail,warn,never}Quale severità di policy controlla il codice di uscita (predefinito: fail).
--baseline FILEConfronta con un report --json precedente ed elenca cosa è cambiato.
--fail-on-driftEsce con 4 quando il confronto solleva un avviso.
--format {text,json,sarif,csv}Formato di output (predefinito: text).
--jsonScorciatoia per --format json.
--streamEmetti eventi JSON delimitati da nuove righe man mano che i risultati vengono trovati.
-o, --output FILEScrivi i risultati su un file invece che su stdout.
--validate {banner,paramiko,none}Strategia di validazione SSH (predefinito: banner).
--scan-method {auto,connect,syn}Back-end di scansione (predefinito: auto).
--socks [user:pass@]host:portRaggiungi ogni target tramite un proxy SOCKS5.
--max-rate NLimita le sonde al secondo nell'intera scansione (predefinito: nessun limite).
-t, --timeout SECONDSTempo massimo di attesa di una sonda (predefinito: 2.0).
--min-timeout SECONDSLimite minimo per il timeout adattivo della sonda (predefinito: 0.1).
--no-adaptive-timeoutAttendi l'intero --timeout su ogni sonda.
-w, --workers NConnessioni in volo per host (predefinito: 512).
--max-sockets NTetto massimo di socket di sonda aperti contemporaneamente (predefinito: dal limite dei descrittori di file).
--host-concurrency NHost scansionati in parallelo (predefinito: 16).
-r, --retries NNuovi tentativi per sonde in timeout (predefinito: 0).
--max-targets NRifiuta elenchi di target più grandi di questo (predefinito: 65536).
--no-early-exitSpazza ogni porta anche su host che non rispondono affatto.
--no-progressDisabilita l'indicatore di avanzamento in tempo reale.
-v, --verboseRegistrazione dettagliata (-vv riattiva anche Paramiko).
-q, --quietSopprime l'avanzamento e la registrazione informativa.
--versionStampa la versione ed esce.