sql注入讲解

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

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

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

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

三、成功执行后,仅仅是跟正常查询显示相同的内容,那有没有办法能够显示其余内容呢?咱们在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;

四、union select查询成功后显示的仍是没有变,其缘由是主查询也成功返回告终果,而页面上只显示了返回结果的第一行,所以要想看到union select的结果,须要令第一行也就是主查询的结果为空。经常使用的办法就是把主查询的1改为-1.

五、mysql中有几个默认自带的库和查询函数。咱们就可使用这些来查出数据库中全部的内容。

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

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

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

 

union 查询的通常步骤:

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

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

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

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

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

六、使用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%';

sql

相关文章
相关标签/搜索