TD9 corrections and rewords

This commit is contained in:
Yorick Barbanneau 2023-04-23 00:31:51 +02:00
parent 60aecd0591
commit d4fb4c586a

View file

@ -11,7 +11,7 @@ author:
### Première exécution du programme ### Première exécution du programme
Le programme demande à l'utilisateur une saisir, lorsque je rentre un texte, il Le programme demande à l'utilisateur une saisie, lorsque je rentre un texte, il
répond `Nope`: répond `Nope`:
``` ```
@ -41,7 +41,7 @@ retour.
### avec strings ### avec strings
L'exécution de `strings hackme` montre des choses interessantes. On y voit des L'exécution de `strings hackme` montre des choses intéressantes. On y voit des
traces des fonctions `wprintf` (qui pourrait être utile pour la suite), traces des fonctions `wprintf` (qui pourrait être utile pour la suite),
`strlen`. `getline`. On voit aussi tout un tas d'autres chaines qui semble être `strlen`. `getline`. On voit aussi tout un tas d'autres chaines qui semble être
des mots de passe: des mots de passe:
@ -51,8 +51,8 @@ des mots de passe:
GLIBC_2.2 GLIBC_2.2
GLIBC_2.0 GLIBC_2.0
__gmon_start__ __gmon_start__
ZYh< ZYh<
ZYh0 ZYh0
8Eureu% 8Eureu%
UWVS UWVS
[^_] [^_]
@ -65,8 +65,8 @@ GCC: (Debian 8.3.0-6) 8.3.0
[...] [...]
``` ```
`IAmSuperSecure` parait relativement intéressant. mais à ce state rien n'est `IAmSuperSecure` parait relativement intéressant. Mais à ce stade rien n'est
sûr. Mais juste comme ça essayons tout de même un `lstrace` sur nore programme: sûr. Mais juste comme ça essayons tout de même un `lstrace` sur notre programme:
``` ```
ltrace ./hackme ltrace ./hackme
@ -84,10 +84,10 @@ exit(1 <no return ...>
La sortie de `ltrace` une fois la saisie effectuée, montre qu'elle est comparée La sortie de `ltrace` une fois la saisie effectuée, montre qu'elle est comparée
avec `IAmSuperSecure`, un essai le confirme. Comme dirait Bernard dans <u>Day of avec `IAmSuperSecure`, un essai le confirme. Comme dirait Bernard dans <u>Day of
the Tentacle</u>: *This is all too easy!* : the Tentacle</u>: *"This is all too easy!"* :
``` ```
./hackme ./hackme
This is level 0, welcome! What do you have to say? This is level 0, welcome! What do you have to say?
IAmSuperSecure IAmSuperSecure
Ok, that was easy! Ok, that was easy!
@ -136,7 +136,7 @@ $2 = 0x804d030 <p> "HelloDad"
``` ```
Nous avons notre mot de passe `HelloDad`. Mais cette chaine ne figure pas dans Nous avons notre mot de passe `HelloDad`. Mais cette chaine ne figure pas dans
la liste des chaines données par la commande `strings`, elle est donc obsurcie. la liste des chaines données par la commande `strings`, elle est donc obscurcie.
Essayons donc de comprendre comment. Recommençons l'exécution avec un `watch` Essayons donc de comprendre comment. Recommençons l'exécution avec un `watch`
la chaine contenue sur le programme: la chaine contenue sur le programme:
@ -184,12 +184,12 @@ Dump of assembler code for function z:
En observant le contenu de cette fonction, on comprend alors que le En observant le contenu de cette fonction, on comprend alors que le
déchiffrement du mot de passe du niveau 2 se fait en retirant `0x9` à chaque déchiffrement du mot de passe du niveau 2 se fait en retirant `0x9` à chaque
caractère de la chaine contenue dans le programme. On retrouv caractère de la chaine contenue dans le programme.
## Level 2 ## Level 2
C'est reparti pour un tour! Nouvelle exécution du programme en plaçant un point C'est reparti pour un tour! Nouvelle exécution du programme avec *gdb* en
d'arrêt sur `srtcmp@plt` et on arrive jusqu'au niveau 2: plaçant un point d'arrêt sur `srtcmp@plt` et on arrive jusqu'au niveau 2:
``` ```
On to level 2! So what do you want? On to level 2! So what do you want?
@ -202,18 +202,18 @@ Breakpoint 1, 0x08049030 in strcmp@plt ()
#2 0x080490cd in main () #2 0x080490cd in main ()
``` ```
Cette fois-ci c'est la fonction `r2()` qui s'occupe du "déchiffrement, voici son Cette fois-ci c'est la fonction `r2()` qui s'occupe du "déchiffrement", voici
code désassemblé : son code désassemblé :
``` ```
(gdb) frame 1 (gdb) frame 1
#1 0x080493ca in r2 () #1 0x080493ca in r2 ()
(gdb) disass (gdb) disass
Dump of assembler code for function r2: Dump of assembler code for function r2:
0x080493a0 <+0>: push %ebx 0x080493a0 <+0> push %ebx
0x080493a1 <+1>: sub $0x14,%esp 0x080493a1 <+1>: sub $0x14,%esp
0x080493a4 <+4>: push $0x804a280 0x080493a4 <+4>: push $0x804a280
0x080493a9 <+9>: call 0x8049060 <wprintf@plt> 0x080493a9 <+9>: call 0x8049060 <wprintf@plt>
0x080493ae <+14>: call 0x8049220 <r> 0x080493ae <+14>: call 0x8049220 <r>
0x080493b3 <+19>: mov %eax,%ebx 0x080493b3 <+19>: mov %eax,%ebx
0x080493b5 <+21>: mov %eax,(%esp) 0x080493b5 <+21>: mov %eax,(%esp)
@ -251,7 +251,7 @@ Code de `x1()` qui "chiffre" la saisie utilisateur du troisième mot de passe.
C'est le chiffrement inverse de celui vu au niveau 1, ici on ajoute `0x9` à C'est le chiffrement inverse de celui vu au niveau 1, ici on ajoute `0x9` à
chaque caractère. chaque caractère.
Pour déchiffrer le mote de passe écrit dans le programme, j'ai écris un script Pour déchiffrer le mot de passe écrit dans le programme, j'ai écris un script
Python : Python :
```python ```python
@ -267,7 +267,7 @@ ce qui nous donne `IWantTea`
### Level 3 ### Level 3
Après avoir lancé le programme et atteint la saisie du niveau 3, `Ctrl+c` envoi Après avoir lancé le programme et atteint la saisie du niveau 3, `Ctrl+c` envoi
le signal `SIGINT` au programme, donne la main à l'invite de commande. voici le le signal `SIGINT` au programme, donne la main à l'invite de commande. Voici le
résultat de la commande `bt`: résultat de la commande `bt`:
``` ```
@ -277,10 +277,9 @@ résultat de la commande `bt`:
#7 0x080490d2 in main () #7 0x080490d2 in main ()
``` ```
`r()` se se charge de la saisie, mais que fait `wut()`, interessons nous `r()` se se charge de la saisie, mais que fait `wut()`? Intéressons nous
à cette fonction d'abord passant dans sa frame puis en la désassemblant: à cette fonction d'abord passant dans sa frame puis en la désassemblant:
``` ```
(gdb) frame 6 (gdb) frame 6
#6 0x08049403 in wut () #6 0x08049403 in wut ()
@ -310,7 +309,7 @@ End of assembler dump.
``` ```
Voici deux comparaisons intéressantes. La première s'effectue sur les 4 octets à Voici deux comparaisons intéressantes. La première s'effectue sur les 4 octets à
l'adresse contenur dans `%eax`. La suivante sur le contenu à l'adresse de l'adresse contenue dans `%eax`. La suivante sur le contenu à l'adresse de
`%eax + 0x4`. `%eax + 0x4`.
Un script Python permet encore une fois de transformer ces deux valeurs en Un script Python permet encore une fois de transformer ces deux valeurs en
@ -339,15 +338,15 @@ print('Level 3 text: {}'.format(finaltext))
``` ```
La seconde série de boucles de ce script sert à remettre les octets dans le bon La seconde série de boucles de ce script sert à remettre les octets dans le bon
ordre. En effet les données sont mises sur la pile et chaque élément de 4 octets ordre. En effet les données sont mises sur la pile donc chaque élément de 4
doit être inversé. octets doit être inversé.
Le mot de passe est `EureKa!` Le mot de passe est `EureKa!`
## Level 4 ## Level 4
comme pour le niveau 3, il faut utiliser la technique du `ctrl+c` pour utiliser Comme pour le niveau 3, il faut exécuter notre programme dans gdb, utiliser la
`bt`: technique du `ctrl+c` puis `bt`:
``` ```
... ...
@ -356,11 +355,12 @@ comme pour le niveau 3, il faut utiliser la technique du `ctrl+c` pour utiliser
#7 0x080490d7 in main () #7 0x080490d7 in main ()
``` ```
C'est la fonction `aa()` qui appelle `r()` (fonction de saisie), intéressons
C'est la fonction `aa()` qui appelle `r()` (fonction de saicie), Interessons nous à elle en la désassemblant :
nous à elle en la désassamblant :
``` ```
(gdb) frame 6
[...]
(gdb) disass (gdb) disass
Dump of assembler code for function aa: Dump of assembler code for function aa:
0x080494d0 <+0>: push %ebx 0x080494d0 <+0>: push %ebx
@ -393,10 +393,9 @@ Dump of assembler code for function aa:
End of assembler dump. End of assembler dump.
``` ```
Cette fonction appelle une autre foncion : `bb()`. C'est elle qui semble se Cette fonction appelle une autre : `bb()`. C'est elle qui semble se charger de
charger de la vérification de la saisie. la vérification de la saisie. Avant de l'étudier, voyons comment `aa()` met les
éléments en place avant de l'appeler :
Mais avant ça `aa()` met les élements en place:
* mets l'adresse vers la zone mémoire contenant la saisie utilisateur dans * mets l'adresse vers la zone mémoire contenant la saisie utilisateur dans
l'adresse contenue dans `%esp` l'adresse contenue dans `%esp`
@ -405,17 +404,18 @@ Mais avant ça `aa()` met les élements en place:
`%ebx` `%ebx`
* `%esp` est incrémenté de 16 (*0x10*). * `%esp` est incrémenté de 16 (*0x10*).
* Ensuite le résultat de `strlen()` est comparé à 4, en cas de non égalité, le * Ensuite le résultat de `strlen()` est comparé à 4, en cas de non égalité, le
procgramme branche sur `f()` qui met fin à l'exécution.. Nous pouvons donc en programme branche sur `f()` qui met fin à l'exécution.. Nous pouvons donc en
déduite que notre saisie doit être de 4 cacactères exactement. déduite que notre saisie doit être de 4 caractères exactement.
* La pile est ensuite décrémentée de 8 * La pile est ensuite décrémentée de 8
* *0x804adf5* est ensuite positionné sur la pile, Il semble que se soit une * *0x804adf5* est ensuite positionné sur la pile, Il semble que se soit une
adresse. le contenu de cette espace mémoire est *0x66737a65*. adresse. Le contenu de cette espace mémoire est *0x66737a65*.
* `%ebx` est ensuite poussé sur la pile * `%ebx` est ensuite poussé sur la pile
* `bb()` est appelée, c'est cette fonction qui se chage du 'déchiffrement' * `bb()` est appelée, c'est cette fonction qui se charge du 'déchiffrement'
### La fonction `bb()` ### La fonction `bb()`
voic le code de cette fonction donné par `objdump` avec l'affichage des sauts : Voici le code de cette fonction donné par `objdump` avec l'affichage des sauts :
``` ```
8049470: 56 push %esi 8049470: 56 push %esi
8049471: 53 push %ebx 8049471: 53 push %ebx
@ -451,13 +451,13 @@ voic le code de cette fonction donné par `objdump` avec l'affichage des sauts :
Voici un déroullé des instructions principales de cette fonction : Voici un déroullé des instructions principales de cette fonction :
* `8049472` : on mets en place le contenu de l'adresse contenant notre série de * `8049472` : on mets en place le contenu de l'adresse vers notre série de
4 octets mystères *0x66737a65* dans `%ebx` 4 octets mystères (*0x66737a65*) dans `%ebx`
* `8049476` : l'adresse vers notre saisie est positionnée dans `%esi` * `8049476` : l'adresse vers notre saisie est positionnée dans `%esi`
* `804947a` : l'octet de poids faible de `%ebx` est copié dans `%edx` * `804947a` : l'octet de poids faible de `%ebx` est copié dans `%edx`
* `804947d` : et logique de `%dl` sur lui même, si le test est vrai alors le * `804947d` : et logique de `%dl` sur lui même, si le test est vrai alors le
programme branche sur la fin "normale" de la fonction. Ceci signifirait que programme branche sur la fin "normale" de la fonction. Ceci signifiait que
notre chaine mystère est vide (donc pas de mot de passe). notre chaine mystère est vide (donc pas de mot de passe dans le programme).
* `8049481` : l'octet de poids faible de notre saisie `%esi` est positionné * `8049481` : l'octet de poids faible de notre saisie `%esi` est positionné
dans `%eax` dans `%eax`
* `8049484` : un `xor` est ensuite réalisé entre *0x12* et `%eax` * `8049484` : un `xor` est ensuite réalisé entre *0x12* et `%eax`
@ -465,11 +465,11 @@ Voici un déroullé des instructions principales de cette fonction :
* `8049489` : en cas d'inégalité, la fonction se termine. * `8049489` : en cas d'inégalité, la fonction se termine.
* `804948b` : *0x1* est écrit dans `%eax`. * `804948b` : *0x1* est écrit dans `%eax`.
* `8049490` : Branchement vers l'instruction `80494a6` * `8049490` : Branchement vers l'instruction `80494a6`
* `80494a6` : l'octet de poid faible de `(%esi,%eax,1)` correspondant à la * `80494a6` : l'octet de poids faible de `(%esi,%eax,1)` correspondant à la
lettre suivante de notre chaine mystère `ecx` lettre suivante de notre chaine mystère `ecx`
* `80494aa` : si l'opération booleene de `%cl` sur lui même est différente de * `80494aa` : si l'opération booléenne de `%cl` sur lui même est différente de
zéro alors le probramme branche sur `8049498`. Ce test permet de savoir si on zéro alors le programme branche sur `8049498`. Ce test permet de savoir si on
est en fin de chaine (`\0`) sur notre chaine mystère. sinon le fil de code est en fin de chaine (`\0`) sur notre chaine mystère. Sinon le fil de code
continue jusqu'à la fin de la fonction. continue jusqu'à la fin de la fonction.
* `8049498` : le programme prend le caractère suivant de notre saisir et le * `8049498` : le programme prend le caractère suivant de notre saisir et le
place dans `%edx` place dans `%edx`
@ -480,9 +480,9 @@ Voici un déroullé des instructions principales de cette fonction :
revenons à l'instruction `80494a6`. revenons à l'instruction `80494a6`.
En clair, notre chaine mystère est bien le **mot de passe "chiffré"**, un simple En clair, notre chaine mystère est bien le **mot de passe "chiffré"**, un simple
*xor* avec *0x12* sur cachun des caractères de ce dernier nous permettra de *xor* avec *0x12* sur chacun des caractères de ce dernier nous permettra de
trouver le mot de passe à saisir. On utilise pour celà la propriété suivante du trouver le mot de passe à saisir. On utilise pour cela la propriété suivante du
*"ou exclusif"* *"ou exclusif"* :
$$A \oplus B = C \implies C \oplus B = A$$ $$A \oplus B = C \implies C \oplus B = A$$
@ -516,11 +516,11 @@ Ce qui donne:
Level 4 text: what Level 4 text: what
``` ```
Le mot de pase de ce niveau est donc `what` Le mot de passe de ce niveau est donc `what`
## Niveau 5 ## Niveau 5
Ici encore la technique du `ctrl+c` fonctionne bien: Ici encore la technique du `ctrl+c` fonctionne bien :
``` ```
[...] [...]
@ -573,7 +573,7 @@ sauts affichés par `objdump` :
``` ```
Sans rentrer dans les détails instruction par instruction comme fait lors du Sans rentrer dans les détails instruction par instruction comme fait lors du
niveau précédent, cette fonction: niveau précédent, cette fonction :
* Vérifie que la saisir utilisateur soit supérieure à 3 caractères * Vérifie que la saisir utilisateur soit supérieure à 3 caractères
(instructions `8049548` à `8049553`) (instructions `8049548` à `8049553`)
@ -581,10 +581,10 @@ niveau précédent, cette fonction:
* Boucle sur les caractères contenus dans la chaine saisie par l'utilisateur et * Boucle sur les caractères contenus dans la chaine saisie par l'utilisateur et
réalise un `xor` de celui-ci avec `%ecx`. Le résultat de cette opération est réalise un `xor` de celui-ci avec `%ecx`. Le résultat de cette opération est
stockée dans `%ecx` (instructions `8049555` à `804956a`). stockée dans `%ecx` (instructions `8049555` à `804956a`).
* Cette boucle s'arrete lorsque le caractère fin de chaine (`\0`) est trouvé * Cette boucle s'arrête lorsque le caractère fin de chaine (`\0`) est trouvé
(instruction `8049568`) (instruction `8049568`)
* Compare `%ecx` à `0x43`, s'il y a égalité alors le programme continue, sinon * Compare `%ecx` à `0x43`, s'il y a égalité alors le programme continue, sinon
la fonction `f()` est appelée, ammenant la mauvaise fin. la fonction `f()` est appelée, amenant vers la mauvaise fin.
Cat algorithme de chiffrement est vraiment faible, quelques ligne en Python Cat algorithme de chiffrement est vraiment faible, quelques ligne en Python
permettent de générer des mots de passes valides: permettent de générer des mots de passes valides:
@ -613,3 +613,24 @@ manquant pour arriver à `0x43`:
./level5.py Toto ./level5.py Toto
here is your password: Totoc here is your password: Totoc
``` ```
Maintenant il est possible de passer le dernier niveau :
```
.hackme
[...]
Level 5 is onboard! Will you make it?
Totoc
Yay!
************************************************
* ____ _ _ *
* / ___|___ _ __ __ _ _ __ __ _| |_ ___| | *
* | | / _ \| '_ \ / _` | '__/ _` | __/ __| | *
* | |__| (_) | | | | (_| | | | (_| | |_\__ \_| *
* \____\___/|_| |_|\__, |_| \__,_|\__|___(_) *
* |___/ *
* *
* You passed all the levels!! *
************************************************
```