continue TD9

This commit is contained in:
Yorick Barbanneau 2023-04-30 19:01:09 +02:00
parent b52709be62
commit 713e8d12c4

View file

@ -99,7 +99,7 @@ Une fois pframe installé et le point d'arrêt positionné sur `strcmp@plt`, la
*pile d'appel* montre que la fonction appelante est `r1()`. Une fois passé dans *pile d'appel* montre que la fonction appelante est `r1()`. Une fois passé dans
son contexte, analysons le code assembleur: son contexte, analysons le code assembleur:
``` ```{.numberLines}
[...] [...]
(gdb) bt (gdb) bt
#0 0x08049030 in strcmp@plt () #0 0x08049030 in strcmp@plt ()
@ -124,9 +124,11 @@ Dump of assembler code for function r1:
0x08049375 <+37>: test %eax,%eax 0x08049375 <+37>: test %eax,%eax
``` ```
\pagebreak
Nous pouvons voir que les adresses vers les chaines comparées par `strcmp()` Nous pouvons voir que les adresses vers les chaines comparées par `strcmp()`
sont positionnées sur la pile comme le montre les commentaires ci-dessus. sont positionnées sur la pile comme le montre les commentaires aux lignes 17 et
Affichons le contenu pointés par celles-ci avec `gdb`: 19 de la capture `gdb` ci-dessus. Mais que contiennes ces adresses :
``` ```
(gdb) p (char*)($eax) (gdb) p (char*)($eax)
@ -186,6 +188,8 @@ 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. caractère de la chaine contenue dans le programme.
\pagebreak
## Level 2 ## Level 2
C'est reparti pour un tour! Nouvelle exécution du programme avec *gdb* en C'est reparti pour un tour! Nouvelle exécution du programme avec *gdb* en
@ -251,6 +255,8 @@ 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.
\pagebreak
Pour déchiffrer le mot 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 :
@ -264,7 +270,7 @@ print(cleartext)
ce qui nous donne `IWantTea` 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
@ -312,6 +318,8 @@ Voici deux comparaisons intéressantes. La première s'effectue sur les 4 octets
l'adresse contenue 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`.
\pagebreak
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
texte, le voici: texte, le voici:
@ -518,7 +526,7 @@ Level 4 text: what
Le mot de passe de ce niveau est donc `what` Le mot de passe de ce niveau est donc `what`
## Niveau 5 ## Level 5
Ici encore la technique du `ctrl+c` fonctionne bien : Ici encore la technique du `ctrl+c` fonctionne bien :
@ -586,8 +594,46 @@ niveau précédent, cette fonction :
* 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, amenant vers 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 Cet algorithme de chiffrement est vraiment faible. `0x43` correspond à `C` dans
permettent de générer des mots de passes valides: la table ascii, utilisons les mathématiques:
\begin{gather}
\nonumber0 \oplus A = A\\
\nonumber\text{et } A \oplus A = 0\\
\nonumber\text{ainsi } 0 \oplus A \oplus A = 0\\
\nonumber\text{donc } 0 \oplus A \oplus A \oplus A \oplus A \oplus B = B
\end{gather}
Ansi saisir un même caractère un nombre pair de fois suivi de `C`, alors c'est
gagné :
```
.hackme
[...]
Level 5 is onboard! Will you make it?
xxxxC
Yay!
************************************************
* ____ _ _ *
* / ___|___ _ __ __ _ _ __ __ _| |_ ___| | *
* | | / _ \| '_ \ / _` | '__/ _` | __/ __| | *
* | |__| (_) | | | | (_| | | | (_| | |_\__ \_| *
* \____\___/|_| |_|\__, |_| \__,_|\__|___(_) *
* |___/ *
* *
* You passed all the levels!! *
************************************************
```
Pour ameliorer le chiffrement, il faudrait pouvoir vérifier le `xor` sur 4
octets set non sur un seul.
### script pour trouver les mots de passe
Il est aussi très simple d'écrire un script permettent de générer des mots de
passes permettant de passer le niveau 5. Par exemple, celui-ci ajoute le
caractère de fin au mot fourni par l'utilisateur :
```python ```python
#!/bin/env python3 #!/bin/env python3
@ -606,31 +652,9 @@ last_letter=xor^target
print("here is your password: {}{}".format(password,chr(last_letter))) print("here is your password: {}{}".format(password,chr(last_letter)))
``` ```
L'utilisation est simple, on donne un mot de passe et il ajoute le caractère L'utilisation est simple:
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!! *
************************************************
```