• [FBCTF2019]Products Manager


    基于约束的SQL攻击

    一、知识点:

    1.数据库字符串比较:

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

    如下两条查询语句:

    select * from users where username='Dumb'

    select * from users where username='Dumb '

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

    2. INSERT截断:

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

    二、利用场景:

    利用场景设在用户登陆的地方,假如有用户[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,虽然此时查询出来的是我们自己的用户信息,但是返回的用户名则是目标的用户名。如果此后的业务逻辑直接以该用户名为准,则我们就达到了水平越权的目的。

    三、限制条件

    1.服务端没有对用户名长度进行限制。如果服务端限制了用户名长度就不能导致数据库截断,也就没有利用条件。

    2.登陆验证的SQL语句必须是用户名和密码一起验证。如果是验证流程是先根据用户名查找出对应的密码,然后再比对密码的话,那么也不能进行利用。因为当使用Dumb为用户名来查询密码的话,数据库此时就会返回两条记录,而一般取第一条则是目标用户的记录,那么你传输的密码肯定是和目标用户密码匹配不上的。

    3.验证成功后返回的必须是用户传递进来的用户名,而不是从数据库取出的用户名。因为当我们以用户Dumb和密码123456登陆时,其实数据库返回的是我们自己的用户信息,而我们的用户名其实是[Dumb      ],如果此后的业务逻辑以该用户名为准,那么就不能达到越权的目的了。

    参考:https://www.freebuf.com/articles/web/124537.html

    Products Manager wp

    题目提供了源码,可以看到flag在facebook用户这里,并且name长度的最大字节是64。

     因为有64字节的长度,所以我们名字要大于64字节,例如facebook(很多空格)1,这个作为用户名进行注册,成功注册用户后,我们用facebook作为用户名和刚刚我们设置的密码进行查询。

     得到flag。

  • 相关阅读:
    数据库删除Push
    MFC Tab Control控件的详细使用
    mysql char和varchar的长度
    PostgreSQL常用脚本
    Linux常用操作命令
    PostgreSQL杀掉会话
    PostgresSQL备份还原
    Grpc客户端添加请求头(Header)
    Polly重试
    名词探疑3:I18N,L10N,A11Y
  • 原文地址:https://www.cnblogs.com/wkzb/p/12286303.html
Copyright © 2020-2023  润新知