is_numeric函数的绕过

  • 1.利用数组+十六进制来进行绕过,j[]=58B
  • 2.空字符%00绕过,is_numeric对%00和放在后面的%20的判断是非数值
  • 3.php中当一个其他数据类型和数值类型的数据比较大小时,会先将其他数据类型转换成数值类型,这里输入类似9999a数据也可绕过

val()函数和dumpfile()

$("#content").val() 是什么意思:

获取id为content的HTML标签元素的值,是JQuery,     ("#content")相当于document.getElementById("content");

("#content").val()相当于 document.getElementById("content").value;

例:[RoarCTF 2019]Easy Calc

num传递字母会被waf拦截

payload:http://node3.buuoj.cn:29279/calc.php?%20num=var_dump(scandir(chr(47)))扫描目录

在num前加一个空格符来绕过waf拦截

原因:假如waf不允许num变量传递字母,可以在num前加个空格,这样waf就找不到num这个变量了,因为现在的变量叫“ num”,而不是“num”。但php在解析的时候,会先把空格给去掉,这样我们的代码还能正常运行,还上传了非法字符。

同理查看该文件内容

payload:http://node3.buuoj.cn:29279/calc.php?%20num=var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))

两种等号

php中有两种比较的符号 == 与 ===

  • == 在进行比较的时候,会先将字符串类型转化成相同,再比较
  • === 在进行比较的时候,会先判断两种字符串的类型是否相等,再比较
如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换成数值并且比较按照数值来进行,所以要是有is_numeric判断直接加个字母就行

strcmp漏洞绕过

strcmp是比较两个字符串,如果str1<str2 则返回<0 如果str1大于str2返回>0 如果两者相等 返回0

假如不知道$password的值的,题目要求strcmp判断的接受的值和$password必需相等,strcmp传入的期望类型是字符串类型,那就传入一个数组类型,传入 password[]=xxx 可以绕过 是因为函数接受到了不符合的类型,将发生错误,但是还是判断其相等

md5绕过(Hash比较缺陷)

0e在比较的时候会将其视作为科学计数法,所以无论0e后面是什么,0的多少次方还是0。md5('240610708') == md5('QNKCDZO')

QNKCDZO
0e830400451993494058024219903391

s878926199a
0e545993274517709034328855841020
  
s155964671a
0e342768416822451524974117254469
  
s214587387a
0e848240448830537924465865611904
  
s214587387a
0e848240448830537924465865611904
  
s878926199a
0e545993274517709034328855841020
  
s1091221200a
0e940624217856561557816327384675
  
s1885207154a
0e509367213418206700842008763514

file_get_contents

这个函数是从文件读取内容到字符串,就可以利用data协议绕过,将指定字符串写入,而data://协议允许读入,payload:

传入的变量=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=(base64编码)

文件包含和filter伪协议见之前文章

JSON绕过

输入一个json类型的字符串,json_decode函数解密成一个数组,判断数组中key的值是否等于 $key的值,但是$key的值我们不知道,但是可以利用0=="admin"这种形式绕过

message={"key":0}

最后拿一个韦神学长出的题来来演示一下

<?php
error_reporting(0);
highlight_file(__FILE__);
include "passwd.php";

if(isset($_GET['L1'])) {
    $L1 = $_GET['L1'];
    echo "Here is level1.<br />";
    is_numeric($L1) ? die("nonono!") : NULL;
    if ($L1 > 2021) {
        echo "Congratulations,You pass the level1!<br />";

        echo "Here is level2.<br />";
        if(isset($_GET['L2']))
            $L2=$_GET['L2'];
        if (strlen($L2) <= 3 && $L2 > 20000) {
            echo "Congratulations,You pass the level2!<br />";

            echo "Here is level3.<br />";
            if (isset($_GET['L3']))
                $md5_1 = md5('QNKCDZO');
            $md5_2 = md5($_GET['L3']);
            if ($md5_1 == $md5_2) {
                echo "Congratulations,You pass the level3!<br />";

                echo "Here is level 4.<br />";
                if (isset($_GET['L4']))
                $level_4 = $_GET['L4'];
                // You can't know my password
                    if (strcmp($level_4, $level_4_password) == 0) {
                        echo "Password is right,You pass the level4!<br />";

                        echo "Here is level5.<br />";
                        if (isset($_POST['L5'])) {
                            $level_5 = $_POST['L5'];
                            eval("print_r($level_5);");
                        }
                    } else {

                        die("Sorry, you didn't pass the level4!");

                    }

            } else {

                die("Sorry, you didn't pass the level3!");

            }
        } else {

            die("Sorry, you didn't pass the level2!");

        }
    }
    else {

        die("Sorry, you didn't pass the level1!");

    }
}

Level1是is_numeric函数判断L1不能是数字且大于2021,那就加个字母,L1=99999a

Level2要求L2长度不能大于3且大于20000.那就科学计数法,直接L2=9e9

Level3是判断L3和”QNKCDZO“的MD5是否相等,但是没有说不能一样啊,直接L3=QNKCDZO

Level4判断了L4和L4_Password,这里是strcmp的漏洞,直接L4[]=a绕过

Level5是将POST传入的L5命令执行并输出,那就L5=system("tac flag.php")

补充:

1、PHP的字符串解析特性是什么?

答: PHP需要将所有参数转换为有效的变量名,因此在解析查询字符串时,它会做两件事:1.删除空白符  2.将某些字符转换为下划线(包括空格)【当waf不让你过的时候,php却可以让你过】

2、发现过滤怎么办?

答:用char()转ascii再进行拼接

3、字符串要求一定大小又限制了长度?科学计数法 9e9干上去!!!

届ける言葉を今は育ててる
最后更新于 2023-01-09