Land #4054, @jhart-r7's SunRPC lib and module cleanup

bug/bundler_fix sprint-F06
jvazquez-r7 2014-11-18 17:01:01 -06:00
commit 1f2313d87e
No known key found for this signature in database
GPG Key ID: 38D99152B9352D83
8 changed files with 91 additions and 62 deletions

View File

@ -38,24 +38,26 @@ module Exploit::Remote::SunRPC
register_advanced_options(
[
# XXX: Use portmapper to do call - Direct portmap to make the request to the program portmap_req
OptInt.new('TIMEOUT', [true, 'Number of seconds to wait for responses to RPC calls', 5])
# XXX: Use portmapper to do call - Direct portmap to make the request to the program portmap_req
], Msf::Exploit::Remote::SunRPC)
register_options(
[
# XXX: XPORT
# XXX: XPORT
Opt::RHOST,
Opt::RPORT(111),
], Msf::Exploit::Remote::SunRPC
)
end
def sunrpc_create(protocol, program, version)
def sunrpc_create(protocol, program, version, time_out = timeout)
self.rpcobj = Rex::Proto::SunRPC::Client.new(
:rhost => rhost,
:rport => rport.to_i,
:proto => protocol,
:program => program,
:timeout => time_out,
:version => version,
:context => {
'Msf' => framework,
@ -68,7 +70,7 @@ module Exploit::Remote::SunRPC
end
ret = rpcobj.create
return print_error("#{rhost}:#{rport} - SunRPC - No response to Portmap request") unless ret
raise ::Rex::Proto::SunRPC::RPCError, "#{rhost}:#{rport} - SunRPC - No response to Portmap request" unless ret
arr = XDR.decode!(ret, Integer, Integer, Integer, String, Integer, Integer)
if arr[1] != MSG_ACCEPTED || arr[4] != SUCCESS || arr[5] == 0
@ -76,18 +78,15 @@ module Exploit::Remote::SunRPC
err << 'Message not accepted' if arr[1] != MSG_ACCEPTED
err << 'RPC did not execute' if arr[4] != SUCCESS
err << 'Program not available' if arr[5] == 0
print_error(err)
return nil
raise ::Rex::Proto::SunRPC::RPCError, err
end
rpcobj.pport = arr[5]
#progname = progresolv(rpcobj.program)
#print_status("#{rhost} - SunRPC Found #{progname} on #{protocol} port #{rpcobj.pport}")
end
def sunrpc_call(proc, buf, timeout=20)
def sunrpc_call(proc, buf, timeout = timeout)
ret = rpcobj.call(proc, buf, timeout)
return print_error("#{rhost}:#{rport} - SunRPC - No response to SunRPC call for procedure: #{proc}") unless ret
raise ::Rex::Proto::SunRPC::RPCError, "#{rhost}:#{rport} - SunRPC - No response to SunRPC call for procedure: #{proc}" unless ret
arr = Rex::Encoder::XDR.decode!(ret, Integer, Integer, Integer, String, Integer)
if arr[1] != MSG_ACCEPTED || arr[4] != SUCCESS
@ -105,8 +104,7 @@ module Exploit::Remote::SunRPC
else err << "Unknown Error"
end
end
print_error("#{rhost}:#{rport} - SunRPC - #{err}")
return nil
raise ::Rex::Proto::SunRPC::RPCError, "#{rhost}:#{rport} - SunRPC - #{err}"
end
return ret
end
@ -142,8 +140,7 @@ module Exploit::Remote::SunRPC
when GARBAGE_ARGS then err << "Garbage Arguments"
else err << "Unknown Error"
end
print_error("#{rhost}:#{rport} - SunRPC - #{err}")
return nil
raise ::Rex::Proto::SunRPC::RPCError, "#{rhost}:#{rport} - SunRPC - #{err}"
end
return ret
@ -162,6 +159,11 @@ module Exploit::Remote::SunRPC
return "UNKNOWN-#{number}"
end
# Returns the time that this module will wait for RPC responses, in seconds
def timeout
datastore['TIMEOUT']
end
# Used to track the last SunRPC context
attr_accessor :rpcobj
end

View File

@ -6,6 +6,17 @@ module Rex
module Proto
module SunRPC
class RPCError < ::StandardError
def initialize(msg = 'RPC operation failed')
super
@msg = msg
end
def to_s
@msg
end
end
class RPCTimeout < ::Interrupt
def initialize(msg = 'Operation timed out.')
@msg = msg

View File

@ -127,6 +127,8 @@ class Metasploit3 < Msf::Auxiliary
# done
sunrpc_destroy
rescue Timeout::Error, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Rex::Proto::SunRPC::RPCError => e
print_error(e.to_s)
rescue ::Rex::Proto::SunRPC::RPCTimeout
print_warning 'Warning: ' + $!
print_warning 'Exploit may or may not have succeeded.'

View File

@ -6,7 +6,6 @@
require 'msf/core'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::SunRPC
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
@ -14,23 +13,22 @@ class Metasploit3 < Msf::Auxiliary
def initialize
super(
'Name' => 'SunRPC Portmap Program Enumerator',
'Description' => %q{
This module calls the target portmap service and enumerates all
program entries and their running port numbers.
},
'Description' => '
This module calls the target portmap service and enumerates all program
entries and their running port numbers.
',
'Author' => ['<tebo[at]attackresearch.com>'],
'References' =>
[
['URL', 'http://www.ietf.org/rfc/rfc1057.txt'],
['URL', 'http://www.ietf.org/rfc/rfc1057.txt']
],
'License' => MSF_LICENSE
)
register_options([], self.class)
end
def run_host(ip)
vprint_status "#{ip}:#{rport} - SunRPC - Enumerating programs"
peer = "#{ip}:#{rport}"
vprint_status "#{peer} - SunRPC - Enumerating programs"
begin
program = 100000
@ -38,42 +36,52 @@ class Metasploit3 < Msf::Auxiliary
procedure = 4
sunrpc_create('udp', program, progver)
sunrpc_authnull()
sunrpc_authnull
resp = sunrpc_call(procedure, "")
progs = resp[3,1].unpack('C')[0]
progs = resp[3, 1].unpack('C')[0]
maps = []
if (progs == 0x01)
print_good("#{ip}:#{rport} - Programs available")
while XDR.decode_int!(resp) == 1 do
map = XDR.decode!(resp, Integer, Integer, Integer, Integer)
maps << map
while XDR.decode_int!(resp) == 1
maps << XDR.decode!(resp, Integer, Integer, Integer, Integer)
end
end
sunrpc_destroy
return if maps.empty?
vprint_good("#{peer} - Found #{maps.size} programs available")
table = Rex::Ui::Text::Table.new(
'Header' => "SunRPC Programs for #{ip}",
'Indent' => 1,
'Columns' => %w(Name Number Version Port Protocol)
)
lines = []
maps.each do |map|
prog, vers, prot, port = map[0,4]
prot = if prot == 0x06; "tcp"
elsif prot == 0x11; "udp"
prog, vers, prot_num, port = map[0, 4]
thing = "RPC Program ##{prog} v#{vers} on port #{port} w/ protocol #{prot_num}"
if prot_num == 0x06
proto = 'tcp'
elsif prot_num == 0x11
proto = 'udp'
else
print_error("#{peer}: unknown protocol number for #{thing}")
next
end
lines << "\t#{progresolv(prog)} - #{port}/#{prot}"
resolved = progresolv(prog)
table << [ resolved, prog, vers, port, proto ]
report_service(
:host => ip,
:port => port,
:proto => prot,
:name => progresolv(prog),
:info => "Prog: #{prog} Version: #{vers} - via portmapper"
host: ip,
port: port,
proto: proto,
name: resolved,
info: "Prog: #{prog} Version: #{vers} - via portmapper"
)
end
# So we don't print a line for every program version
lines.uniq.each {|line| print_line(line)}
rescue ::Rex::Proto::SunRPC::RPCTimeout
print_good(table.to_s)
rescue ::Rex::Proto::SunRPC::RPCTimeout, ::Rex::Proto::SunRPC::RPCError => e
vprint_error(e.to_s)
end
end
end

View File

@ -76,11 +76,12 @@ class Metasploit3 < Msf::Auxiliary
:update => :unique_data
)
elsif(exports == 0x00)
print_status("#{ip} - No exported directories")
vprint_status("#{ip} - No exported directories")
end
sunrpc_destroy
rescue ::Rex::Proto::SunRPC::RPCTimeout
rescue ::Rex::Proto::SunRPC::RPCTimeout, ::Rex::Proto::SunRPC::RPCError => e
vprint_error(e.to_s)
end
end

View File

@ -80,9 +80,7 @@ class Metasploit3 < Msf::Exploit::Remote
print_status("Trying to exploit rpc.cmsd with address 0x%x ..." % brute_target['Ret'])
begin
if (not sunrpc_create('udp', 100068, 4))
fail_with(Failure::Unknown, 'sunrpc_create failed')
end
sunrpc_create('udp', 100068, 4)
# spray the heap a bit (work around powerpc cache issues)
buf = make_nops(1024 - @aixpayload.length)
@ -105,9 +103,11 @@ class Metasploit3 < Msf::Exploit::Remote
sunrpc_destroy
rescue Rex::Proto::SunRPC::RPCTimeout
# print_error('RPCTimeout')
vprint_error('RPCTimeout')
rescue Rex::Proto::SunRPC::RPCError => e
vprint_error(e.to_s)
rescue EOFError
# print_error('EOFError')
vprint_error('EOFError')
end
end

View File

@ -98,7 +98,12 @@ class Metasploit3 < Msf::Exploit::Remote
end
def brute_exploit(brute_target)
begin
sunrpc_create('udp', 100232, 10)
rescue Rex::Proto::SunRPC::RPCTimeout, Rex::Proto::SunRPC::RPCError => e
vprint_error(e.to_s)
return
end
unless @nops
print_status('Creating nop block...')
@ -145,6 +150,8 @@ class Metasploit3 < Msf::Exploit::Remote
sunrpc_call(1, request, 2)
rescue Rex::Proto::SunRPC::RPCTimeout
print_status('Server did not respond, this is expected')
rescue Rex::Proto::SunRPC::RPCError => e
print_error(e.to_s)
end
sunrpc_destroy

View File

@ -74,9 +74,7 @@ class Metasploit3 < Msf::Exploit::Remote
def exploit
begin
if (not sunrpc_create('tcp', 0x5F3DD, 2))
fail_with(Failure::Unknown, 'sunrpc_create failed')
end
sunrpc_create('tcp', 0x5F3DD, 2)
fs = "%n" * target['Offset']
fs << [target.ret].pack("V") # push esp # ret from MSVCR71.dll