Pwning the portal: from database dump to session hijacking
I find that doing bug hunting and responsible disclosure is a nice practical way to “learn by doing” for beginners and for practicing your recon and exploit skills while helping companies stay secure. This is a responsible disclosure write-up about a series of vulnerabilities that lead to information disclosure, database dump, and account takeover, among others.
Due to the confidentiality of the findings and associated targets, we will not mention the target details and will redact any identifiable information. The company in question had authorized public bug hunting against its systems. Any steps mentioned herein are for educational purposes and should not be used to attack systems you have not been given permission to perform such attacks on. Bitcrack Cyber Security has already responsibly disclosed the vulnerabilities to the target company through their responsible disclosure policy.
Gathering as many subdomains of the target as possible is an important step to broaden your attack surface. The more surface one has to look for bugs, the more probable it is to find some.
The bug bounty community has focused a lot on reconnaissance over the last years with tools and services such as Projectdiscovery.io | Chaos, Security Trails. For this phase, I decided to not spend too much time and use tools and services that are already part of my automation, i.e.
- Query certificates based on the target organization’s name on crt.sh
- Do a reverse WHOIS lookup using reversewhois.io
- Use Project Discovery’s subfinder
After gathering the subdomains and filtering the ones responsive to the HTTP protocol, the next step was to fuzz all of the hosts for “quick wins” using a custom wordlist of known vulnerability identifiers, and leaks and exposures developers might have misconfigured. One host caught my eye when I discovered that an SVN repository was publicly available:
A closer look…
The host was a portal for the target company employees. It has a login page with additional functionalities such as password change and a “forgot password” functionality. One can also register for the portal but, since it’s a corporate portal, one has to “request” for an account by providing company data.
An SVN repository has no different purpose than a Git repository. Both SVN and Git are version control systems, with the difference that SVN is a centralized solution, unlike the distributed system Git. It can contain source code, sensitive information, or anything the developers have used for building the web application, without constraining any public access.
Extracting an SVN repository can be easily done with the help of tools such as svn-extractor. By downloading and exploring the repository I came to the conclusion that it contained the source code for the portal, both for authenticated and unauthenticated parts of the application. Before anything, I used
grep to catch any sensitive words such as
apiKey etc. Here I had the first “win”, with some database credentials
Although I was in the advantageous position of having the source code of the application, I decided to first test my skills of approaching a target with zero knowledge of the source code.
The blackbox testing approach resulted in multiple issues:
- Two endpoints vulnerable to blind SQLi. One GET request and one POST request.
- Two reflected XSS’, all in POST requests.
Showing SQLi impact
The blind SQLi on the GET request endpoint could be exploited with a time-based blind SQLi payload. The end result of the payload was:
With the help of the great and well-known tool sqlmap, I was able to extract database information such as database names, users and their privileges, table and column names, their entries, as well as a sample of the users’ entries with the following columns:
Note that the last column contains plaintext passwords of users. It is important to note that this is no legacy application and it is still used by employees, as observed by the recent date entries of the column
Showing XSS’ impact
Unfortunately, both XSS are POST-based XSS’, meaning that they can only be triggered by a POST method, so we’d have to trick the victim into making that request.
This issue can be bypassed by combining the XSS with a CSRF issue, as the application lack CSRF protection. That way, by sending a link from a malicious host we control, we can force the victim into making a POST request with our malicious payload:
<html> <body> <script>history.pushState('', '', '/')</script> <form action="http://vulnerable-site/portal/index.php" method="POST"> <input type="hidden" name="loginParameter" value=""><script>alert(1)</script>"" /> <input type="hidden" name="languageParameter" value="en" /> <input type="hidden" name="passwordParameter" value="password" /> <input type="hidden" name="redirectParameter" value="" /> <input type="hidden" name="actionParameter" value="checkLogin" /> <input type="submit" value="Submit request" /> </form> <script> document.forms.submit(); </script> </body> </html>
Code reviewing and uncovering more issues
After spending some time on the blackbox approach, I decided to take a look at the source code. I had the feeling that, since there were such issues on the unauthenticated side of the application, there should be more of them on the authenticated side as well.
After analyzing some code, I found the pattern which the developers used to make SQL statements and reflect user input in the source code. A quick way to find possible SQLi and XSS issues is, again, by using
grep. The queries
grep -iorE "^.*SELECT.*WHERE.*" ./*
grep -nrE ".* echo \( isset \( .+_(POST|GET)" ./*
returned strings in the code that match the regex pattern.
grep -iorE "^.*SELECT.*WHERE.*" ./*:
We see in multiple lines that the user input is being passed into the query without any filtering, which can later be confirmed by analyzing which variable is being assigned based on user input in the code.
grep -nrE ".* echo \( isset \( .+_(POST|GET)" ./*:
Here we also see that the values of the HTTP parameters are being reflected un-sanitized, leading to XSS’.
Through that way, I was able to uncover authenticated SQLi’s as well as authenticated POST-/GET-based reflected XSS’, which could make session hijacking possible, since the victim can have a valid session.
Additionally, through code reviewing, it was also discovered that through the “Forgot Password” functionality, a user would get the username and password received in an email in plaintext, which violates best practices as this can also indicate that the password is being stored in plaintext in the database instead of with a secure hashing algorithm.