I cookie crittografati sono vulnerabili agli attacchi di Padding Oracle

7

Attualmente sto aiutando a scrivere una struttura web veloce compilata nel linguaggio dei cristalli e sto cercando di trovare un modo per accelerare le sessioni usando i cookie crittografati. Attualmente stiamo prendendo una stringa json e la crittografiamo con AES. Quindi, la codifica base64 e la firma.

La mia domanda è: è necessario firmare o una stringa crittografata modificata non decifrare? Se non risulta in un codice JSON valido che può essere analizzato in una sessione, sarà vuoto nello stesso modo in cui lo farebbe con una firma non valida. La mia comprensione è che gli attacchi di oracle padding funzionano ottenendo feedback dal server. Sarebbe sufficiente una stringa json vuota cifrata?

    
posta isaacsloan 21.07.2017 - 22:45
fonte

3 risposte

3

La risposta breve è che non è possibile fare affidamento sulla crittografia per garantire l'integrità di un messaggio. Vedi qui ad esempio.

Per dimostrare perché questa affermazione generale è valida anche per l'esempio specifico di questa domanda, vediamo come un utente malintenzionato può modificare un messaggio crittografato. Per semplicità, suppongo che tu stia utilizzando la crittografia AES-CBC. Consideriamo la seguente stringa:

{"Name":"Ryan Archer","Crime":"First Degree Murder","Judge 1":"Afred E Newman Jr","Verdict":"Not Guilty"}

Quando un AES-CBC codifica la stringa precedente, verrà crittografato nei seguenti blocchi da 16 byte:

Block 0:   "Name":"Ryan Arc
Block 1:   her","Crime":"Fi
Block 2:   rst Degree Murde
Block 3:   r","Judge 1":"Al
Block 4:   fred E Newman Jr
Block 5:   ","Verdict":"Not
Block 6:   Guilty" 

E ogni blocco della stringa crittografata corrisponderà allo stesso blocco della stringa di testo in chiaro originale.

Ora ecco una caratteristica interessante di CBC. Anche se non conosci la chiave di crittografia, puoi modificare il testo crittografato in modo tale che, una volta decodificato, il testo in chiaro venga modificato in un modo specifico.

Facciamo l'esempio sopra. Se qualcuno fosse in grado di crittografare AES-CBC con una certa chiave e non conosco questa chiave, se io XOR gli ultimi 3 byte del blocco 4 del testo cifrato con la stringa "Not", l'impatto sul testo decrittato sarebbe essere come segue:

  • Il blocco 4 verrebbe danneggiato in un modo casuale sconosciuto.
  • Gli ultimi 3 byte del blocco 5 sarebbero XORed con la stringa "Not"

Quindi, dopo la decrittazione, la stringa dovrebbe essere la seguente:

Block 0:   "Name":"Ryan Arc
Block 1:   her","Crime":"Fi
Block 2:   rst Degree Murde
Block 3:   r","Judge 1":"Al
Block 4:   %$#$%@#%$@#%#%#$ (random garbage bytes)
Block 5:   ","Verdict":"
Block 6:   Guilty" 

E verrebbe letto come la seguente stringa json valida.

"Name":"Ryan Archer","Crime":"First Degree Murder","Judge 1":"Al%$#$%@#%$@#%#%#$","Verdict":" Guilty"

Il nome del giudice è corrotto casualmente, ma l'attaccante ha modificato con successo una porzione critica del messaggio - Ryan Archer è ora colpevole di omicidio!

Naturalmente non tutte le stringhe sono strutturate in questo modo ed è possibile che i byte casuali nel blocco 4 corrompano la stringa in modo che non sia più una stringa json valida. Ma un utente malintenzionato può provare questo attacco più volte con varie modifiche della stringa crittografata e prima o poi otterrà una stringa JSON valida.

    
risposta data 27.08.2017 - 17:10
fonte
3

Is it necessary to sign or will a modified encrypted string fail to decrypt?

Nel mondo della crittografia un messaggio modificato è chiamato messaggio alterato. La crittografia di per sé non fornisce protezione contro la manomissione, ma i codici a blocchi non vengono utilizzati da soli. I cifrari a blocchi vengono utilizzati in diverse modalità, ad es. ECB, CBC, CTR, GCM, ecc. Diverse modalità hanno proprietà diverse, alcune offrono protezione contro la manomissione (ad es. Crittografia autenticata, ad es. GCM) e altre no.

Se utilizzi una modalità di crittografia autenticata, un messaggio manomesso non verrà decrittografato. Ma, se stai usando altre modalità come CBC o CTR (queste sono le più diffuse nella mia esperienza) un messaggio manomesso decodificherà felicemente a meno che non ci sia un errore di padding

If it doesn't result in valid json which can be parsed into a session it will be empty in the same way that it would with an invalid signature.

Dipende da come la tua applicazione gestisce un json non valido, e qui è dove può apparire un oracle di riempimento.

My understanding is that padding oracle attacks work by getting feedback from the server. Would an encrypted empty json string be enough?

Un attacco oracle di padding si verifica quando l'attaccante invia un messaggio manomesso ed è in grado di distinguere se il padding è corretto o meno. E questo è il motivo per cui ho detto in precedenza che il modo in cui la tua applicazione gestisce un JSON non valido può derivare in un oracle padding

Immagina che un utente malintenzionato mandi un messaggio manomesso con una spaziatura sbagliata, la tua applicazione proverà a decrittografare il messaggio ma verrà lanciata un'eccezione di padding errata. Dopo di che l'utente maltrattato manomette nuovamente il messaggio ma questa volta è in grado di falsificare un padding corretto, l'applicazione decodificherà correttamente il messaggio ma il contenuto sarà e JSON non valido, l'applicazione tenterà di analizzare il JSON non valido e di generare un errore non può essere analizzato

Se l'utente malintenzionato è in grado di distinguere entrambi gli scenari, lo stato HTTP restituito è diverso, oppure uno stacktrace mostra i diversi messaggi di errore o semplicemente cronometrando il tempo di risposta. Quindi l'attaccante ha un oracle di riempimento e può recuperare il testo in chiaro dal cookie

Per evitare ciò, devi sempre fornire lo stesso messaggio di errore quando il messaggio non può essere decifrato e quando il messaggio decodifica ma il contenuto non è valido. Inoltre, dovresti assicurarti che entrambi gli scenari richiedano lo stesso tempo per rispondere.

IMO l'approccio migliore sarebbe utilizzare una modalità di crittografia autenticata che ti consenta di crittografare e firmare insieme e lasciare che sia il framework / libreria di crittografia a gestirli

A proposito, ho menzionato una modalità di crittografia che non dovrebbe mai essere utilizzata. È ECB, se stai usando questa modalità (alcune librerie predefinite) cambia come è una modalità debole

    
risposta data 27.08.2017 - 02:15
fonte
1

Is it necessary to sign or will a modified encrypted string fail to decrypt?

Il modo classico (e più veloce) per autenticare il tuo messaggio sta utilizzando MAC . Dovresti usare la firma se hai bisogno di non ripudio (che probabilmente non hai bisogno).

If it doesn't result in valid json which can be parsed into a session it will be empty in the same way that it would with an invalid signature. [...] padding oracle attacks work by getting feedback from the server. Would an encrypted empty json string be enough?

Per quanto riguarda il riempimento dell'attacco oracolare:

AES è una crittografia a blocchi. Non ci sono imbottiture in AES. Se la tua implementazione utilizza padding vulnerabile (come fa PKCS7), l'attacco di oracle potrebbe essere teoricamente possibile. Tuttavia, AES è una crittografia CBC (che inizia con un pasticcio casuale), il che significa che lo stesso testo in chiaro genererà ogni volta un testo cifrato differente. Sarebbe molto difficile per l'attaccante indovinare che hai restituito una stringa json vuota.

Tuttavia, potrebbe essere possibile rilevare l'errore di riempimento in altri modi. Se si utilizzano codici di errore HTTP diversi nell'implementazione REST o si misura il tempo di risposta del server. MAC aiuterà qui, dal momento che l'aggressore non può manomettere il tuo messaggio. Il messaggio verrà rilasciato immediatamente se il MAC non è valido e la decifratura non prende mai il posto.

È possibile includere un intervallo casuale nella risposta per rendere più difficile il profilo delle risposte e / o restituire lo stesso codice http per tutto ciò per aumentare ulteriormente la sicurezza, ma penso che quest'ultimo causerebbe più problemi del guadagno. Ovviamente, non dovresti rivelare che hai rilevato un errore di riempimento.

    
risposta data 26.08.2017 - 13:48
fonte

Leggi altre domande sui tag