> 文章列表 > MySQL注入秘籍【下篇】

MySQL注入秘籍【下篇】

MySQL注入秘籍【下篇】

MySQL注入秘籍【下篇】

  • 1.盲注
    • 布尔盲注
    • 时间盲注
  • 2.order by注入
  • 3.limit注入
  • 4.二次注入
  • 5.宽字节注入
  • 6.Update注入
  • 7.堆叠注入
  • 8.HTTP头部注入

1.盲注

布尔盲注

通过页面对永真条件和永假条件返回的内容是否存在差异,进行判断是否可以进行布尔盲注

使用永真条件'1'='1'

1' and '1'='1

MySQL注入秘籍【下篇】

使用永假条件'1'='2'

1' and '1'='2

MySQL注入秘籍【下篇】

可以看出永真条件和永假条件分别代入SQL语句执行后,永为假的页面缺少了部分信息,利用这种差异性,我们就可以构造payload获取到数据库中的数据

布尔盲注主要依赖于返回结果的差异判断,所以我们在注入过程中也只能一位一位的进行判断,在判断长度的时候或者切割字符串的时候,就需要用到一些内置的函数

MySQL注入秘籍【下篇】

盲注点确认后,使用SQLMap等自动化工具扫描🩰

时间盲注

依赖于响应时间上的差异来判断。举个简单的例子:如果1=1为真,就休眠5秒;这样页面返回时间一定大于5秒

通常可利用的产生时间延迟的函数有:sleep()、benchmark()

除了上述布尔盲注的常用函数外,还需要一些能够进行判断和造成时间延时的函数

MySQL注入秘籍【下篇】


2.order by注入

order by注入通常出现在排序中,前端结果展示的表格,某一列需要进行升序或者降序排列,或者做排名比较的时候常常会用到order by排序,order by在select语句中,紧跟在where [where condition]后,且order by注入无法使用预编译来防御,由于order by后面需要紧跟column_name,而预编译是参数化字符串,而order by后面紧跟字符串就会提示语法错误,因此通常防御order by注入需要使用白名单的方式

判定存在的方法:

可以通过order by列名,根据排序返回的情况来判断是否存在注入

order by rand()
order by rand(1=1)
order by rand(1=2)

MySQL注入秘籍【下篇】
MySQL注入秘籍【下篇】

利用方式:

order by通常情况下后面可直接接SQL语句,所以利用方式很多

1、基于报错

order by exp(~(select * from (select version())x))
order by (select exp(~(select * from (select version())x)))

2、基于盲注

order by if(1=1,1,(select 1 from information_schema.tables)) # 正常
order by if(1=2,1,(select 1 from information_schema.tables)) # 异常
order by if(mid(database(),1,1)='s',1,(select 1 from information_schema.tables)) # 正常
order by if(mid(database(),1,1)='a',1,(select 1 from information_schema.tables)) # 异常

如果直接使用sleep函数,如果表里的数据有n条,sleep(2),会使查询时间为2*n,会对服务器造成拒绝服务攻击,一般不建议在order by 处使用时间盲注来判断以及注入数据👑


3.limit注入

order by注入和limit注入有啥区别?

其实两者的区别很简单:order by注入后可以直接接SQL语句,而limit后面不行,需要再跟PROCEDURE ANALYSE()才可

其实也可以分为两种情况,一种是limit前有order by,一种是没有order by

无order by

利用起来相对比较简单,可以直接在后面接union,也可以用后面那种limit专属的方式

select * from aaa limit 1,1;-- 使用union注入
select * from aaa limit 1,1 union select version();-- 报错注入,延时类似
select * from aaa limit 1,1 procedure analyse (extractvalue(rand(),concat(0x3a,version())),1);

有order by

这个情况下就不能用union注入了,不然会抛出异常,所以用limit的专属注入方式,适用于5.0.0<MySQL<5.6.6版本


4.二次注入

二次注入就是攻击者构造的恶意payload首先会被服务器存储在数据库中,在之后取出数据库在进行SQL语句拼接时产生的SQL注入问题

例如,我们可以控制如下SQL语句中的username

UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass'

那我们只需要将username设置为一些比较明显效果的函数,比如' and sleep(5)# 就可以直观的看到较长的响应时间

实战中如果不是特别有把握尽量不要使用update注入,毕竟会对目标的数据进行修改❌

我们可以尝试注释掉后面对原密码的验证的语句达到修改其他用户密码的目的

注册用户test'#并登陆,修改密码,这里可构成SQL语句如下

UPDATE users SET PASSWORD='123123' where username='test'#' and password='111111'

执行后,test用户的密码被成功修改:

MySQL注入秘籍【下篇】


5.宽字节注入

了解宽字节注入前,先了解一个PHP的防御函数magic_quotes_gpc(魔术引号开关)

magic_quotes_gpc函数在php中的作用是判断解析用户提交的数据,如果magic_quotes_gpc=On,PHP解析器就会自动为post、get、cookie过来的数据增加转义字符\\,以确保这些数据不会引起程序,特别是数据库语句因为特殊字符引起的污染而出现致命的错误

常见的宽字节:GB2312、GBK、GB18030、BIG5、Shift_JIS

因为使用了GBK编码会认为两个字符是一个汉字,所以可以使用一些字符和转义过后多出来的\\组合两个字符,数据库就会尝试将他们转换为一个汉字,也就使得数据库不识别字符,对单引号、双引号的转义失败,从而达到闭合语句的目的

形成过程: 当PHP连接MYSQL时,当设置character_set_client = gbk时会导致GBK编码转换的问题,当注入的参数里带有%df(%bf)时,在魔术引号开关或者addslashes()函数的作用下,会将%df%27转换为%df%5c%27,此时%df%5c在会解析成一个汉字,从而“吃掉”反斜杠,单引号因此逃逸出来闭合语句

不一定非得%df,%99、%aa、%fe等都可以🧢

根本原因: character_set_client(客户端字符集)和 character_set_connection(连接层的字符集)不同,或转换函数如iconv、mb_convert_encoding使用不当

注入流程分析:

正常情况下,我们输入id=1'#,经过addslashes转义后,会变成1\\'#,构成的SQL语义大概如下:

select * from users where id = '1\\'#';

看上去没问题,但是我们注意到它有一行设置了编码:

mysql_query("SET NAMES gbk");

根据刚才的双字节知识,我们如果输入id=1%df'#,那么转义后,就变成了1%df\\'#,而%df\\会被尝试识别成一个汉字,因此'就被释放出来绕过了转义限制,构成的SQL语义大概如下:

select * from users where id = '1�'#';

尝试判定一下,是不是对的,输入 id=1%df' or 1 -- -,可见成功出现了结果

MySQL注入秘籍【下篇】


6.Update注入

和其他注入一样,无非就是闭合语句,然后注入自己的恶意语句,达到自己想要的效果,比如修改密码、查询数据等等

update注入一般给敏感数据如database()的值设置到可见变量中,然后直接查看

update注入点如何重复给字段赋值?

-- 正常update,sqli处为注入点
update user set username="sqli" where age=111;-- 重复给username赋值
update user set username="sqli",username=user() where age=111;

MySQL注入秘籍【下篇】


7.堆叠注入

堆叠注入与受限于select语句的其他注入不同,堆叠注入可用于执行任意SQL语句。

简单的说,由于分号;为MYSQL语句的结束符。若在支持多语句执行的情况下,可利用此方法执行其他恶意语句,如RENAME、DROP等。

例如:

select * from users;show databases; 

虽然这个注入姿势很牛逼,但实际遇到很少,其可能受到API或者数据库引擎,又或者权限的限制只有当调用数据库函数支持执行多条sql语句时才能够使用,利用mysqli_multi_query()函数就支持多条sql语句同时执行

但实际情况中,如PHP为了防止sql注入机制,往往使用调用数据库的函数是mysqli_ query()函数,其只能执行一条语句,分号后面的内容将不会被执行,所以可以说堆叠注入的使用条件十分有限,一旦能够被使用,将可能对网站造成十分大的威胁


8.HTTP头部注入

注入的点不在咱们经常关注的参数中,而在http头中

  • HTTP头注入是指从HTTP头中获取数据,而未对获取到的数据进行过滤就直接代入SQL语句中,从而产生注入
  • HTTP头注入常常发生在程序采集用户信息的模块中

所有和数据库存在交互的地方,都可能存在SQL注入🪖

因为http头注入常出现在收集用户信息的点,所以常见的注入点如下:

MySQL注入秘籍【下篇】

版权声明:本文教程基于d4m1ts知识库