分类 sql-labs 下的文章

前言:本次实验使用phpstudy作为web集成环境,关于phpstudy搭建

0x00:首先点击下载sqli-labs源码https://codeload.github.com/Audi-1/sqli-labs/zip/master

0x01:解压后放进网站根目录,进到 sqli-labs的文件夹下,打开 sql-connections文件夹

0x02:打开编辑 db-creds.inc,填入mysql的账号跟密码

0x03:然后在本机浏览器地址栏输入 http://127.0.0.1/你放在网站根目录下的文件夹名称/,如我的是 http://127.0.0.1/sql

0x04:然后就可以点击下面的关卡进去练习了

1.网页界面说让我们输入id序号

2.那我就在url地址栏加上下面代码回车,可以看到已经登录成功

?id=1

3.测试注入点,首先可以判断这里接受的是一个GET请求,先在1后面加一个’ 发现报错,说明这里没有过滤掉引号,所以这里是一个注入点

【关键】分析为什么会报错,当输入?id=1' 后端传递给mysql时,mysql实际执行了下面的代码:

select * from users where id='1'' limit 1;

发现没有,多了一个单引号,所以会报错

4.SQL注入通常有两种类型,整形注入和字符型注入,那么判断这里是哪种注入就要分析这里的报错语句,报错信息中共有5个单引号,”实际上是两个单引号,最外面的两个是报错信息的提示引号,’1’两边的引号是后台代码的引号,多出来的就是我们加上的,因为这里给输入的1加上了引号所以后台接受的是字符型,那么我们在后续的注入中需要加 ’ 来闭合后面的引号。GET请求后数据会转为url编码,20%是空格,27%是单引号。

5.经过测试发现–+注释符可以用,注入点加下面代码来查询原sql查询语句查询了多少个关键字。注释符的作用至关重要,可以把注入语句后面的代码注释掉,从而不影响我们注入语句的执行。常用的注释符有 “#...” “-- ...” “/*...*/”,这里我解释下为什么我们注释使用 “--+”,因为 -- 注释符在后面必须要跟一个空格,我们在url地址栏 -- 后面输入空格会被过滤掉,所以使用 --+让 + 号占一个位置。

order by 1--+

【关键】为什么payload要加注释符呢?其实是为了payload把后面的语句去掉,防止干扰payload执行,比如没有注释掉后面的

select * from users where id='1' order by 1' limit1;

那上面的语句肯定会报错,因为多了个单引号和 limit 1;如果有注释的话:

select * from users where id='1' order by 1--+' limit1;  //这样mysql就实际执行的是下面的代码
select * from users where id = '1' order by 1;   //这样就不会报错,达到了我们sql注入的目的

6.我们从1开始测试,到4的时候报错,说明后端sql语句对表查询了3个字段,order by 1 的意思就是,第一个查询字段的数据作为排序的依据,因为后端查询的字段只有3个,所以当 order by 4 的时候因为没有第四个字段存在,所以会报错没有正常显示。我这里看了下后端代码,使用的是 select * ... , * 的意思就是所有,也就是查询表里面所有的字段。为了大家看的比较直观,我po出了这个表:

从上面可以看出,确实是只有3列

7.然后我们可以注入点加下面代码进行回显位置判断(id=0可以避免数据库表数据的干扰),可以看到3跟2可以显现出来,因此我们可以把2或3替代为需要注入的sql语句。关于union

union select 1,2,3--+

8.查库,用group_concat一行显示出所有库,注入点加下面 代码;代码意思是在information_schema这个库的schemata表里面,把schema_name这列的数据用group_concat函数全部分成一组显示出来。关于group_concat()

union select 1,2,(select group_concat(schema_name) from information_schema.schemata)--+

9.用database()查出当前工作所用的库。

10.查出显示是security这个库,下一步是查出security这个库里面有什么表;注入点加下面的利用代码 ;代码意思是,在information_schema这个库下的tables表里面,筛选出table_schema这个列是security的数据,并且把table_name这一列组合显示出来。了解sql中where的用法

union select 1,2,(select group_concat(table_name) from information_schema.tables where table_schema='security')--+

11.上面可以看到有四个表,我们可以查看下users里面有什么列

12.注入点加利用代码;代码的意思是,在information_schema这个库的columns表里面,筛选出table_name是users的数据,并且把column_name这个列的数据组合显示出来;这样我们就查到了users这个表里面有什么列。

union select 1,2,(select group_concat(column_name) from information_schema.columns where table_name='users')--+

13.我们先把用户名爆出来,注入点加下面的利用代码;代码的意思是,把security库下的users表里面的username列中的数据,组合显示出来。

union select 1,2,(select group_concat(username) from security.users)--+

14.再查密码,注入点加利用代码;代码的意思是,把security库下的users表里面的password列中的数据,组合显示出来

union select 1,2,(select group_concat(password) from security.users)--+

15.将爆出的账号跟密码组合起来,这样就得到了网站下的账号跟密码。

1.和第一关同理,先加’ ,报错,说明此处存在漏洞,根据报错信息,此处有三个引号说明这里是接收的是整形数据,或者这里也可以输入 2-1 或者 6-2之类的整形计算,没有报错说明这里可以进行整形计算遂判断这里是整形注入。注入点为?id=1

2.整数型注入无需再加单引号闭合前面的引号。

3.接下来是爆库,爆表,爆字段

1.我们url加?id=1’发现报错,是5个单引号,还多了个),所以这里猜测后台查询语句为:WHERE id=('$id') 所以这里采用 ') 来闭合。注入点为id=1')

2.接下来的爆库爆表爆字段跟第一关一样,参考第一关的语句

1.第一步仍然是判断注入点,我们加单引号发现不报错,那么就加双引号试试,果然不出老夫所料,报错了,而且还多了一个单括号。那么我们就用 “) 来闭合。注入点为id=1”)

2.接下来的爆库,爆表,爆字段跟第一关一样