Very long time did not write on Habr and decided to share a small, occurred in his spare time, and a funny story. No, no, this article is not about what sqli is and how to defend against them, but about the atypical “promotion” of SQLi. It will be useful for beginner web pensters as training and, suddenly, for some administrators of Counter Strike server monitoring.
And if you spoil for experiencedThat article is about how to change the parameters in the sqlmap on the fly, for each request on the desired mechanism (you can flush to the bottom and save 5 minutes).
Let's go in order.
purpose
On the Internet there are many different monitoring sites for game servers (Counter Strike in this story), where administrators add their servers and they all line up in the ratings by vote (players vote, usually every 24 hours).
An example of such a script')
Somehow they dropped a link to me, just vote for the server, I naturally did it through burpsuite and noticed that when I vote, a hash is transmitted, which does not change from the IP address of the voter and depends only on the server ID. I started to google and found that the site used a popular script to monitor CS servers monengine (as in the screenshot above).
Parsing vulnerabilities
After downloading the source for the first link, I went to the file in vote.php and immediately began to look for the hash parameter (the one that is responsible for voting for the server) and found the following line:
if($hash != md5("m0n*********s4lt:P{]we$id@********%;")) exit(".");
Vote.php file, line 12Nothing interesting, a hash from the server ID + wired "salt". Considering the hash for my server, I realized that the “salt” for voting was not changed.
Running through the file again, I noticed the lines:
$id = mysql_real_escape_string($_POST['id']);
File vote.php, line 9and
$select_server = "SELECT * FROM ".DB_SERVERS." WHERE server_id = $id"; $select_server = dbquery($select_server); if(mysql_num_rows($select_server) == 1) {
The vote.php file, lines 23-25As you can see (line 9), a completely correct escaping of user data is used (from the viewpoint of the function itself, and not of the approach, for example, PDO) for the $ id parameter via the mysql_real_escape_string () function. But (!), An important point, the parameter itself is not framed in quotation marks, line 23 (for example, PDO does this automatically). Those. To modify an SQL query, no quotes are required and the mysql_real_escape_string () function goes through the forest (except for some situations, for example, using into outfile, where quotes are necessary and tricks via hex, etc. do not work).
We note that the result of the query is not displayed on the page, but is processed by the mysql_num_rows () function, i.e. the injection is blind (which is quite normal).
But the most interesting point is that in order to send the sql injection we need to ... sign it!
The task is reduced to the "promotion" of blind sql injection, where each request must be signed by a previously known algorithm. You can start writing your little exploit using the view construct
$id = "-1 union select 1,2,3,4,5,6,7,......... from mon_admin where admin_id =1 and admin_pass = 0x61 or sleep(1)-- -";
And signing each time their requests to the server
$hash = md5("m0n*********s4lt:P{]we$id@********%;");
Connect sqlmap
For finding and "promotion" sqli there is a popular tool - sqlmap. Therefore, instead of writing your exploit, you can connect it. But in this case, he would not have found anything, since he simply would not have reached the moment when the vote.php script fulfills the request (due to an incorrect signature). Those. our task is to modify at each request one of the POST parameters (hash) according to the desired algorithm. It's easy to do this via the --eval parameter, where you can write python code, where the variable specified inside eval will be changed before being sent.
Total:
python sqlmap.py -u "http://vuln.com/vote.php" --data="action=voteup&id=1&hash=2" // POST --eval="import hashlib;hash=hashlib.md5('m0n*********s4lt:P{]we$id@********%;').hexdigest()" // hash -p id // --dbms=MySQL --union-cols=XXX --level=XXX --dump -T mon_admin // --headers="X-Requested-With: XMLHttpRequest" // , ajax
The result - sqli will be promoted. From funny - you can’t do anything if the salt and / or the signature algorithm is unknown to the attacker.
PS I tried to find the creator of the script, but did not find it. As I understand it, the development has long been closed and everything just put this script as it is, changing the design. Therefore, if you use this script, you can fix this vulnerability.
In the file vote.php change
$select_server = "SELECT * FROM ".DB_SERVERS." WHERE server_id = $id";
on
$select_server = "SELECT * FROM ".DB_SERVERS." WHERE server_id = '$id'";
But it will not save even from a pack of potential bugs that are in the same script.