如何从匿名函数创建有效负载


How to create a payload from a anonymus function

我想通过某种传输将一个函数发送到另一个脚本。

为此,我需要将此函数打包到一个PHP可评估负载中(将其评估为另一个PHP文件中的字符串,该文件可能在另一台服务器上)。

$abc = "testABC";
$xyz = new TestClass();
$test = true;
$x = function () use ($test, $xyz, $abc) {
    echo $abc;
    var_dump($test, $xyz);
};

这个函数将被打包成一个字符串,如下所示:

$payload = function () {
    $test = unserialize('b:1;');
    $xyz = unserialize('O:9:"TestClass":0:{}');
    $abc = unserialize('s:7:"testABC";');
    echo $abc;
    var_dump($test, $xyz);
};

为了完成这项工作,我编写了以下函数,它提取函数代码,匹配任何use(...)子句,并重命名被调用的变量。最后,它将把use(...)变量指定为不可序列化的字符串。

function packAnonFunction($payload, ...$args) {
    $func = new ReflectionFunction($payload);
    $filename = $func->getFileName();
    $start_line = $func->getStartLine() - 1;
    $end_line = $func->getEndLine();
    $length = $end_line - $start_line;
    $source = file($filename);
    $body = implode("", array_slice($source, $start_line, $length));
    $body = preg_replace('/('$[a-z]+)' '=' function/', '''$payload = function', $body);
    if(preg_match('/use's'(('$[a-zA-Z0-9]+(?:,'s'$[a-zA-Z0-9]+)*)')/', $body, $matches)) {
        $vars = $matches[1];
        if(strpos($vars, ', ') !== false) {
            $parts = explode(', ', $vars);
        } else {
            $parts = [$vars];
        }
        $return = [];
        foreach($parts as $key => $variable) {
            $return[$variable] = $args[$key];
        }
        $variableString = "";
        foreach($return as $var => $value) {
            $value = serialize($value);
            $variableString .= "'t{$var} = unserialize('{$value}');'n";
        }
        $body = str_replace(" use (" . $vars . ")", "", $body);
        $body = str_replace("{'n", "{'n" . $variableString, $body);
    }
    return $body;
}

你可以这样使用它:

$abc = "testABC";
$xyz = new TestClass();
$test = true;
$x = function () use ($test, $xyz, $abc) {
    echo $abc;
    var_dump($test, $xyz);
};
echo packAnonFunction($x, $test, $xyz, $abc);

我唯一没有避开的滞后是,您必须按照分配use(...)语句的顺序放置args($test, $xyz, $abc)。

在操作中查看:https://3v4l.org/89pXm

你怎么看?