Today, we will be taking a look at another reason to perform a web application penetration test: padding a business-case for upgrading end-of-life or legacy software. The company I worked for at the time needed to manage their telephone number inventory, while enabling legislative compliance. It was time to update the in-place solution as it was slow, outdated, and had some very specific requirements that made it very hard to work with, but no one wanted to foot the bill for the update.
While this story does involve a vendor, there will be no vendor-shaming. The software version under test was deemed end-of-life by the vendor, but the company was slow to update as the in-place solution was still technically working. You are likely to find vulnerabilities in any piece of software if you look long and hard enough. In this particular instance, a quick testing cycle found just the vulnerability needed: XSS on the login page.
The web application in question had a URL that looked like “http://example.com/Logon&PreviousPage=Logon”. The page was a basic-looking login page, but the login form where the user entered their credentials was a java applet. My first thought, already knowing that the stakeholders did not care about the fact that an out-of-date java version was required, was to look for XSS in that glowing PreviousPage=Logon parameter in the URL. Changing the value from Logon to another value caused that value to appear in the source code. Furthermore, any additional parameter added to the URL would be passed into the source code as well. For example, I added “&cats=meow” to the end of the URL, and this happened:
Essentially, any parameter added to the page would appear as a PARAM in the source code! Now, if the page had input sanitization on the URL parameters, this might not matter so much. This, however, was not the case. Verifying my suspicions, I tried various special characters after the &cats=meow, like ‘ and “, finding that whatever I put into the URL was placed into the source code verbatim. Wonderful! We have found our way in!
An alert box popping up on a login page is not very scary to the big-wigs in charge of the big cheques, and so I started creating an actual exploit that could show off the actual risks. First, I completely removed the original login form with this code:
var x=document.getElementsByTagName('applet'); x.parentNode.removeChild(x);
Thinking back on how this web application handles URL parameters and looking at the above URL, this code likely wont work on its own. The web app would likely get confused by the extra equal signs in the URL, maybe split these into their own HTML PARAM tags or just behave sporadically. There was an easy fix for this, and this little trick actually helps obscure XSS attacks from end-users during the social-engineering stage. All I had to do was URL encode the exploit and it was good to go. To take things further, and to further hide the attack from end-users, I completely URL encoded the exploit instead of just encoding the required characters.
…Bam! We now have the user’s credentials stored away for future (ab)use! For simplicity, I rigged the evil login page to display a warning message instead of storing the user’s password, but this gets the point across just fine. Of course, this version of the software was end-of-life and so no vendor patch would be coming, so the best course of action was to update to a newer version.