When pentests are not enough

I am not a devoted adept of sytematic code reviews, and find that most of the time, penetration tests cover 80% of the vulnerabilities in a much shorter timeframe. Let's face it : usually, the return on investment is just much better. However, for complex pieces of software, a complementary analysis involving code review and dynamic testing can lead to interesting results, especially for critical features such as authentication, crypto-functions, or access control. Here is a a report regarding my latest finding (CVE-2019-11816), and the associated Proof Of Concept.

Let's plug it in

The discovery of this privilege escalation involved quite a bit of luck. Actually, I was not really interested in the security of the source code at first, but was rather trying to improve a module designed for the OPNsense firewall. While analyzing the structure of a plugin, I observed that access control to pages was declared in XML ACL files. Some of them use a wildcard to tell the routing module that pages are accessible event if parameters are speciified in the URL. Well, that did not smell that good.

ACL file

Is this page accessible? Yes it is.

Following the call stack and grepping heavily through the source code, I finally stumbled upon the isPageAccessible function.

isPageAccessible

Oh man, there is already something wierd in there. The call to strpos checks if the string "api/core/menu" is in the URL and returns true when it is the case. This means that if we specify a random parameter with this value, we can access any page if we are authenticated as a restricted user on the firewall. To test this hypothesis, I created a user that could only access the OpenVPN server module, and attempted to access the user manager page.

First bypass

Well, it works. Of course, it is also possible to forge a POST request on the page and create a new admin user.

Does this URL match? Well, it does.

To be honest, I did not expect to discover this security issue. My first suspicion was more related to the URL matching system, which is most probably based on a custom URL parser. The urlMatch function does just that.

urlMatch

Here, we notice that no particular check is performed on the URL format, and that the defined wildcard was interpreted directly. If you are a bit familiar with software security, the first thing you should think about is directory traversal. And you would be right. I tested it in a really basic way using the following request, which also worked.

Second Bypass

We have a second way to escalate to administrator!

Kill two birds with one stone

I immediately reported both of the bypasses to the OPNsense team who has been awesomely friendly and reactive, as they provided a patch under three hours. They also notified me about the fact that pfSense was most likely vulnerable to the second variant of the bypass, which turned out to be true. Massive shoutout to Ad Schellevis and Franco Fichtner from the OPNsense team for their incredible work.

Who's impacted ?

If you are running OPNsense before version 19.1.8, or pfSense before 2.4.4-p3, you are impacted. However, the bypass requires that the attacker is authenticated and authorized to access at least one module on the firewall. This is not such a frequent usecase, so you should probably not worry about this vulnerability.

References

CVE NIST

OPNsense release notes

pfSense release notes

Need offensive security services, or application security support? CryptID has got you covered!

Next Post Previous Post