Bootstrap

SQL注入分类、防御

一、SQL注入分类

按数据类型分

数字类型

后台语句可能为:

$id=$_POST['id']
select user,password from users where id=$id

字符类型

$id=$_POST['id']
后台语句可能为:select user,password from users where id='$id'

总结:

  • 数字类型直接将后台接收到用户输入的内容带入到数据库中执行;而字符型将接收到的内容添加到引号内然后进行执行。
  • 字符型注入需要考虑语句的闭合问题,而数字类型则不存在

MySQL手工测试字符型闭合语句

select user,password from users where id='$id'
select user,password from users where id="$id"
select user,password from users where id=($id)
select user,password from users where id=('$id') 括号可以无限叠加
select user,password from users where id=("$id")  括号可以无限叠加
select user,password from users where id=(($id))  括号可以无限叠加

可参考sqli-labs靶机进行测试学习

按注入位置分

GET方式注入
注入参数以GET方式进行提交
POST方式注入
注入参数以POST方式进行提交
基于cookie的注入
后台接收cookie内的参数,在http的cookie字段中存在注入漏洞
基于http头部的注入
后台会接收referer或user-agent字段中的参数,http头部中的referer、user-agent字段中存在注入漏洞

盲注

基于布尔的盲注
特点:网站页面在输入条件为true和false的情况下会显示不同,但页面中没有输出。此时需要在SQL语句之后添加条件判断。
猜解思路:

  • 猜解数据库:先构造条件判断当前数据库的名字长度,然后逐字猜解数据库名。
  • 猜解数据表:先构造条件判断数据表的数量,然后逐个进行猜解,先猜解表名长度然后逐字猜解表名。
  • 猜解数据列:指定数据库中的指定表进行猜解字段,首先猜解字段的数目,然后逐个猜解字段
  • 猜解内容:指定数据列,先查询数据的条数,然后逐条猜解其中的内容

基于时间的盲注
特点:网站页面在输入条件为真和为假返回的页面相同,但通过延时函数构造语句,可通过页面响应时间的不同判断是否存在注入
猜解思路:
类似基于布尔的盲注,只是将条件为真转换为延时响应
常用函数

  • if(condition,A,B):若condition返回真则执行A,假则执行B
  • substr(str,A,B):字符串截取函数,截取str字符串从A位置开始,截取B个字符
  • left(str,A):类似字符串截取函数,返回str字符串从左往右数的A个字符
  • count(A):计算A的数目,常用与查询数据表、数据列、数据内容的条数
  • len(A):计算A的长度,常用于返回数据库名、数据表名、数据列名的长度
  • ascii(A):返回A的ascii码,当逐字猜解限制单引号的输入时,可以通过查询ascii码来绕过

基于UNION的注入

首先通过order by 进行判断查询参数的数目,然后构造union查询,查看回显。有时需要将前面参数名修改为假的参数。如id=-10’ union select 1,2,查找页面中1和2的位置,在页面中显示的数字的地方构造查询的内容。
若页面无回显但报错可以尝试报错注入

基于报错的注入

常用函数:

  1. updatexml(1,concat('~',SQL语句,'~'),1)
  2. extractvalue(1,concat('~',(SQL语句)))

宽字节注入

宽字节注入的原理即为数据库的编码与后台程序的编码不一致,数据库中一个字符占两个字节,而后台程序为一个字符占一个字节,当后台程序对输入的单引号的字符进行转义时,通过在这些转义的字符前输入%bf然后将%bf’带入后台程序时会转义为%bf’,此时带入数据库中,数据库将%bf\看作是一个中文字符从而使用单引号将SQL语句进行闭合。

基于base64加解密注入

后台程序在接收用户输入的参数后先进行base64解码然后带入到SQL语句中执行。所以这种类型的注入首先需要将payload进行base64加密

搜索型注入

当搜索关键字时,后台SQL语句可能为:select username from users where id='%$id%',此时构造闭合语句时需要考虑%的闭合

二、防御

代码层面

  1. 对用户输入的内容进行转义(PHP中addslashes()、mysql_real_escape()函数)。
  2. 限制关键字的输入(PHP中preg_replace()函数正则替换关键字),限制输入的长度 。
  3. 使用SQL语句预处理,对SQL语句首先进行预编译,然后进行参数绑定,最后传入参数。

网络层面

部署防火墙

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;