一 、注入
1.union注入
1、判断注入点
2、判断是闭合形式
3、判断查询列数
4、判断显示位
5、获取所有数据库名
6、获取数据库所有表名
7、获取字段名
8、获取字段中的数据
先判断闭合方式
尝试
?id=1’
?id=1”如果都报错,则为整形闭合。
如果单引号报错,双引号不报错。
尝试?id=1’–+
无报错则单引号闭合。
报错则单引号加括号。如果单引号不报错,双引号报错。
尝试?id=1"–+
无报错则双引号闭合。
报错则双引号加括号。多层括号同理
判断查询列数
order by 1 用第一列排序 order by 2...直到n报错,所以表里一共n - 1列
判断显示位
让原sql查询结果为空, 拼接union select 1,2,3.....看看是回显那一列,然后就可以在回显列的位置进行操作了
database()显示当前数据库名
后面很简单了,用information_schema即可
2.boolean 注入
Boolean注入是在没有显示位的情况下(就是不会返回Sql语句的查询结果)
但它也会代入数据库查询,只会返回True,False.这时我们就可以用逻辑操作符进行注入
所以可以通过遍历(套一下),先套库名长度,再套库名
可以使用burpsuit进行爆破
使用 substr(database(),1,1)='t'--+ ,截取database的每一个字符去请求,最终得到正确的库名,表明,字段名,就可以拿到基本数据了。
3.报错注入攻击
主要是使用updatexml()函数,获取数据库的各种信息
updatexml(xml_doument,XPath_string,new_value)
第一个参数:XML的内容
第二个参数:是需要update的位置XPATH路径
第三个参数:是更新后的内容
所以第一和第三个参数可以随便写,只需要利用第二个参数,他会校验你输入的内容是否符合XPATH格式
当第二个参数不符合XPath语法时,会直接把执行结果给出来,所以可以在入参前面添加一些字符构造成不符合的字符串比如 # ~ 0x7e 等等
然后就是基本的流程,拿数据库名,然后利用information_schema查询即可。
需要注意的一点是updatexml函数最多输出32个字节。这个时候md5解密是解不出来的,因为~的存在占据一位,密文只有31位,所以substring函数作用就出来了,截取一下,然后把目标数据拼接出来。
4.时间注入
利用sleep()或者benchmark()函数让sql执行时间变长,主要是通过if(expr1,expr2,expr3)函数
expr1值为True时,返回expe2,否则返回expr3,所以就可以通过下列方式来进入注入攻击
if(length(database()) > 1, sleep(5), 1),套出库名 表名 等等。。
5.堆叠查询注入
通过在注入点拼接第二条sql,注入内容和时间注入类似,例如
';select if(substr(user(), 1, 1) = 'r', sleep(3), 1)
6.二次注入攻击
在向数据库存数据时没有做校验,当输入恶意入参时,也是将恶意数据存到了数据库,然后通过查询数据关联到恶意数据实现注入攻击
例如 创建用户 username = test' 返回值为用户id
查询时传入用户id,内部实际是通过id找到username,如果username是直接拼接的话,可以实现注入攻击
7.宽字节注入
如果后台是通过转义' / " 来防止sql注入,如果数据库编码是GBK的话,可以通过拼接其他字符,让转义符转成其他字符来实现注入,比如转义 ’ 为%5c ,可以通过在前面加 %df,即入参为 1%df' 实际变成 1 %df%5c,而%df%5c其实会转义成别的合规字符,这样就可以进行注入攻击了,后面的步骤和union注入基本一致,只是要用嵌套查询来避免再使用 '
8.cookie注入
挺离谱的,真的会有人cookie里面传查询参数嘛,传了就能通过Burpsuite抓包修改cookie来实现注入
9.base64注入
入参是经过base64编码之后,所以把一些恶意的入参base64编码之后进行请求实现注入
10.XFF注入
请求头中有头部参数X-Forwarded-for,简称XFF头,代表客户端真实IP,PHP中是通过getenv()来实现的,即把对应的变量替换成 $IP,先判断client_ip ,然后x_forwarded_for,然后是remote_addr,都可以伪造。。。分别传入一些恶意的头比如 目标ip ' and 1 = 1 ip' and 1 = 2来判断是否存在注入点
二、绕过
即绕过一些过滤规则
1.大小写绕过
and =》 And aNd ....
2.双写绕过
and =》 anandd
3.编码绕过
把关键字做URL全编码 and or ,因为服务器会自动对URL进行一次编码,所以要对关键字进行两次URL全编码
4.内联注释绕过
and => /*!and*/
三、修复建议
1.过滤危险字符,针对sql注入经常使用到的关键字/函数,一出现就直接退出程序
2.使用预编译,POD预编译语句,不要将变量直接拼接到PDO语句,而是使用占位符来进行操作