• CTF 代码审计之绕过过滤的空白字符


    题目

      $value) {
            $value = trim($value);
            if(is_string($value)){
                $req[$key] = addslashes($value);
            }
        }
    }
    
    //定义 is_hwhs_number 函数,用于判断一个数字是否为回文数字。
    function is_hwhs_number($number) {
        $number = strval($number);
        $i = 0;
        $j = strlen($number) - 1;
        while($i < $j) {
            if($number[$i] !== $number[$j]) {
                return false;
            }
            $i++;
            $j--;
        }
        return true;
    }
    
    
    //判断传入的 number 是否为数字类型/整数类型,如果是,则返回一个提示信息。
    if(is_numeric($_REQUEST['number'])) {
        $info="抱歉您输入的是数字";
    }
    elseif($req['number']!=strval(intval($req['number']))) {
        $info = "数字必须等于其整数!!";
    }
    else {
    
    //将整数化后的 number 和其反转后的值进行比较,如果不相同,则返回提示信息。
        $value1 = intval($req["number"]);
        $value2 = intval(strrev($req["number"]));
        if($value1!=$value2=232){
            $info="这不是回文数字!!";
        }
        else {
        //判断 number 是否为回文数字,如果是,则返回一个提示信息,否则输出 flag2.php 文件的内容。
            if(is_hwhs_number($req["number"])){
                $info = "{$value1} 是一个回文数字!";
            }
            else {
                var_dump($flag);
            }
        }
    }
    ?>
    
    
    • 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
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76

    函数

    代码中使用到的函数:

    • trim:用于删除字符串两端的空白字符(包括空格、制表符、换行符等)。
    • intval:【取整】
    • strval:将变量转换为字符串
    • strrev:用于翻转字符串,将原先的字符串首尾对调。
    • addslashes:用于对字符串进行转义,将一些特殊字符转换成它们的转义形式,从而避免 SQL 注入。例如,将单引号 ' 转义成 \',将双引号 " 转义成 \",将反斜杠 \ 转义成 \\ 等。

    部分代码解释

        $value1 = intval($req["number"]);
        $value2 = intval(strrev($req["number"]));
    
    • 1
    • 2
    • 这两行代码分别将字符串 $req[“number”] 转成整数,分别存储在 $value1 和 $value2 变量中。

    • 其中,intval 函数将字符串转换为整数,如果 $req[“number”] 实际上不是一个数值字符串,则该函数返回 0。

    • 在第二行代码中,strrev 函数将字符串反转,即将字符串中的字符顺序翻转过来,例如,strrev(‘123’) 的输出结果为 ‘321’。然后再将反转后的字符串转成整数,存储在 $value2 变量中。

    • 这两个变量的作用是为了比较 $req[“number”] 和它的反转字符串是否相等。如果相等,则说明 $req[“number”] 是一个回文数,否则不是回文数。

    思路


    审计代码可以发现,number必须符合下面3个条件才可以输出flag:

    1. number不为空,且不能是一个数值型数字, 但过滤前得是数字
    2. number不能是一个回文数,过滤后是回文数。
    3. $value1!=$value2=232,限制number只能为232
    • number要为非数值,理所当然想到空格字符%20和空字符%00。注意is_numeric函数对于%20空格字符只能放在数值后,空字符%00无论是放在前后都可以判断为非数值。所以这里选%00.
    • %0C :是 URL 编码中的一种,它代表的是一个 ASCII 控制字符,即换页(Form Feed)\f 。在 PHP 中,%0C 会被解析成一个字符,会被 is_hwhs_number 函数判断为不是回文数字,从而进入 var_dump 的分支,输出 $flag 的内容。

    POC

    URL?number=%00%0C232
    
    • 1

    得到flag如下:

    
    C:\phpstudy_pro\WWW\pass2\02kbzf.php:58:string '' (length=44)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    参考

    1. php代码学习(二)绕过空白过滤
    2. PHP代码审计分段讲解
    3. 绕过过滤的空白字符
  • 相关阅读:
    使用服务器常见指令记录
    【面试题】 经典但依然超难做的 前端面试题 (值得收藏)
    如何验证 Kubernetes YAML 文件
    camera项目相关路径
    swiper 左右保留部分
    您与1秒钟测量两千个尺寸之间仅差一台智能测径仪!
    【JAVA刷题初阶】刷爆力扣第十弹——二叉树
    金融数字化转型这场硬仗,如何才能做到“有底”和“有数”?
    面向对象编程之断言assert
    【数据分享】北京市出租车GPS数据~
  • 原文地址:https://blog.csdn.net/qq_36292543/article/details/132598204