1、输入1' 发现数据库报错,原因是我们的输入直接被代入到数据库查询语句里面。

2、有没有办法可以不让他报错呢?可以尝试一下构造正确的数据库语法,使之不报错。比如输入 1 and 1=1 试试

select * from wuser where id = 1 and 1=1; 1=1永远成立,id=1也是同样存在,所以这个查询不会报错,会输出正确信息。

然后尝试 id = 1 and 1=2 ,结果不显示,说明我们构造的语句成功在数据库中执行了。

3、成功执行后,仅仅是跟正常查询显示相同的内容,那有没有办法可以显示其他内容呢?我们在mysql中使用union select来实现。

union select的作用是拼接在正确数据库查询语句后面进行联合查询,union select查询的字段数一定跟主查询的字段数一致。

比如 select id ,user ,pass from wuser 这是主查询,查询的字段是3个,所以后面的union select的查询字段一定也是3个。

select * from wuser where id = 1 union select 1,2,3;

4、union select查询成功后显示的还是没有变,其原因是主查询也成功返回了结果,而页面上只显示了返回结果的第一行,因此要想看到union select的结果,需要令第一行也就是主查询的结果为空。常用的办法就是把主查询的1改成-1.

5、mysql中有几个默认自带的库和查询函数。我们就可以使用这些来查出数据库中所有的内容。

自带的函数有:database(),version(),user()

自带的库有:information_schema,此库只有mysql5.0以后的版本才有。

在之前union select显示的数字位置,将数字替换成查询

 

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

union 查询的一般步骤:

1、通过and 1=1,and 1=2的输入,来判断是否存在注入点。如果结果不一致,说明我们输入的语句被数据库执行了。

2、通过观察或报错信息来判定输入点的数据类型,数字型,字符型,搜索型

3、使用order by来确定主查询数目。orderby本质上是一个排序的语法,但是order by有个条件,就是排序必须建立在正确的主查询条数上。所以在注入中用order by并不是为了排序,而是为了确认主查询的条数,确保union select的查询数与主查询一致。order by只会在超出主查询列数后才会报错,小于或等于主查询列数不报错。

4、使用union select 查询,将主查询项改成负数或不存在,select * from wuser where id = -1 union select 1,2,3

5、在显示的数字位置上,替换对应的查询语句,database(),version(),user()

6、使用information_schema进行所有内容查询,以下用课堂上的查询来举例:

a.使用database()得知当前的库名:woniu

b.根据库名列出所有的表名:SELECT group_concat(TABLE_NAME) FROM information_schema.TABLES WHERE TABLE_SCHEMA = "库名"

-1 union select 1,(SELECT group_concat(TABLE_NAME) FROM information_schema.TABLES WHERE TABLE_SCHEMA = "woniu"),3

c.根据库名woniu 表名 wstu 列出所有的列名:num,name,age

SELECT group_concat(COLUMN_NAME)  FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = "库名" AND TABLE_NAME = "表名"

d、知道表名和列名,可以直接查出表的内容

select group_concat(num) from wstu;select group_concat(name) from wstu;select group_concat(age) from wstu;



字符型注入:

字符型和数字型原理一样,只是需要注意下语法规范问题。

正常数字查询:select * from wuser where id = 1;

字符查询:select * from wuser where id = '1';

字符型的注入语句就变成 select * from wuser where id = '1 and 1=1'; 发现我们输入的内容都被包裹在单引号内,不能执行我们想要的sql语句,因此就要想办法去构造payload来脱离单引号包裹。

字符型注入的payload: id = 1' and 1=1 #

在sql查询中就变成了 select * from wuser where id = '1' and 1=1#'

我们通过自己添加的单引号跟原有的第一个单引号闭合,然后执行我们的sql注入语句,原来的第二个单引号因为无法处理,所以用#注释掉。

最终形成 select * from wuser where id ='1' and 1=1

在mysql中注释符有两种:#和--空格,通常我们在页面上使用话,要转换成url编码,#转换成%23,--空格转换成--+



判定字符型注入和数字型注入的区别:

输入单引号报错后将报错信息取出进行比对。

报错的是:''1'''   ,首先去掉报错文本的单引号-》'1''->去掉我们的输入1'-》'' ,发现剩下一对单引号,说明是字符型

报错的是:'1'',首先去掉报错文本的单引号-》1'->去掉我们的输入1'-》  ,发现没有引号留下,说明是数字型

字符型不一定就是单引号,也有双引号,也有括号等等,就要根据实际的报错情况去试探出查询的语法。



搜索型和字符型的用法相同,也是要考虑到闭合和注释的。

搜索型的语法一般是:select * from wuser where id like '%1%';

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄