In a lot of web application penetration tests that I’ve done in last couple of years I noticed that the amount of technical vulnerabilities (i.e. XSS or SQL injection) is slowly declining. Of course, this depends on developers’ awareness but also on frameworks that are used for development of such applications. One of the best (or worst, depending on the point of view) is definitely .NET (yeah, I know, it feels weird to say that Microsoft is best in something security related).
With .NET applications, a whole range of security vulnerabilities is actually eliminated by default. For example, XSS vulnerabilities are prevented by default (the infamous “A potentially dangerous Request.Form value was detected from the client” error), CSRF will not work (or will be very difficult to exploit) due to __EVENTVALIDATION and __VIEWSTATE parameters and so on.
I found such a semi-logical vulnerability recently that demonstrates how complex backend environments, where multiple teams of developers have to work together, can be very error prone to correct handling of “weird” situations. The same example also shows why an automated web application vulnerability scanner cannot replace a human penetration tester – this category of vulnerabilities will always be very difficult to find automatically, if not impossible.
The application I tested used very complex workflows (which are a pretty huge obstacle for automated vulnerability scanners). When the user wanted to change some of his security settings, the application used two factor authentication (2FA) and through a series of challenge/response screens the user had to confirm his actions. Looks good so far.
The last step in this complex workflow was a POST HTTP request, where the user submitted the calculated response back to the server for validation. If the submitted response was OK, the activity was approved, otherwise an error was given.
This is what the request looked like:
POST /Configuration.asmx/SecureAuthenticator HTTP/1.1
As you can see in the requests’ body, a JSON structure is being sent with the desired parameter. Besides testing for XSS and SQL Injection vulnerabilities in various parameters, the last two parameters look interesting.
So easy! What was the error here? After talking to the developers, the error happened when the front end sent a request to the authentication component. The front end correctly validated if the responseOtpCode and authenticator parameters exist, but didn’t check their contents (at the end of the day, it’s the authentication component’s job).
Now, the authentication component tried to match the value of the authenticator parameter to one of the supported mechanisms (apparently it supported more mechanisms and not only “Google”). When this failed, the authentication component returned back an error value: 255. However, the front end expected only 0 or 1 (successful or failed authentication) and somehow didn’t catch this properly.
At the end, we can see that this simple, half-logical vulnerability lead to a catastrophic scenario. Luckily, the fix was easy, but this once again showed that due to the vulnerability and the complex workflow, we must not rely only on automated vulnerability scanners.Web App Penetration Testing and Ethical Hacking - SANS Prague August 2019
Apr 23rd 2015
4 years ago