Ricerca di chiavi crittografiche insicure generate da sistemi Debian

Massimo Gravino
INFN - Sezione di Padova
3 ottobre 2008

Sommario

Il bug e le sue conseguenze

A maggio del 2008 e` stato pubblicato un advisory [2] di Debian riguardante una grave vulnerabilita` di OpenSSL, introdotta con la versione 0.9.8c-1 del 17/9/2006 e corretta il 13/05/2008.

Il problema riguarda il generatore random [ 3, 4] usato da openSSL per generare le chiavi crittografiche, che risulta predicibile, in quanto il seme usato per la generazione di numeri casuali in realta` e` solo il PID del processo, che su linux e` al massimo 32768.

Di conseguenza, per ogni tipologia di chiavi e per ogni architettura, il software e` in grado di generare solo 32768 chiavi diverse. Chiunque puo` rigenerarle tutte facilmente [5] e quindi le chiavi private sono da considerare compromesse.

Tutte le applicazioni che utilizzano le chiavi crittografiche di OpenSSL possono essere interessate dal problema: SSH, OpenVPN, i certificati X.509 e le chiavi usate nelle sessioni SSL/TLS (https, imaps, pops, etc.).

Il problema non e` limitato ai sistemi Debian, ma interessa tutti i sistemi su cui siano state importate chiavi generate da sistemi Debian vulnerabili.

Ad esempio un utente puo` avere sul suo portatile una versione di Debian o Ubuntu con OpenSSL vulnerabile e con essa puo` generare una coppia di chiavi SSH da usare per l'autenticazione mediante chiave pubblica: gli basta copiare la chiave pubblica appena generata sugli host a cui ha accesso, in ~/.ssh/authorized_keys.
A questo punto questi host (non necessariamente con sistema Debian) diventano vulnerabili ad un attacco brute-force.[6]
Particolarmente grave e` il caso in cui l'autenticazione con chiave pubblica compromessa sia abilitata per l'utente root.

Come identificare le chiavi Debian compromesse

Per verificare se una chiave crittografica e` stata generata su un sistema vulnerabile basta verificare se si trova nelle blacklists [5] delle chiavi generabili da questi sistemi.

Il modo piu` efficiente e` confrontare le fingerprints della chiave da controllare con le fingerprints di tutte le chiavi presenti nella blacklist.

Debian ha messo a disposizione lo script perl dowkd.pl in grado di controllare rapidamente vari tipi di chiavi crittografiche generate su architetture little-endian a 32 e 64 bit (come i386 e amd64):

Lo script non e` in grado di segnalare chiavi di differente lunghezza o generate su architeture big-endian 32bit (come powerpc o sparc).

Ecco i comandi per scaricarlo e controllare la firma digitale:

wget http://security.debian.org/project/extra/dowkd/dowkd.pl.gz
wget http://security.debian.org/project/extra/dowkd/dowkd.pl.gz.asc
gpg --keyserver hkp://subkeys.pgp.net --recv-keys 02D524BE
gpg --verify dowkd.pl.gz.asc
gunzip dowkd.pl.gz

Il programma puo` controllare le chiavi contenute in un file (sia chiavi ssh che certificati pem) oppure la chiave pubblica utilizzata da un server ssh remoto. Dispone inoltre di opzioni per controllare automaticamente le chiavi degli utenti e dell'host locale.

La sintassi e` la seguente:

./dowkd.pl [OPZIONI...] COMANDO [ARGOMENTI...]

L'unica opzione riconosciuta e`:

COMANDO e` uno dei seguenti:

Quando il programma trova una chiave della blacklist, segnala il file in cui l'ha trovata e la posizione della chiave nel file, indicandola come "weak key". Prima di terminare, stampa il totale delle chiavi esaminate e di quelle deboli.

Su una macchina con molti utenti (es. bastion host o public login) e` molto facile trovare "weak keys" nei file ~/.ssh/known_hosts delle home degli utenti; tuttavia questo non costituisce un rischio immediato per l'host in esame, ma piuttosto ci segnala che gli utenti si collegano (o si sono collegati) a nodi il cui server ssh ha (o aveva) una chiave insicura (quindi la connessione potrebbe essere decifrata).
Per controllare di quali host si tratta, basta andare a leggere la riga del file known_hosts segnalata da dowkd. Si puo quindi verificare subito se l'host ha ancora la vecchia chiave col comando

       ./dowdk.pl host <nomehost>
In caso positivo otterremmo una risposta di questo tipo:
./dowkd-v7.pl host pc170
pc170: weak key (OpenSSH/dsa/1024)
pc170: weak key (OpenSSH/rsa/2048)
summary: keys found: 2, weak keys: 2

Piu` interessante e` pero` scoprire se gli utenti si autenticano su SSH usando chiavi pubbliche che sono nella blacklist. Bisogna cioe` controllare i file ~/.ssh/authorized_keys e ~/.ssh/authorized_keys2. Un modo veloce per farlo in tutto l'albero delle home e` questo:

find <home-path> -name "authorized_keys*" -exec ./dowkd.pl file {} \;

Una volta identificate le chiavi deboli e` necessario sostituirle con chiavi nuove (generate su sistemi non affetti dal bug). A seconda del tipo di chiave da sostituire la procedura sara` differente [7].
In particolare, nel caso delle chiavi utente di SSH basta rimuovere la chiave dal file e sostituirla con la nuova, generata al solito modo.

Disabilitazione dell'autenticazione con chiave pubblica

Anche quando le chiavi crittografiche utilizzate sono sicure, l'autenticazione SSH mediante chiave pubblica e` da considerare meno sicura dell'autenticazione con password, a meno che la chiave privata corrispondente non sia stata protetta con una passphrase.
Invece di solito l'autenticazione con chiave pubblica viene utilizzata proprio per evitare di dover inserire una password ad ogni login, e questo si ottiene solo se non si protegge la chiave privata.
In tal modo, in caso di compromissione dell'host su cui e` salvata la chiave privata, e` molto semplice per l'intruso copiarsi la chiave privata dell'utente e utilizzarla per collegarsi agli altri suoi account remoti.

In effetti l'intrusione mediante accesso con chiave crittografica rubata e` una pratica che sta diventando abbastanza frequente e che si avvale di tool automatici per il furto di chiavi private. [8,9,10,11]

Per ridurre il rischio di queste intrusioni sarebbe bene limitare l'utilizzo dell'autenticazione mediante chiave pubblica senza password ai soli casi in cui l'autenticazione deve essere eseguita da procedure automatiche.
Per maggiore sicurezza sarebbe poi utile impedire l'autenticazione mediante chiave pubblica sugli host di public login (con decine o centinaia di utenti) e sugli host che consentono l'accesso via SSH alla LAN (bastion host). Per disabilitare l'accesso con chiave pubblica su un server SSH e` sufficiente editare /etc/ssh/sshd_config e aggiungere (o modificare) le righe:

RSAAuthentication no
PubkeyAuthentication no
Una volta salvato il file e` necessario riavviare il servizio sshd.

Un'altra misura precauzionale e` quella di impedire l'accesso diretto via SSH dell'utente root. In tal modo per poter accedere come root da remoto e` necessario prima accedere come utente non privilegiato. Questo tra l'altro consente anche una migliore identificabilita` degli accessi remoti privilegiati.
Per disabilitare l'accesso diretto di root via SSH e` sufficiente inserire in /etc/ssh/sshd_config la direttiva

PermitRootLogin no
e quindi riavviare il servizio.

Riferimenti

  1. http://wiki.debian.org/SSLkeys
  2. http://www.debian.org/security/2008/dsa-1571
  3. random number generator (hardware)
  4. random number generator (hardware)
  5. http://metasploit.com/users/hdm/tools/debian-openssl/
  6. http://milw0rm.com/exploits/5622
  7. http://www.debian.org/security/key-rollover/
  8. http://www.us-cert.gov/current/archive/2008/08/27/archive.html#ssh_key_based_attacks
  9. "http://isc.sans.org/diary.html?storyid=4937
  10. http://www.theregister.co.uk/2008/08/27/ssh_key_attacks_warning/
  11. http://hep.uchicago.edu/admin/report_072808.html