SSH: utilizzo di chiavi pubbliche e note-man-in-the-middle

6

Di solito, le persone consigliano di usare una singola coppia di chiavi privata-pubblica ovunque (se non stiamo parlando di una possibilità di compromettere la chiave privata):

  1. Best Practice:" Una chiave ssh per utente "o" più chiavi ssh per host "
  2. Riutilizzo di chiavi private / pubbliche
  3. link

    Sembra che ciò comporterebbe una vulnerabilità quando si utilizza l'autenticazione del certificato client su SSH. Poiché è così popolare da suggerire, sospetto che l'algoritmo sottostante non funzioni. Ma non capisco esattamente cosa c'è che non va.

Ho cercato di rendere la mia descrizione il più dettagliata possibile, per ridurre al minimo possibili discrepanze, quindi, per favore, scusami per la lunghezza ...

Presupposti

  • PC1 ha entrambi i fingerprint ( S1_id_rsa.pub e S2_id_rsa.pub ) nei suoi host conosciuti.
  • Server1 conosce in qualche modo l'esistenza dell'account PC1 su Server2 .
  • Chiavi:
    • PC1 : ha P1_id_rsa , S1_id_rsa.pub , S2_id_rsa.pub .
    • Server1 , l'utente malintenzionato: ha S1_id_rsa , P1_id_rsa.pub , S2_id_rsa.pub .
    • Server2 : ha S2_id_rsa , P1_id_rsa.pub

Algoritmo

Questo è qualcosa come un noto attacco man-in-the-middle , ma un po 'diverso.

  1. PC1 invia "Ciao" a Server1
  2. Server1 invia "Ciao" a Server2
  3. Il server condivide la sua chiave pubblica

    1. Server2 invia Server1 S2_id_rsa.pub
    2. Server1 invia PC1 S1_id_rsa.pub (anziché S2_id_rsa.pub )
    3. PC1 accetta l'impronta di S1_id_rsa.pub (come è noto)
  4. Vengono creati due tunnel segreti condivisi separati utilizzando Diffie-Hellman :

    1. "Server1 - Server2"

      1. Server2 genera DH1.a e invia DH1.A, firmato con S2_id_rsa , a Server1
      2. Server1 genera DH1.b e invia DH1.B a Server2
      3. Tunnel stabilito
    2. "PC1 - Server1"
      1. Server1 genera DH2.a e invia DH1.A, firmato con S1_id_rsa , a PC1
      2. PC1 genera DH2.b e invia DH2.B a Server1
      3. Il tunnel è stabilito.
  5. Autenticazione client ( Server2 ora vuole essere sicuro che stia parlando con PC1 )

    1. PC1 invia P1_id_rsa.pub a Server1
    2. Server1 invia P1_id_rsa.pub a Server2
    3. Server2 genera una sfida, che può essere risolta solo con P1_id_rsa e la invia a Server1
    4. Server1 solo i tunnel sfidano a PC1
    5. PC1 risolve la sfida e invia risposta a Server1
    6. I tunnel Server1 rispondono a Server2
    7. Fatto.
  6. Fatto

P.S. Ho esaminato crittografia a chiave pubblica e attacco man-in-the-middle su Wikipedia e questa risposta abbastanza dettagliata (la mia visione dell'intero processo è ampiamente basata su di esso), ma non ho trovato la risposta ..

Non sono riuscito a trovare un "completo ssh di autenticazione e processi di crittografia per i manichini" leggibile ...

Ho già fatto la stessa domanda su Server Fault, ma è stato suggerito per ripubblicarlo qui.

    
posta Igor 21.01.2013 - 17:16
fonte

4 risposte

3

Infine, penso di aver capito.

Prima di tutto - Ho confuso i protocolli ssh v1 e ssh v2 nella mia descrizione. L'autorizzazione challenge-response proviene da ssh v1.

Nel client ssh v2 si firma semplicemente un pacchetto specifico con la sua chiave privata e il server lo controlla usando la chiave pubblica memorizzata. Questo pacchetto è descritto in rfc, qui :

To perform actual authentication, the client MAY then send a
signature generated using the private key.  The client MAY send the
signature directly without first verifying whether the key is
acceptable.  The signature is sent using the following packet:

  byte      SSH_MSG_USERAUTH_REQUEST
  string    user name
  string    service name
  string    "publickey"
  boolean   TRUE
  string    public key algorithm name
  string    public key to be used for authentication
  string    signature

The value of 'signature' is a signature by the corresponding private
key over the following data, in the following order:

  string    session identifier
  byte      SSH_MSG_USERAUTH_REQUEST
  string    user name
  string    service name
  string    "publickey"
  boolean   TRUE
  string    public key algorithm name
  string    public key to be used for authentication

Quindi, il pacchetto firmato contiene "identificatore di sessione" che è calcolato come segue :

  H = hash(V_C || V_S || I_C || I_S || K_S || e || f || K)
  <…..>
  mpint     K, the shared secret  

Cioè, la firma dipende dal segreto condiviso e i segreti condivisi sono diversi per P1 < - > S1 e S1 & lt ; - > S2 tunnel.

    
risposta data 11.02.2013 - 14:44
fonte
3

Usually, people recommend to use a single private-public key pair everywhere (if we're not talking about a possibility of compromising the private key)

Si noti che ci sono due coppie di chiavi coinvolte in una connessione SSH:

  • uno per identificare l'host del server (il server ha la chiave privata);
  • uno per identificare l'utente (il client ha la chiave privata), se si utilizza l'autenticazione della chiave pubblica.

I consigli che citi riguardano le chiavi utente. Avere una singola chiave privata per utente è un modello praticabile, anche se non lo consiglio particolarmente (il costo di avere coppie di chiavi separate per host o sito non è così elevato). Le chiavi del server, d'altra parte, non sono mai duplicate. Sono generati di nuovo quando il server SSH è installato.

Su questo argomento, oltre ai post che hai citato nella tua domanda, vedi anche Qual è la differenza tra i file authorized_keys e known_hosts per SSH?

Nell'attacco che descrivi, hai mescolato i ruoli delle chiavi. Queste sono le chiavi host, ssh_host_rsa e non le chiavi utente. Questo non è direttamente rilevante nel modo in cui funziona l'attacco che descrivi, ma potrebbe far parte della tua confusione.

Il punto fisso è al punto 3.3:

PC1 accepts S1_id_rsa.pub's fingerprint (as it's known)

Ci sono due casi.

  • Se PC1 è collegato a S2 in precedenza, PC1 (o più precisamente l'account dell'utente su PC1) ha memorizzato la chiave pubblica ospite di S2 nel suo file known_hosts . Quindi, se S1 invia la chiave host di S2, il client SSH su PC1 rileverà che la presunta chiave host non corrisponde alla chiave host registrata e interrompe la connessione con un messaggio spaventoso:

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    @    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
    Someone could be eavesdropping on you right now (man-in-the-middle attack)!
    It is also possible that the RSA host key has just been changed.
    

    L'attacco è quindi impossibile in questo scenario (a meno che l'utente non faccia in modo di bypassare il controllo - OpenSSH lo rende intenzionalmente difficile).

  • Se PC1 non è mai connesso a S2, PC1 accetterà felicemente qualsiasi cosa S1 stia dicendo che è la chiave di S2. Poiché PC1 non ha alcuna conoscenza preliminare di alcuna associazione tra il nome S2 e un'identità crittografica, né alcun modo per contattare una terza parte fidata che conosce tale associazione (cioè un'infrastruttura a chiave pubblica), non c'è modo di impedire a questa attacco nel mezzo.

risposta data 21.01.2013 - 18:23
fonte
1

Il problema è che il client potrebbe sapere che sta parlando al server 1 a causa dell'uso del certificato del server 1. Se server1 ha un certificato valido che dice che sono server2, il client non sarebbe consapevole se prima non si fosse connesso a server2. La maggior parte dei client SSH tuttavia traccia l'impronta digitale del certificato a cui si connettono per un determinato server. Quando il client va a connettersi e termina con una connessione al server 1, anche se il certificato è firmato, l'utente probabilmente riceverà un avviso che l'impronta digitale è cambiata.

Come per una connessione nota a S1 che cerca di affermare di essere s2, se s2 conosce con precisione p1, s chiave privata, allora se 01 vuole parlare con s2 a s1 allora dovrebbe cifrare per s2 e s2 quindi criptare per p1 . Quando p1 non ottiene uno scambio di chiavi da s2, saprà che c'è un problema dal momento che s1 non può firmare uno scambio con p1 come s2.

    
risposta data 21.01.2013 - 18:14
fonte
0

In realtà si tratta di una vulnerabilità nota con certificati di crack nell'elenco di fiducia e del perché sono necessari elenchi di revoche.

Affinché questo attacco funzioni, devono esserci 2 fori:

  1. PC1 deve pensare che stia comunicando con server2 mentre in realtà sta comunicando con server1.
  2. PC1 deve avere S1_id_rsa.pub come certificato attendibile e punta all'indirizzo del server2 (l'altro PC1 saprà che sta parlando al server1 invece del server2 al punto 4.3).

# 1 può accadere su una rete non sicura, mentre # 2 può succedere solo quando è avvenuta una violazione precedente che ha permesso al server1 di inserirsi come parte fidata.

    
risposta data 21.01.2013 - 17:48
fonte