samedi 26 novembre 2016

Attaque ECB bloc shuffling

L'attaque sur les blocs en mode ECB (Electronic Code Book)

Les chiffrements symétriques par bloc découpent les données en blocs de taille fixe. Ces blocs sont de 128-bit pour les algorithmes récents (recommandés) ou 64-bit pour des algorithmes plus anciens comme le DES. 

Pour des raisons de sécurité, des modes liant les blocs entre eux sont recommandés (CBC, OFB, etc). Dans ces cas, les blocs subissent habituellement un chaînage entre eux selon un mode opératoire défini de façon a rendre le chiffré le plus indépendant possible des données en clair pour une même clef de chiffrement.  

Le mode ECB est l'absence de mode spécifique. L'algorithme symétrique par bloc (DES, AES, Twofish, ...) est dans ce cas appliqué directement au données sans autre traitement des blocs.



Le mode ECB est à proscrire absolument car il laisse fuir de l'information. Malheureusement, de nombreux développeurs l'utilisent par méconnaissance des risques associés à ce mode opératoire. 

La problématique est que tout bloc de données en clair donne le même bloc chiffré pour une même clef. Ce principe laisse fuir de l'information ou permet des altérations valides du chiffré. L'exemple suivant de l'image BMP chiffrée en mode ECB en AES illustre cette faiblesse.


Version plaintext

Version ciphertext

Un outil de chiffrement d'images BMP en AES-ECB est disponible là: http://www.willhackforsushi.com/code/ecb_encrypt_image.zip


La bijectivité du mode ECB expose les données chiffrées à des attaques par substitution, suppression ou ajout de blocs dans un message chiffré.



Ci-dessous, des exemples d'attaque sont réalisés en DES mode ECB. DES est utilisé parce qu'il utilise une taille de bloc de 8 octets plus facile à manipuler en mode commande, mais le principe reste le même.

L'exemple utilisé s'appuie sur le cryptogramme de la chaîne de caractères "id=123456&value=52&acct=000000178356" en DES avec la clef 0x0011223344556677:

$ echo -ne "id=123456&value=52&acct=000000178356" | openssl enc -des-ecb -K 0011223344556677 | xxd -p
34738ccb598fcaff3bf8fb2c6b1d9db312405ac7072f1c45396e156b2749f8ad6f2fcdb9d36dda57

$ echo -ne 34738ccb598fcaff3bf8fb2c6b1d9db312405ac7072f1c45396e156b2749f8ad6f2fcdb9d36dda57 | xxd -r -p | openssl enc -des-ecb -d -K 0011223344556677 ; echo
id=123456&value=52&acct=000000178356


L'attaque ECB bloc shuffling

Tout d'abord, un éclatement des chaînes clair/chiffré en bloc de 8 octets permet de mieux visualiser le principe.

$ echo -ne "id=123456&value=52&acct=000000178356" | sed 's/.\{8\}/& /g'
id=12345 6&value= 52&acct= 00000017 8356

$ echo -ne 34738ccb598fcaff3bf8fb2c6b1d9db312405ac7072f1c45396e156b2749f8ad6f2fcdb9d36dda57 | sed 's/.\{16\}/& /g'; echo
34738ccb598fcaff 3bf8fb2c6b1d9db3 12405ac7072f1c45 396e156b2749f8ad 6f2fcdb9d36dda57


Mapping des blocs

id=12345         6&value=         52&acct=         00000017         8356
34738ccb598fcaff 3bf8fb2c6b1d9db3 12405ac7072f1c45 396e156b2749f8ad 6f2fcdb9d36dda57
       1               2                 3                4               5
  
L'attaque consiste à ajouter/supprimer/réordonner des blocs. L'exemple illustré infra est d'insérer le bloc 4 après le bloc 2. Le dernier bloc doit être conservé en fin de cryptogramme car il contient le padding qui validera ou non le déchiffrement.

$ echo -ne "34738ccb598fcaff3bf8fb2c6b1d9db3396e156b2749f8ad12405ac7072f1c45396e156b2749f8ad6f2fcdb9d36dda57" | xxd -r -p | openssl enc -des-ecb -d -K 0011223344556677; echo
id=123456&value=0000001752&acct=000000178356

Le déchiffrement est correct car le dernier bloc possède toujours un padding valide.

Le résultat donne une valeur différente pour le paramètre value.
value=52 devient value=0000001752

De réelles attaques existent avec ce concept, y compris dans le monde Web ou certains paramètres (token, cookie, panier, ...) peuvent être gérés de manière stateless côté serveur en chiffrant des données dont la gestion est déléguée au navigateur du client. 

Padding PKCS#7

Dans un chiffrement par bloc, le padding sert à combler le dernier bloc pour l'aligner sur la taille du bloc. Si les données sont un multiple du bloc, alors un bloc complet de padding est ajouté. La procédure de déchiffrement contrôle la validité du padding, avant de l'extraire pour retourner les données en clair. Le padding permet de déterminer que le déchiffrement c'est passé correctement.

Plusieurs types de padding existent, mais le plus utilisé consiste à écrire le nombre d'octets de padding dans chaque octet de padding (standard PKCS#7, PKCS#5, RFC1423) :
01
02 02
03 03 03
...

Le padding du dernier bloc est visible dans la commande de déchiffrement infra qui demande de ne pas tenir compte du padding avec l'argument "-nopad". 
$ echo -ne "34738ccb598fcaff3bf8fb2c6b1d9db3396e156b2749f8ad12405ac7072f1c45396e156b2749f8ad6f2fcdb9d36dda57" | xxd -r -p | openssl enc -des-ecb -nopad -d -K 0011223344556677 | hd
00000000  69 64 3d 31 32 33 34 35  36 26 76 61 6c 75 65 3d  |id=123456&value=|
00000010  30 30 30 30 30 30 31 37  35 32 26 61 63 63 74 3d  |0000001752&acct=|
00000020  30 30 30 30 30 30 31 37  38 33 35 36 04 04 04 04  |000000178356....|
00000030

Les autres paddings

Dans le monde des cartes à puce, c'est le padding NIST 800-38a qui est couramment implémenté. Il s'agit d'un bit à 1 suivi de bit à 0. Soit 0x80 (b1000 0000).
H  e  l  l  o  ?  ?  ?
48 65 6C 6C 6f 80 00 00

Parfois, le padding consiste à valoriser l'octet par son rang, ex: 04 03 02 01
H  e  l  l  o  ?  ?  ?
48 65 6C 6C 6f 03 02 01

On rencontre également des paddings composés exclusivement du caractère nul (0x00) ou espace (0x20) lorsqu'il s'agit de texte.

H  e  l  l  o  ?  ?  ?
48 65 6C 6C 6f 00 00 00
48 65 6C 6C 6f 20 20 20


Attaque "Bit flip"

Attaque cryptographique « Bit Flip »

L’attaque Bit flip cible les cryptosystèmes de chiffrement par flot comme RC4, AES mode CTR ou A5/1. Dans ce modèle de chiffrement, un générateur produit une « suite chiffrante » continue appelée keystream.
Le keystream opère un XOR (ou exclusif) sur les données. Il s’agit d’un addition modulo 2. 


L’opération de déchiffrement consiste à procéder à la même opération entre le chiffré et le keystream pour obtenir le clair.

Soit P (plaintext), C (ciphertext) et K (keystream), on a les relations suivantes

C = K XOR P
P = K XOR C
mais aussi la relation particulière (pour info)
K = C XOR P

Les propriétés du XOR utilisé dans les chiffrements par flot permettent d’agir sur le contenu en clair en modifiant des bits du cryptogramme (ciphertext).

Exemple d’un chiffrement et déchiffrement RC4 d’une chaîne de caractère « uid=1000 » avec une clef de 128-bit 0x00112233445566778899AABBCCDDEEFF.

$ echo -n uid=1000 |openssl enc -rc4 -K 00112233445566778899AABBCCDDEEFF | xxd -p
f032c86aa31751b5

$ echo -n f032c86aa31751b5 | xxd -r -p | openssl enc -rc4 -d -K 00112233445566778899AABBCCDDEEFF; echo
uid=1000

Le cryptogramme f032c86aa31751b5 correspond au texte en clair uid=1000.
    u  i  d  =  1  0  0  0
   f0 32 c8 6a a3 17 51 b5

Si l’attaquant opère une attaque Bit Flip, il peut changer la valeur de certains octets sans que le déchiffrement soit invalide.

Bit flit 

Le mode opératoire proposé est de modifier le cryptogramme à l'aveugle. La partie simulant la boite noire ou le serveur attaqué est représentée par la commande openssl déchiffrant le cryptogramme. La commande xxd convertit la chaîne héxadimale ASCII en une suite binaire d'octets avant traitement par openssl.

$ echo -n f032c86aa21751b5 | xxd -r -p | openssl enc -rc4 -d -K 00112233445566778899AABBCCDDEEFF; echo
uid=0000

autre exemple :

$ echo -n f032c86aa21751b4 | xxd -r -p | openssl enc -rc4 -d -K 00112233445566778899AABBCCDDEEFF; echo
uid=0001

Conlusion


Cette attaque est simple et puissante. Lorsqu’un cryptogramme n'est pas protégé par une intégrité cryptographique et qu'un chiffrement par flot est employé, il est facile de modifier la valeur du clair à l'aveugle. Parfois, certains paramètres d’authentification sont chiffrés de la sorte par les applications Web. Le pentesteur peut alors agir sur la valeur du paramètre (cookie, token, …) pour obtenir des comportements interessants.

Edition hexadécimale avec vi et xxd

La commande XXD

La commande xxd permet de convertir du binaire en hexadécimal et inversement. Elle permet aussi de patcher un fichier binaire. Utilisé avec vi ou vim, xxd permet de disposer d’un éditeur hexadécimal de fortune en mode commande. Enfin, cet outil permet d’afficher au format binaire.

Afficher la représentation binaire d’octets 

Avec echo
$ echo -n 5C00FF | xxd -r -p | xxd -b
0000000: 01011100 00000000 11111111                             \...

 Avec un fichier
$ xxd -b bin        
0000000: 01011100 00000000 11111111                             \...

Edition hexadécimale

Il est possible d'utiliser vi ou vim comme éditeur héxadécimal (grâce à xxd)

Pour passer en mode éditeur hexadécimal, entrez <esc> puis :%!xxd

Pour revenir au mode initial <esc>:%!xxd -r

Patcher un fichier binaire

Pour patcher un binaire, il suffit de passer en mode édition hexadécimal puis d’ajouter, supprimer ou modifier les valeurs sur la partie hexadécimale uniquement (à gauche). La modification sur la partie ASCII n’est pas prise en compte. Ensuite il faut soit : 
  • sauvegarder soit dans un fichier externe (sans sauvegarder le fichier courant car le buffer de vi est vidé) 
  • sauvegarder le fichier courant par une conversion au format initial puis en enregistrant normalement le fichier courant

Depuis l’édition hexadécimale, la modification du fichier s’opère sur la partie hexadécimale uniquement avec <esc>:%!xxd



Le mode insertion de vi <esc>i permet de modifier le fichier, dans l’exemple ci-dessous, la séquence 46494c45 remplace 36393c35.


Pour enregistrer dans un fichier externe, il faut saisir  <esc>:%!xdd –r > newfile, mais cela vide le buffer courant de vi. 


Dans ce cas, pour conserver le fichier initial intact, il faut sortir sans enregistrer le fichier avec <esc>:q!

Voici le résultat du fichier patché dans un nouveau fichier


Pour patcher directement le fichier lui-même, il suffit de reconvertir l’édition en cours : <esc> %!xxd –r puis de sauvegarder :wq.

Edition et modification


Conversion du mode d’édition :% !xxd -r


Sauvegarde :wq


Le fichier txt est patché