• PHP代码审计系列(二)


    PHP代码审计系列(二)

    本系列将收集多个PHP代码安全审计项目从易到难,并加入个人详细的源码解读。此系列将进行持续更新。

    strcmp比较字符串

    源码如下

    
    $flag = "flag";
    if (isset($_GET['a'])) {  
        if (strcmp($_GET['a'], $flag) == 0) //如果 str1 小于 str2 返回 < 0; 如果 str1大于 str2返回 > 0;如果两者相等,返回 0。 
    
        //比较两个字符串(区分大小写) 
            die('Flag: '.$flag);  
        else  
            print 'No';  
    }
    
    ?>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    通读代码逻辑如下:

    首先判断是否存在GET请求参数a

    若存在使用strcmp函数比较a与flag是否相等,若相等则输出flag退出脚本

    输入正确的flag,但我们是不知道flag的值的

    在这里插入图片描述

    利用strcmp函数的漏洞,当传入非字符串类型的数据这个函数将发生错误,但是在5.3之前的php中,显示了报错的警告信息后,将return 0也就是会判断相等

    在这里插入图片描述

    sha()函数比较绕过

    源码如下

    
    
    $flag = "flag";
    
    if (isset($_GET['name']) and isset($_GET['password'])) 
    {
        if ($_GET['name'] == $_GET['password'])
            echo '

    Your password can not be your name!

    '
    ; else if (sha1($_GET['name']) === sha1($_GET['password'])) die('Flag: '.$flag); else echo '

    Invalid password.

    '
    ; } else echo '

    Login first!

    '
    ; ?>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    通读代码逻辑如下:

    首先判断GET请求中是否存在name与password参数若都存在继续进行

    然后判断name是否等于password若等于则失败

    经过sha1加密===相等则输出flag

    这题也是条件矛盾了,根据sha1的漏洞进行比较的绕过(md5函数也存在)。

    传入非字符串类型使得sha1函数返回错误为false,两个都这样操作就false===false条件成立

    在这里插入图片描述

    SESSION验证绕过

    源码如下

    
    
    $flag = "flag";
    
    session_start(); 
    if (isset ($_GET['password'])) {
        if ($_GET['password'] == $_SESSION['password'])
            die ('Flag: '.$flag);
        else
            print '

    Wrong guess.

    '
    ; } mt_srand((microtime() ^ rand(1, 10000)) % rand(1, 10000) + rand(1, 10000)); ?>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    通读代码逻辑如下:

    首先启动session

    判断GET请求是否携带password如果携带则继续

    判断password与session中存储的password是否一致,一致则输出flag

    使请求与session中存储的 password一致即可

    http://localhost/phpbugs/08.php?password=
    
    • 1

    密码md5比较绕过

    源码如下

    
    
    //配置数据库
    if($_POST[user] && $_POST[pass]) {
        $conn = mysql_connect("********, "*****", "********");
        mysql_select_db("phpformysql") or die("Could not select database");
        if ($conn->connect_error) {
            die("Connection failed: " . mysql_error($conn));
    } 
    
    //赋值
    
    $user = $_POST[user];
    $pass = md5($_POST[pass]);
    
    //sql语句
    
    // select pw from php where user='' union select 'e10adc3949ba59abbe56e057f20f883e' # 
    
    // ?user=' union select 'e10adc3949ba59abbe56e057f20f883e' #&pass=123456
    
    $sql = "select pw from php where user='$user'";
    $query = mysql_query($sql);
    if (!$query) {
        printf("Error: %s\n", mysql_error($conn));
        exit();
    }
    $row = mysql_fetch_array($query, MYSQL_ASSOC);
    //echo $row["pw"];
    
      if (($row[pw]) && (!strcasecmp($pass, $row[pw]))) {
    
    //如果 str1 小于 str2 返回 < 0; 如果 str1 大于 str2 返回 > 0;如果两者相等,返回 0。
    
    
        echo "<p>Logged in! Key:************** </p>";
    }
    else {
        echo("<p>Log in failure!</p>");
    
      }
    }
    ?>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    通读代码逻辑如下:

    首先判断POST请求中是否存在user与pass字段,若存在尝试连接数据库,连接失败结束脚本

    之后对pass字段进行MD5加密赋值给变量$pass,user字段赋值给、$user

    执行以下sql,如果未查询到结果结束脚本

    select pw from php where user='$user'
    
    • 1

    若查询到数据结果,将执行mysql_fetch_array函数以关联数组形式返回数据查询结果

    如果返回的数组中存在pw字段并且$pass等于数组中的pw字段输出flag

    sql中存在注入,构造修改sql返回的pw结果集,payload如下

    user=' union select 'e10adc3949ba59abbe56e057f20f883e'#&pass=123456
    
    • 1

    在这里插入图片描述

    urldecode二次编码绕过

    源码如下

    
    if(eregi("hackerDJ",$_GET[id])) {
      echo("

    not allowed!

    "
    ); exit(); } $_GET[id] = urldecode($_GET[id]); if($_GET[id] == "hackerDJ") { echo "

    Access granted!

    "
    ; echo "

    flag: *****************}

    "
    ; } ?>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    通读代码逻辑如下:

    首先判断GET请求中是否存在id参数,若存在终止脚本

    对id参数通过urldecode函数进行url解码

    如果解码后的id等于hackerDJ则输出flag

    对hackerDJ中的h进行二次url编码绕过

    h对应的url编码未%68,%68url编码结果为%2568

    在这里插入图片描述

  • 相关阅读:
    springcloud5:zookeeper和Consul
    yo!这里是c++中的多态
    【高等数学基础进阶】导数与微分
    【TensorFlow】环境配置-----TensorFlow 安装与配置
    [OC学习笔记]ARC与引用计数
    vue-cli脚手架创建项目
    重新定义商业——以用户为中心的全新商业模式
    Bert-vits2-v2.2新版本本地训练推理整合包(原神八重神子英文模型miko)
    javascript基础七:说说你对Javascript中作用域的理解?
    谷粒学苑_第四天
  • 原文地址:https://blog.csdn.net/qq_18980147/article/details/128209395