题目:Bugku CTF(Web)——login1)
writeup

第一次遇到这种基于约束的SQL攻击,在此记录一下吧。

参考文章:
WangEX's Blog
Dhaval Kapil

1. 知识储备

1.1数据库字符串比较:

在数据库对字符串进行比较时,如果两个字符串的长度不一样,则会将较短的字符串末尾填充空格,使两个字符串的长度一致,比如,字符串A:String和字符串B:String2进行比较时,由于String2String多了一个字符串,这时MySQL会将字符串A填充为String ,即在原来字符串后面加了一个空格,使两个字符串长度一致。看如下两条查询语句:

select * from users where username='admin'
select * from users where username='admin    '

它们的查询结果是一致的,即第二条查询语句中admin后面的空格并没有对查询有任何影响。因为在MySQL把查询语句里的username和数据库里的username值进行比较时,它们就是一个字符串的比较操作,符合上述特征。

1.2INSERT截断:

这是数据库的另一个特性,当设计一个字段时,我们都必须对其设定一个最大长度,比如CHAR(10),VARCHAR(20)等等。但是当实际插入数据的长度超过限制时,数据库就会将其进行截断,只保留限定的长度。

2. 漏洞复现

这里我搬运一篇博客里面的场景吧。如果想看具体的题目可以到开头的题目那里去看看。


我们把利用场景设在用户登陆的地方,假如有用户[Dumb],我们想要使用他的账号登陆,但是我们又不知道他的密码,那么我们可以注册一个名字叫[Dumb done]的用户,即在目标用户名的后面加一串空格(注意:空格后需再跟一个或多个任意字符,防止程序在检查用户名是否已存在时匹配到目标用户),空格的长度要超过数据库字段限制的长度,让其强制截断。

当我们注册该用户名后,由于截断的问题,此时我们的用户名就为:[Dumb ],即除了后面的一串空格,我们的用户名和目标用户名一样。

假如服务端的用户登陆代码为:

<?php
$username = mysql_real_escape_string($_GET['username']);
$password = mysql_real_escape_string($_GET['password']);
$query = "SELECT username FROM users
          WHERE username='$username'
              AND password='$password' ";
$res = mysql_query($query, $database);
if($res) {
  if(mysql_num_rows($res) > 0){
      return $username;//此处较原文有改动
  }
}
return Null;
?>

从一般SQL注入的角度看,这段代码是不能注入的,但是当我们以目标用户名Dumb和我们自己注册用户的密码进行登陆时就可以绕过认证。当我们以用户名:[Dumb]和密码:[123456](假设)登陆时,对应的SQL语句就为:

SELECT username FROM users WHERE username='Dumb' AND password='123456'

当执行这条语句后,数据库将返回我们自己注册的账户信息,但是注意此处的return $username,虽然此时查询出来的是我们自己的用户信息,但是返回的用户名则是目标的用户名。如果此后的业务逻辑直接以该用户名为准,则我们就达到了水平越权的目的。

3. 限制条件

  1. 服务端没有对用户名长度进行限制。如果服务端限制了用户名长度就不能导致数据库截断,也就没有利用条件。
  2. 登陆验证的SQL语句必须是用户名和密码一起验证。如果是验证流程是先根据用户名查找出对应的密码,然后再比对密码的话,那么也不能进行利用。因为当使用Dumb为用户名来查询密码的话,数据库此时就会返回两条记录,而一般取第一条则是目标用户的记录,那么你传输的密码肯定是和目标用户密码匹配不上的。
  3. 验证成功后返回的必须是用户传递进来的用户名,而不是从数据库取出的用户名。因为当我们以用户Dumb和密码123456登陆时,其实数据库返回的是我们自己的用户信息,而我们的用户名其实是[Dumb ],如果此后的业务逻辑以该用户名为准,那么就不能达到越权的目的了。

4. 随便写写

SQL约束攻击还是老问题,对用户输入检查不严格。我觉得应用的场景应该不是很多,毕竟空白符一般都是不给输入的。(本人能力有限,如有错误,欢迎指教。)

最后修改:2019 年 07 月 03 日
如果觉得我的文章对你有用,请随意赞赏