命名空间

参考:

\phpinfo()也可以执行

如下代码是phti0n师傅code-breaking的function这道题目。

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

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

简单判断,我们可以利用create_function函数注入。但以上代码变量$action必须包含[a-z0-9_]之外的字符,才会执行$action('',$arg);

可以使用%5c(\)绕过,可以测试:

<?php
\phpinfo();

原因:

code-breaking puzzles第一题,function,为什么函数前面可以加一个%5c? 其实简单的不行,php里默认命名空间是\,所有原生函数和类都在这个命名空间中。普通调用一个函数,如果直接写函数名function_name()调用,调用的时候其实相当于写了一个相对路径;而如果写\function_name() 这样调用函数,则其实是写了一个绝对路径。 如果你在其他namespace里调用系统类,就必须写绝对路径这种写法。

可以理解,类似<?php echo "1";?>这样的简单,不涉及命名空间的的php脚本,其实这个脚本本身就处于一个默认的命名空间下,这个命名空间就是\。类似的我们也可以namespace其他的命名空间,并通过命名空间调用函数

<?php

namespace test1{
    function a(){
        echo 'a';
    }
}

namespace test2{
    function b(){
        echo 'b';
    }
    function phpinfo(){
        echo 'phpinfo changed';
    }

}

namespace{
    \test1\a(); # a
    \test2\b(); # b
}

非主命名空间下重写内置函数

在非主命名空间下(namespace{}和默认)下,我们可以更改php内置函数。

主命名空间下
先尝试在namespace{}默认情况下重写内置函数会是什么情况

<?php
// 默认
function phpinfo(){
    echo "phpinfo changed\n";
} # 报错:PHP Fatal error:  Cannot redeclare phpinfo() in
<?php
// namespace{}
namespace{
    echo "phpinfo changed\n";
} # 报错:PHP Fatal error:  Cannot redeclare phpinfo() in

非主命名空间下

<?php
namespace test2{
    function b(){
        echo 'b';
    }
    function phpinfo(){
        echo 'phpinfo changed';
    }

}

namespace{
    \test2\phpinfo();
}

可以看到已经更改了函数phpinfo()

此外还可以参见另一篇文章:重构函数和反射

results matching ""

    No results matching ""