diff --git a/content/secu_logicielle/td9-hackme/index.md b/content/secu_logicielle/td9-hackme/index.md index 1eed4bf..2074108 100644 --- a/content/secu_logicielle/td9-hackme/index.md +++ b/content/secu_logicielle/td9-hackme/index.md @@ -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 son contexte, analysons le code assembleur: -``` +```{.numberLines} [...] (gdb) bt #0 0x08049030 in strcmp@plt () @@ -124,9 +124,11 @@ Dump of assembler code for function r1: 0x08049375 <+37>: test %eax,%eax ``` +\pagebreak + 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. -Affichons le contenu pointés par celles-ci avec `gdb`: +sont positionnées sur la pile comme le montre les commentaires aux lignes 17 et +19 de la capture `gdb` ci-dessus. Mais que contiennes ces adresses : ``` (gdb) p (char*)($eax) @@ -138,7 +140,7 @@ $2 = 0x804d030
"HelloDad" 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 obscurcie. 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 : ``` (gdb) wa * (char*)0x804d030 @@ -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 caractère de la chaine contenue dans le programme. +\pagebreak + ## Level 2 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` à chaque caractère. +\pagebreak + Pour déchiffrer le mot de passe écrit dans le programme, j'ai écris un script Python : @@ -264,7 +270,7 @@ print(cleartext) 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 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 `%eax + 0x4`. +\pagebreak + Un script Python permet encore une fois de transformer ces deux valeurs en texte, le voici: @@ -518,7 +526,7 @@ Level 4 text: what Le mot de passe de ce niveau est donc `what` -## Niveau 5 +## Level 5 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 la fonction `f()` est appelée, amenant vers la mauvaise fin. -Cat algorithme de chiffrement est vraiment faible, quelques ligne en Python -permettent de générer des mots de passes valides: +Cet algorithme de chiffrement est vraiment faible. `0x43` correspond à `C` dans +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 #!/bin/env python3 @@ -606,31 +652,9 @@ last_letter=xor^target 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 -manquant pour arriver à `0x43`: +L'utilisation est simple: ``` ./level5.py Toto 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!! * -************************************************ -```