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


Aucun commentaire:

Enregistrer un commentaire