Hello, fellow humans. This post explains the steps I took to get admin access to a server owned by Uber running the Aruba Airwave software for network management, along with some python scripting tips to easily automate the discovery of such issues based by doing some basic analysis of HTTP responses. To summarize, the main issues found were #1 the use of the default admin credentials as documented here: https://community.arubanetworks.com/t5/Monitoring-Management-Location/What-are-the-default-username-password/ta-p/169726, and #2 being an authenticated XXE vulnerability originally found in 2016 that still impacted the latest versions of the software. After receiving my report, Uber locked down their instance from the public, and reached out to Aruba about getting a fix implemented for the latest version. After working with Aruba for a few months, they were notified of a patch and updated their Airwave instance to 8.2.9, which fixed the XXE vulnerability. Even though these findings were technically out of scope, Uber ended up rewarding me with a $7,500 bounty based on the impact. :thumbsup:
My hunting started (and ended) with some recon on Shodan. Using the search query “org:uber” I narrowed down my search results to only Uber owned resources as indicated by the IP’s ASN. Within the search results, I noticed a unique favicon so I clicked on the corresponding host and was presented with an Aruba Airwave login page. In true 133t fashion, I tried the classic admin:admin username/password combo and was in! With access to this interface, I was able to access system backups/log files, IDS event triggers, floor layouts of each Uber office, and every client hostname/MAC/IP that was connected to their APs. Only adding this screenshot as I don’t want to disclose too much sensitive info regarding floor layout and client info.
The most interesting aspect of this finding was the ability to upload firmware updates to the Aruba AP controllers which could lead to code execution on APs throughout the Uber offices. I didn’t try this given the limitations of typical bug bounty engagements, but I wanted to take note of the potential RCE impact on infrastructure devices. I also wanted to add value to the report by seeing if there were any authenticated vulnerabilities which corresponded with the version of Airwave they were running. After some research, I wasn’t able to find RCE, but found an XXE vuln giving me read access to the file system via CVE-2016-8526 (https://nvd.nist.gov/vuln/detail/CVE-2016-8526)
Now that I’ve walked through the manual discovery of the issue, I’d like to transition and talk about an automated way this issue and similar issues can be detected using a simple python scripts.
First, we need to see what the response of a valid login request looks like, vs what the response of an invalid login request looks like. Here is the request of an invalid login request for this specific version of the Aruba Airwave Management platform. Notice that it returns a 403 status code.
Then observe what the response of a successful login request looks like. You’ll see we get a 302 redirect status code. The requests library will automatically redirect, so we will be looking for a 200 status code from the response object.
Now we can use this knowledge to write a script that will check the response of a login attempt to determine whether or not that login attempt was successful. The code below uses the requests library in order to send the POST request to submit the login form. It then checks whether or not the request was successful by checking to see if the response’s status code is 200.
We can go a step further and add a passive check to see if a host is actually running this Aruba Airwave interface first and decide if we need to issue the login request check based on the result, as to not send any unnecessary requests. We can do this by appending the following conditional statement to our code to see if the default cred check is actually necessary by searching for a specific string, which in this case will be: “AirWave Management Platform” in the response of a GET request to the host. After that is added, the completed code would look something like below:
I usually add signatures like this to my recon process in order to find low hanging fruit that yield high impact from a list of Hosts/IPs.
Hope this helps!