metasploit-framework/lib/msf/core/exploit/dcerpc.rb

138 lines
2.9 KiB
Ruby

require 'rex/proto/dcerpc'
module Msf
###
#
# 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
# 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
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 = {})
super
register_advanced_options(
[
OptInt.new('DCEFragSize', [ 1, 'Set the DCERPC packet fragmentation size', 127]),
OptBool.new('DCEMultiBind', [ 0, 'Use multi-context bind calls', 'T' ])
], Msf::Exploit::Remote::DCERPC)
register_options(
[
Opt::RHOST,
Opt::RPORT(135),
], Msf::Exploit::Remote::DCERPC)
end
#
# Generate a DCERPC bind request and send it on the default socket
#
def dcerpc_bind (uuid, vers = nil)
# Create the bind request
bind, ctx = dcerpc_make_bind(uuid, vers)
if (bind == nil)
return
end
# Verify that the socket exists
if (sock == nil)
return
end
# 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
end
end