Programmation assembleur (ASM)

publicité
labo secu
(v2017.1.6)
Programmation assembleur (ASM)
Rick Wertenbroek / Magali Frölich / Daniel Rossier
Sécurité sur x86
Jeudi 12 janvier 2017
Echéance: vendredi 27 janvier 2017, 23h59
Objectif du laboratoire
Ce laboratoire propose deux exercices pratiques pour étudier les conventions ABI cdecl utilisées avec
le jeu d’instructions x86. Le premier exercice se concentre sur l'algorithme de chiffrement AES-128
(128 bits). Nous utiliserons les instructions spécialisées fournies par l'extension AES-NI d'Intel. Le
deuxième exercice propose de mettre en place une attaque de type buffer overflow.
Consignes de laboratoire


Le laboratoire est individuel et est évalué selon les conditions établies dans le document
annexe qui vous a été distribué en début de semestre.
Pour toutes les fonctions implémentées en assembleur x86 il sera demandé de respecter la
convention ABI cdecl étudiée en cours.
Etape no. 1 – Chiffrer un bloc de données avec l’algorithme AES
L’algorithme de chiffrement AES-128 sert à chiffrer des blocs de données de 128 bits. C’est un
chiffrement symétrique, ce qui veut dire qu’on utilisera la même clé pour chiffrer et déchiffrer les
données.
Les étapes permettant le chiffrement d'un bloc de données sont les suivantes :




Générer les sous-clés depuis la clé initiale.
Ronde initiale
Rondes internes (Cette opération doit être répétée 8 fois)
Ronde finale
Les instructions principales utilisées dans le programme sont les suivantes :






aeskeygenassist
aesimc
aesenc
aesenclast
aesdec
aesdeclast
imm8,
%xmm1,
%xmm1,
%xmm1,
%xmm1,
%xmm1,
%xmm1,
%xmm2
%xmm2
%xmm2
%xmm2
%xmm2
%xmm1
Génération des sous-clés
Transformation inverse mixColumns
Chiffrement des rondes internes
Chiffrement de la ronde finale
Déchiffrement des rondes internes
Déchiffrement de la ronde finale
Les instructions AES-NI manipulent les registres 128-bits (%xmm0, %xmm1, %xmm2, …).
a) Le ficher labo6/asm_x86/aes.S contient une implémentation de l’algorithme AES.
Prenez connaissance du code contenu dans ce fichier.
-1
-
ASM – Programmation assembleur
b) Editez le code assembleur de ce fichier de manière à pouvoir appeler les fonctions de chiffrement et
de déchiffrement depuis l'application C qui se trouve dans le fichier labo6/c_x86/crypt.c. Les fonctions
doivent respecter la convention ABI cdecl.
Les prototypes sont les suivants :



void aes_initialize(void)
int aes_crypt(void *src, void *dst, void *key)
void aes_decrypt(void *src, void *dst, void *key)
c) Editez le code assembleur et vérifiez que la fonction de chiffrement est correcte en ajoutant le test
suivant : dans la fonction de chiffrement assembleur, sauvez une copie du message à chiffrer dans une
variable locale (en suivant les conventions de l'ABI).
Puis après l’opération de chiffrement, appliquez un déchiffrement et vérifiez que la valeur obtenue
corresponde bien à la valeur originale. Pour cela, utilisez/adaptez la fonction de comparaison. La
fonction de chiffrement retournera 0 si la comparaison est correcte, -1 dans le cas contraire.
Indications
 Attention à bien recompiler le code assembleur dans le répertoire asm_x86 lors de toute
modification. Le Makefile dans le répertoire c_x86 ne régénère pas le code assembleur.

Les détails sur ce jeu d'instructions et les impacts sur la sécurité au niveau du processeur sont
disponibles ici :
http://download-software.intel.com/sites/default/files/article/165683/aes-wp-2012-09-22-v01.pdf


Une variable d’environnement est disponible pour charger et exécuter le programme crypt.bin.
Une configuration de Debug a été ajoutée dans eclipse.
-2-
ASM – Programmation assembleur
Etape no. 2 – Buffer overflow (débordement de tampon)
Une société de location de films propose une petite application C pour louer un film et débiter le
compte de l’utilisateur.
Cette application est composée de trois fonctions :
-
void afficher_commande(const char *titre, int size)
void debiter()
void visionner_film()
a) Examinez l’application contenue dans le fichier labo6/c_x86/location_films.c.
Effectuez, si nécessaire, quelques recherches sur internet et décrivez comment utiliser une attaque de
type buffer overflow pour modifier le déroulement du programme (sans en altérer le code source) et
visionner un film sans que le compte de l’utilisateur ne soit débité.
Le code de la fonction afficher_commande(…) est le suivant :
void afficher_commande(const char *titre, int size) {
char recu[20];
strcpy(recu, "Location: ");
strncat(recu, titre, size);
afficher_recu(recu);
}
b) Réalisez l’attaque que vous avez décrite et documentez votre démarche dans le fichier
labo6/README.md
 U-Boot détectera votre attaque et un message vous indiquera que vous avez réussi l’exercice.
Faites une capture et ajoutez-là à votre labo6/README.md
 Dessinez le contenu de la pile pour illustrer votre attaque.
 (Bonus) Proposez un exemple de contre-mesure ou de protection contre cette attaque autre que
celui mis en place par U-Boot.
Indications
 Il est possible de modifier l’adresse de retour d’une fonction avec une attaque de type buffer
overflow
 Une variable d’environnement est disponible pour charger et exécuter le programme
location_films.bin.
 Une configuration de Debug a été ajoutée dans eclipse.
-3-
Téléchargement