Reword, spell correction

This commit is contained in:
Yorick Barbanneau 2023-03-30 11:12:02 +02:00
parent 70c0823fe7
commit 7a5794b87f

View file

@ -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`.