Click the star toreceive the latest tweets instantly
This article is selected from “Web Security Offense and Defense Penetration Testing Practical Guide (2nd Edition)”
Click on the picture to buy the book at 50% off
Boolean injection attack
The test address of Boolean injection attack is in Chapter 2 of this book.
When accessing this URL, the page returns yes, as shown in Figure 4-25.
Figure 4-25
Add a single quote after the URL to access it again, and then you will find that the return result changes from yes to no, as shown in Figure 4-26.
Figure 4-26
Access id=1′ and 1=1#, id=1′ and 1=2#, and find that the returned results are yes and no respectively. If you change the value of ID, you will find that the returned value is still yes or no. It can be judged from this that the page only returns yes or no, but does not return the data in the database, so Union injection cannot be used here. You can try to use Boolean injection here. Boolean injection refers to constructing a SQL judgment statement, and by looking at the return results of the page to infer which SQL judgment conditions are true, so as to obtain the data in the database. We first determine the length of the database name. The statement is as follows:
1' and length(database())>=1-- +
There are single quotes, so comment characters are needed to comment. The position of 1 can be any number, such as 1′ and length (database())>=1– +, 1′ and length (database())>=4– + or 1′ and length( database())>=5– +, construct such a statement, and then observe the return results of the page, as shown in Figure 4-27~Figure 4-29.
Figure 4-27
Figure 4-28
Figure 4-29
It can be found that when the value is 4, the returned result is yes; and when the value is 5, the returned result is no. The meaning of the entire statement is that if the length of the database name is greater than or equal to 4, the result is yes; if the length of the database name is greater than or equal to 5, the result is no, so it is judged that the length of the database name is 4.
Next, use character-by-character judgment to obtain the database name. The database name generally ranges from a to z, 0 to 9, and may have some special characters. The letters here are not case-sensitive. The SQL statement that is judged character by character is as follows:
1' and substr(database(),1,1)='t'-- +
Substr means interception, which means intercepting the value of database(), starting from the first character, and only returning one at a time.
The usage of substr is different from the usage of limit, so you need to pay attention. Limit sorts from 0, but here it sorts from 1. You can use Burp Suite’s blasting function to blast the ‘t’ value, as shown in Figure 4-30.
Figure 4-30
It is found that when the value is t, the page returns yes, and other values return no. Therefore, it is judged that the first digit of the database name is t, as shown in Figure 4-31.
Figure 4-31
You can also use ASCII code characters to query. The ASCII code of t is 116. In MySQL, the ASCII conversion function is ord, and the SQL statement that is judged character by character is as follows:
1' and ord(substr(database(),1,1))=116-- +
As shown in Figure 4-32, the returned result is yes.
Figure 4-32
We already know from Union injection that the database name is ‘test’, so to determine whether the second letter is e, you can use the following statement:
1' and substr(database(),2,1)='e'-- +
As shown in Figure 4-33, the returned result is yes.
Figure 4-33
The statement to query the table name and field name should also be pasted in the database() position. From the Union injection, we already know that the first table name of the database ‘test’ is users, and the first letter should be u. The judgment statement is as follows :
1'and substr((select table_name from information_schema.tables where table_schema='test' limit 0,1),1,1)='u'-- +
The result is shown in Figure 4-34. The conclusion is correct. By analogy, all table names and field names can be queried.
Figure 4-34
Boolean injection code analysis
On the Boolean injection page, the program first obtains the GET parameter ID and uses preg_match to determine whether there are dangerous characters such as union/sleep/benchmark. Then splice the parameter ID into the SQL statement and query it in the database. If there is a result, yes is returned, otherwise no is returned. When accessing the page, the code returns yes or no based on the database query results without returning any data in the database, so only yes or no will be displayed on the page. The code is as follows:
<?php error_reporting(0); $con=mysqli_connect("localhost","root","123456","test"); if (mysqli_connect_errno()) { echo "Connection failed: " . mysqli_connect_error(); } $id = $_GET['id']; if (preg_match("/union|sleep|benchmark/i", $id)) { exit("no"); } $result = mysqli_query($con,"select * from users where `id`='".$id."'"); $row = mysqli_fetch_array($result); if ($row) { exit("yes"); }else{ exit("no"); } ?>
When accessing id=1′ or 1=1#, the statement executed by the database is select * from users where `id`=’1′ or 1=1#. Since or 1=1 is a forever true condition, so At this point the page will definitely return yes. When accessing id=1′ and 1=2#, the statement executed by the database is select * from users where `id`= ‘1’ and 1=2#, because and ‘1’=’2 ‘ is a permanent false condition, so the page will definitely return no at this time.
MS08067 security laboratory video number is online
Welcome all students to follow and forward~
– Live training courses under the laboratory –
Join MS08067 to study together with 20,000+ classmates