Not too long ago, I was tasked with performing an Application Security Assessment while on-site at a client location. I had worked with this client before, and was eager to see how they had matured their applications over the past couple years. Originally, I had performed an assessment on an older version of the application and I was curious to see the direction they went with the new version of the application.
As I began my normal testing routine, I quickly realized this particular application was built on top of the Google Web Toolkit (GWT) and most of the responses were JSON formatted. Seeing this, I knew this would be a tough nut to crack as both GWT and JSON were built with security in mind.
At the start of this assessment, I decided to start with a quick walkthrough of the application. While my intercepting proxy tool spidered each click, I set up and configured a web vulnerability scanner and let it run against the application. Aside from the typical SSL/TLS configuration issues, the automated scanner didn’t find much in the way of exploitable vulnerabilities that would result in access to the host or a user’s session. This is where the real application penetration testing began.
Let’s break this down a bit and explain what’s happening in more detail.
The input field in question was used as a way for the end user to enter a reference ID associated with their search terms for a particular topic. This value was then stored with the results on the results page for quick reference. The application was responsible for batch processing multiple search queries at once, and this input made it easy to track one particular search batch among the many running simultaneously within the application.
Here’s a breakdown of how I discovered the vulnerability:
- I set my intercepting proxy to catch all request/response sequences between my browser and the application.
- I entered the word ALERT (just like that, in all caps) so I could track where in the request/response sequences that particular input came into play.
- From testing, I knew the application had client-side validation mechanisms in play, so I would have to manipulate the raw request before manually sending it through to the application.
- Testing revealed the third request had my entered word “ALERT”.
- I forwarded the remaining requests/responses and waited for the results page.
- When an alert box popped up revealing the user session token, I knew the attack worked.
- I used:
When executed, the user’s browser would continually try to load a fictitious image by making an HTTP request to the attacker’s web server (at 18.104.22.168) – in this case my attacking machine. At the end of the request would be the user’s session token value (which will replace the ‘document.cookie’ in the script above once the script executes). This session token value could then be used to access the application as the user without needing the user’s authentication credentials. The cool thing about this attack is that the refresh on the page would execute this script every so often, meaning whoever visited the page would wind up sending the attacker their session token. The attacker would gain multiple authenticated session tokens and be able to use the application as any of those users.
A major aspect to highlight in this blog is the fact it took dedicated, manual testing to uncover this vulnerability that was missed by automated tools. GWT and JSON applications can be a nightmare to assess when configured properly and implemented well. There is immense value in dedicated, manual-testing sessions when performing an application penetration assessment.
While automated testing lets a tester check a lot of things in a rapid manner, it simply will not test everything. Manual testing, and being good at manual testing, is what separates “penetration testers” from “good penetration testers”.