During a recent penetration test BURP Suite identified some blind SQL Injection vulnerabilities in a target website. Pointing SQLMAP at the website showed us no love and simply said it was unable to exploit the website. I had mentioned the SQLi issues to the customer and he said that previous penetration testers said they were unexploitable. We decided to take a closer look anyway. The URLs for the website looked rather odd. I can't talk specifically about the website in question, but the URIs looked something like this:
"http://www.example.tgt/website.php?QnnyBZ4_ZB6qvm=xxxTcTc&k3mK4_ZQ6v=6V9A&UQK4_ZQ6v=qVllgrr"
You'll notice that the field names (underlined in RED) have very strange names. At first I thought that these were just weird field names. Maybe the developer has some codenames for fields that I just didn't understand. But then I noticed that the values (underlined in BLUE) were also very odd. None of the information on the URL made any sense to me. I grabbed a coworker and we spent some time trying to figure out what kind of weird encoding was being used. The web application had some useful functionality that make the translation pretty easy to figure out. If we put "AAAAAAAAA" into the ACCOUNT NUMBER field in the websites search page we saw that it redirected us to a web page with a URI containing "0nnyBZ4_ZB6qvm=000000000". When we searched for an ACCOUNT NUMBER of "BBBBBBBBB" it took us to web page with a URI containing "0nnyBZ4_ZB6qvm-qqqqqqqqq". There was obviously some type of character substitution cipher being used on the URL. The maximum size for an account number was 9 characters. But with a few queries I could figure out the entire character set mapping. I searched for an ACCOUNT NUMBER of "ABCDEFGHI" and found a URI containing "0nnyBZ4_ZB6qvm=0qnPvka03". I searched for "JKLMNOPQR" and found a URI containing "0nnyBZ4_ZB6qvm=qMU6Zybjm". I repeated this process for every upper, lower and numeric character and soon I had the following mapping of characters.
Normal Letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
Encrypted Letters = 'QqnPvka03wMU6ZybjmK4BRSEWdVishgClpI1AouFNOJ9zrtL2Yef7Tc8GxDHX5'
Python makes translating between two sets of characters easy. Using Python 3 we can do the following:
This translated the word "HELLO" into "0vUUy" using the character mapping specified. The arguments for "maketrans" are the "FROM STRING" followed by the "TO STRING". Going in the other direction is simply a matter of reversing the parameters passed to str.maketrans() and passing (encrypted_letter, normal_letters)
In Python2 you have to import the string module because the "maketrans" function is stored there. But otherwise the syntax is the same.
Now I can decode the URLs! So we tried in on the URL we saw earlier.
Awesome. Now that is something I can understand. Now that we can freely encode and decode our attacks we had a bit more success with manual exploitation. But I'm lazy! I want SQLMAP to automate my attacks for me! If I don't tell SQLMAP how to encode its injections it will not work against the website. SQLMAP tamper scripts are designed to do exactly that. SQLMAP is distributed with a set of "TAMPER" scripts to perform tasks like add a NULL byte to the end of injections or randomize the case of the letters in your query. Creating a custom tamper script to do our character transposition is pretty simple. SQLMAP is using Python2 so we will have to import the string module. But Looking at one of the other tamper scripts and using it as an example we quickly wrote the following:
We saved this new file a "custom_caesar.py" and placed it inside SQLMAP's "tamper" directory. Then we pass the name of our script to the -tamper argument.
python sqlmap.py -u "https://www.example.tgt/webapp.php? QnnyBZ4_ZB6qvm=xxxTcTc&k3mK4_ZQ6v=6V9A&UQK4_ZQ6v=qVllgrr" -tamper=custom_caesar.py -dump
Then sit back and watch SQLMAP's barrage of winning. A few lines of custom Python code took this vulnerability from "an unexploitable false positive" to a significant vulnerability that requires immediate attention. After using the tamper script we are able to access everything in the database with SQLMAP saving us hours of manual exploitation and encoding. And all it took was plugging 3 lines of custom Python code into an existing tamper script template.
Python is awesome and having the ability to use it and customize tools to meet your demands is incredibly powerful. Come check out SEC573: Automating Information Security with Python.
The SQLMAP Tamper Script
https://gist.github.com/MarkBaggett/49aca627205aebaa2be1811511dbc422#file-custom_caesar-py