In the course of collecting and disclosing vulnerabilities, I occasionally come across an issue that walks like a vuln, quacks like a vuln, but… it’s not exactly a vuln. As per our usual vulnerability disclosure process, we still report these issues to vendors. The behavior observed is nearly always a bug of some sort, but it’s not immediately exploitable, or the “exploit” is merely exercising the expected level of privilege, but in an unexpected context.
Post-authentication -- the case where a behavior can only be exercised by an authenticated user -- is a killer for prioritizing bugfixes, and tends to kick otherwise serious vulnerabilities way down the priority ladder. If you work in software development, you’ve probably run into the curious phenonemon that a “low priority” assignment to a bug really means no priority, and the security issues described here are no different.
Now, “post-auth” isn’t the only vulnerability quality that devalues a bug, but it is a pretty solid killer. This macOS vulnerability and this Android bug were (correctly) rated as fairly high severity issues despite being post-authentication, but it’s difficult for most post-auth bugs to claw their way out of the no-priority pile at the bottom of the queue. In my (purely) anecdotal experience, these kinds of bugs tend to linger until (a) more than one or two users complain about them, (b) they attract the attention of influential, in-house expertise, or (c) they get refactored away during a top-to-bottom component rewrite.
The problem with not addressing bugs that have vague and tenuous security implications is that many of the best penetration testing stories involve chaining together two, five, or ten of these “unexpected behavior” corner cases into a full-blown domain compromise. So, in the spirit of National Cyber Security Awareness Month, I want to offer up some examples of these low-risk, no-priority issues. The goal here is to define some terms and discuss no-priority post-auth vulnerabilities like these, and hopefully start a conversation around how we in the industry prioritize them. After all, you might have one or two like this lurking in your WontFix backlog, so you might find real examples out in the world illuminating.
Authenticated User Enumeration: Tableau Server (R7-2017-09)
While on a penetration testing engagement, Rapid7 consultant and researcher Robert Stewart managed to gain access to an on-site instance of Tableau Server, and found that any authenticated user can collect the usernames of all the users on the system. The twist here is that there is no such functionality in Tableau Server; normally, only administrators can list all local users, regular users shouldn’t have this power. Robby was able to sidestep this restriction by creating a specially crafted POST request with a with a null or blank value for the username field of a different API call, as seen in the Burp Suite screenshot below:
So, while we appear to have a privilege escalation on our hands here, it turns out, usernames aren’t actually secret. Yes, the direct access to a list of users on a given site is restricted to administrators, but in reality, normal users can of course see other people’s usernames -- it’s required functionality in order to do things like autocomplete, or view other people’s workbooks, and all sorts of other normal functions of the application. Given this, it’s certainly possible to use web scraping techniques to just cycle through all the content on a given Tableau Server site and nab all the usernames.
However, penetration testers, like real criminals, are pretty lazy. Being able to abuse an API call to simplify an otherwise tedious task of collecting usernames certainly makes easier the job of credential bruteforcing. In this case, Tableau Server does support account lockouts by integrating with Active Directory or SAML authentication, but the installation found on site was using a local authentication scheme that lacks account lockout controls. So, once armed with a list of valid users, it was only a matter of time before one of them fell over to bruteforcing.
Here, we have a case of not-technically-a-vulnerability -- a categorization that we and Tableau ultimately concluded. Authenticated users can always figure out who the other users are through various creative means. Usernames aren’t secret from other authenticated users on this or nearly any other platform. That said, this API abuse certainly makes things easier for the attacker.
Insider Spoofing: Duo login_duo (R7-2017-17)
Jon Hart, a researcher here at Rapid7, was monkeying around with our own Duo two-factor authentication installation, and found a bit of weirdness lurking in the Linux agent, login_duo. While Duo recommends using the more robust pam_duo PAM module, sometimes you need to go with login_duo to provide 2FA for SSH connections.
As it turns out, login_duo reads data directly from the environment variable, SSH_CONNECTION, which normally is written to by OpenSSH through a socket inspection. However, if a local, already authenticated user can invoke login_duo directly, they can write whatever they want to SSH_CONNECTION. This can lead to either convincing-looking alerts that happen to come from other planets:
...or complete nonsense:
The Duo administrator console is similarly fooled with bogus SSH_CONNECTION data, but sadly, does not render emojis:
All of this is well and good, but again, what does this get an attacker? First off, the attacker would already need to have pretty great local access to a machine that’s running the Duo 2FA authenticator -- and in that case, unless they’re root, their local username is going to be part of the authenticated message, so it’ll be pretty easy to figure out who’s up to shenanigans. It could be useful to an attacker who has this access to start spamming the Duo admin with fake alert messages in hopes of later getting some unsupervised chances at brueforcing the 2FA scheme, but this kind of an attack is hard to imagine actually happening -- there are better ways to DoS a person with annoying messages.
In the end, this is a case of trusting data from a source that’s…well, usually pretty trustworthy, but could be subverted for…reasons not entirely clear yet. As you might expect, we all agreed in the end that it was a pretty funny finding, but ultimately, not a very valuable attack vector.
Administrative XSS: Cisco ASA (R7-2017-04)
While on site, penetration tester Kirk Hayes managed to snag Administrative credentials on the customer’s Cisco ASA VPN terminator. How exactly that happened is neither here nor there, but he did notice a couple issues once on the box. First, Kirk figured out that usernames could be enumerated by anyone (not just admins) thanks to differences between the authentication failure messages: for users that exist, “Login Failed” messages were generated, while nonexistent users triggered an “Authentication Failed” message. This is an honest and true vulnerability, and Cisco addressed it with an advisory. Huzzah for vendor disclosure.
The other issue we reported didn’t get much traction, though. Due to a lack of input sanitization, the configurable WebVPN login form could be host to a persistent XSS boobytrap in the “Username Prompt” field. This would trigger upon any other user’s login attempt, and from there, the user’s browser could be hooked, sessions stolen, all the usual XSS hijinks. However, you need to be an Administrator in order to configure the WebVPN login page, and we agreed with Cisco that an ASA admin has plenty of opportunity to mess around with remote users in various subtle or obvious ways.
Once again, we’re left with an input sanitization issue that could only really be exploited by someone who already has a ton of insider privilege. But, it’s also a case where this absolutely came in handy on a live penetration test. Using one high-privilege account on one high value, internet-facing device to collect other people’s credentials is pretty much pentesting bread-and-butter.
Third-Party Unsafe Export: Rapid7 Nexpose (NEX-50645)
To be sure, Rapid7 has its own share of bugs, since everyone who produces complex software is going to occasionally ship a bug here and there. At any rate, a little while back, independent researcher Raghav Bisht reported an issue against Nexpose, which we started tracking as NEX-50645.
By constructing an asset tag in Nexpose as a Microsoft Excel formula, that tag can ultimately get evaluated by Microsoft Excel and executed. This sounds like a sneaky way to use your vulnerability management system against you to deliver some Office malware… except there are some barriers to actually getting malicious code to run.
For starters, the permission to create tags is usually only granted to the Global Administrator, or by an administrator to a trusted user. So, not only is this an authenticated attack, but it’s another case of needing enhanced privileges. Next, in order to execute this attack, you’d need to convince your target to export a report from Nexpose as a CSV file. There’s no automated way we could find to get a user to do this, and the process takes a fair bit of typing -- it’s not something that you can easily clickjack them into. Finally, Microsoft Excel will tend to not execute unsafe formulas from documents converted from CSV -- it throws up all kinds of warnings about this when you try, so you need to be pretty determined in order to get owned.
That all said, should Nexpose asset tags be interpreted as executable Excel formulas? They’re certainly not designed to act that way, and there’s no expectation here that people use them this way. This is clearly a case of weird behavior that could, under some pretty limited circumstances, conceivably advance an attacker’s goals. (As an aside, Google has already addressed this exact sort of issue as not a bug).
While we’re inclined to agree, we do think we can make this kind of injection-and-export issue harder to exploit (rather, harder than it already is) by employing some more strict input sanitization on tag names. Stay tuned for that fix (but in the meantime, don’t worry about it terribly -- if your Global Administrator wants to mess up your Nexpose-using day, they have many easier opportunities to do so).
Although I’ve been around the vulnerability disclosure circus for a while, I honestly don’t know what the “right” response is to bugs like these. It would be great to commit to fix every security-smelling bug reported, but the realities of time constraints, effort, and money are inevitably going to freeze some of these issues out. So far, we here at Rapid7 have agreed with the vendors on all of these -- they’re not directly exploitable issues, but merely weird things that sometimes help penetration testers (and possibly real threat actors) get down to the business of popping shells.
While there’s no easy answer to the question of how to deal with all post-auth vulnerabilities, it is valuable to consider them from a different angle than simply their individual impact. How useful might the data revealed be to an attacker that does happen to have authenticated access? If the vulnerability would allow them to greatly speed up their attack on your products and infrastructure, you may want to reconsider that assigned low-but-really-no priority.