During a recent pentest assessment my team and I were given the mission to look for vulnerabilities at web applications of a client domain. Although very simple and automated, we used a few tricks that made life easier and got us a shell in less than an hour.
The nice thing is exactly that we did not use any mind blowing tools, 0-days, sophisticated social engineering or whatever. Using only an indirect approach and putting together both basic theory and some practical knowledge of the employed tools, we could own a critical server and exfiltrate sensitive data.
Subdomain enumeration
Our client main web application seemed to be strongly hardened so we decided for an indirect approach. We listed all subdomains we could using Google Dorks
, amass
, sublist3r
and dnsrecon
. This dork was very useful:
site:domain.com -inurl:www
amass
, sublist3r
and dnsrecon
gave us lots of interesting results. After filtering the repeated values and checking which were still online (many were not), we finished our targets list.
The low hanging fruit
Although most of the client’s web applications were reasonably safe, one of them called our attention. It was clearly a legacy web site of a forgotten event hosted by the company years ago. Nevertheless, it was still there, just waiting for being compromised.
Since it was an old application, we were not surprised to discover it was build with plain PHP and no frameworks. Our first action was to navigate through the website, much like a regular user would do, while understanding what functionalities that site provided. I cannot stress enough how important interacting with the target site has been proving to be in our assessments. It gives you a whole different perspective and helps you mounting your attack tree.
After a while we decided that a SQL Injection was a real possibility.
SQLmap FTW
Yes, I know, I know. Automated active tools are noisy, unreliable and made for infosec loosers. While all of this might be true, reinventing the wheel is never a good idea. Especially in the real world. With deadlines. And bosses. And children. You know.
Do you GET it?
We gave our Google-Fu another try with this dork:
site:sub.domain.com ext:php
It brought us a few nice ?id=xxxx
results. All was going well and we had real reasons to think this would be just that easy. However, it seemed that id
was not a vulnerable parameter at all. A little frustrating, indeed.
Since we had spent some time playing around with the application, we knew there was an interesting search form in one page passing values through POST
. We filled the form with fake values, intercepted the request with Burp Suite and used the parameters within SQLmap:
sqlmap -u http://sub.domain.com/querydb.php --data="express=a&submit=Find"
We were immediately cut off.
Our first thought was that there was some kind of WAF protecting the system. But was it?
Some more flags
The cool thing about cool tools like SQLmap
is that they help a lot but only if you help them first. So we did our homework and found out that the database system being used was MySQL. We found it after locating a database connection error message in another page (remember this was a legacy and forgotten system).
We also tweaked the tool a little hoping to bypass the WAF.
sqlmap -u http://sub.domain.com/querydb.php --data="express=a&submit=Find" --random-agent --dbms=mysql --dbs
But again, no luck. We also tried to use the --identify-waf
option, but the result was Generic (Unknown)
. Not very helpful.
Anyway, I was convinced this application was SQLinj vuln so I tried a little harder.
sqlmap -u http://sub.domain.com/querydb.php --data="express=a&submit=Find" --random-agent --dbms=mysql --dbs --risk 3 --level 5
Still nothing. The WAF was definetly the problem.
Tampering
The solution to this problem was to use the --tamper
option. We basically encoded our payload so the WAF would not detect us. I started with a simple between
encoder and the result was better. A few tests were successfully completed, although most were not. So I added a few more tamper scripts, although I was afraid my requests were getting way too large.
Surprisingly enough, it worked flawlessly.
sqlmap -u http://sub.domain.com/querydb.php --data="express=a&submit=Find" --random-agent --dbms=mysql --dbs --risk 3 --level 5 --tamper="between,bluecoat,charencode"
I just had to adjust the timing, so the final command became:
sqlmap -u http://sub.domain.com/querydb.php --data="express=a&submit=Find" --random-agent --dbms=mysql --dbs --risk 3 --level 5 --tamper="between,bluecoat,charencode" --threads 7 --time-sec=2
Bingo! We could dump a users
table and crack the admin hash.
Getting the shell
From this point on it was actually easy, nothing new. Once we got access to the admin panel, we saw there was a place to upload files. So we did the good and old shell.php.png
, which worked like a charm. Yes, in 2018.
Fortunately (for us, of course), this broken application was hosted in the very same server as another critical application, which had no blatant vulnerabilities. We managed to exfiltrate some confidential documents within the scope of the test and declare game over.
Final thoughts
It is extremely important to have all your assets under control. If there is a useless application online, take it down. No matter how hard it is to beat your main server/application, your chain will be just as strong as its weakest link. Also, do not underestimate the existence bizarre legacy stuff, even in security aware corporations. As a pentester it is your obligation to always look first for the lower hanging fruit.
Automated tools can help a lot, but only if you know how to use them properly. That means knowing what part of the process is the tool’s responsibility and what is yours. Never let any tool rule the game, you must always have knowledge and control of each and every action of anything under your responsibility.
Finally, do try harder. It generally pays off :)