admin

基于约束条件的SQL注入
基于约束条件的SQL注入预备知识在讲述这中sql注入的攻击方式前我们先来了解下,这种方式是基于什么的原理而造成的。...
扫描右侧二维码阅读全文
10
2018/09

基于约束条件的SQL注入

基于约束条件的SQL注入

预备知识

在讲述这中sql注入的攻击方式前我们先来了解下,这种方式是基于什么的原理而造成的。

首先我们在数据库中创建一个表:

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

name这个字段的长度为20如果我们插入一个超过此字段的长度会怎么样呢?

mysql> insert into users(name) values("admin                                        1");
Query OK, 1 row affected, 1 warning (0.09 sec)

mysql> select * from users;
+----+----------------------+
| id | name                 |
+----+----------------------+
|  1 | admin                |
|  2 | tpl                  |
|  3 | admin                |
+----+----------------------+
3 rows in set (0.00 sec)

结果可以发现在insert语句中如果插入的字段数据超过设定的最大长度时会自动截断,仅保留设定的长度

id为1的name值和id为3的name值还是不一样的,区别在于id为3的nameadmin后含有大量的空格

那么第二个问题就来了 在select查询中空格是否为忽略呢?

mysql> select * from users where name = 'admin';
+----+----------------------+
| id | name                 |
+----+----------------------+
|  1 | admin                |
|  3 | admin                |
+----+----------------------+
2 rows in set (0.00 sec)

mysql> select * from users where name = 'admin    ';
+----+----------------------+
| id | name                 |
+----+----------------------+
|  1 | admin                |
|  3 | admin                |
+----+----------------------+
2 rows in set (0.02 sec)

结果告诉我们在select中空格并没有对查询有任何影响,因为在数据库的字符串比较中,如果两个字符串的长度不一样,则会将较短的字符串末尾填充空格,使两个字符串的长度一致
所以(1)admin和(2)admin 比较中会自动将(1)admin后加入大量空格与(2)达到相同的长度

利用场景

在一个会员中心如果我们想要获得某一个用户(Tom)的信息,此会员中心有注册的功能,那么我们可以通过上述的知识恶意注册一个Tom 1的用户那么在登陆时即可平行越权下面通过详细代码来演示下

这里用了SKCTF的login1的一道题

login.php
 <?php
    header('content-type:text/html;charset=utf-8');
    include 'flag.php';
    if(isset($_POST['username']) && isset($_POST['password'])){
        $username = $_POST['username'];
        $password = $_POST['password'];
        //pdo
        $pdo = new PDO('mysql:dbname=test;host=127.0.0.1', 'root', 'cTf_p@ssw0rD', array(PDO::ATTR_PERSISTENT=>true));
        $pdo->exec("SET names utf8");
        $sql = 'select * from user where username=? and password=?';                
        $stmt = $pdo->prepare($sql);
        $stmt->execute(array($username, md5($password)));
        if(!$stmt->rowCount()){
            echo "用户名或密码错误";
        } else {
            $info = $stmt->fetchAll(constant("PDO::FETCH_ASSOC"));
            
            if(trim($info[0]['username']) === 'admin'){
                echo $flag;
            } else {
                echo '不是管理员还想看flag?!';
            }
        }
    }
  
?>
register.php
<?php
  header('content-type:text/html;charset=utf-8');
  if(isset($_POST['sub'])){
    if(isset($_POST['username']) && isset($_POST['password'])){
      $username = $_POST['username'];
      $password = $_POST['password'];
      if(!(strlen($password)>=6 && preg_match('/[0-9]/', $password) && preg_match('/[a-z]/', $password) && preg_match('/[A-Z]/', $password))){
        echo '密码必须大于6位,包含大写字母,小写字母和数字';
      }else{
        if($username === 'admin'){
          echo 'admin已存在';
        } else {
          $pdo = new PDO('mysql:dbname=test;host=127.0.0.1', 'root', 'root', array(PDO::ATTR_PERSISTENT=>true));
          $pdo->exec("SET names utf8");
          $sql = "INSERT INTO user VALUES(?,?,?)";
          $stmt = $pdo->prepare($sql);
          $stmt->execute(array(NULL, $username, md5($password)));
          if($stmt->rowCount()){
            echo '注册成功';
            exit('<meta http-equiv="refresh" content="3;url=index.php"/>');
          } else {
            echo '注册失败';
          }
        }
      }
    }else{
      echo '用户名或密码不能为空';
    }
  }
?>

逻辑很简单获得用户名和密码匹配,如果用户是admin则输出flag,在注册页面防止了admin用户注册

if($username === 'admin'){
          echo 'admin已存在';

根据上述的insert截断我们注册一个admin 1密码为Admin123试试

mark

登录下
mark
可以看到拿到了flag

防御

  1. 在服务端对用户名长度进行检测
  2. 登陆验证的SQL语句必须是用户名和密码一起验证
  3. 验证成功后返回的必须是用户传递进来的用户名,而不是从数据库取出的用户名

Refer

https://dhavalkapil.com/blogs/SQL-Attack-Constraint-Based/
http://goodwaf.com/2016/12/30/%E5%9F%BA%E4%BA%8E%E7%BA%A6%E6%9D%9F%E6%9D%A1%E4%BB%B6%E7%9A%84SQL%E6%94%BB%E5%87%BB/

Last modification:September 10th, 2018 at 05:29 pm
If you think my article is useful to you, please feel free to appreciate

Leave a Comment