不确定 php 5.6 字符串连接利用

Unsure of php 5.6 string concatenation exploit

我最近在我们的代码库中偶然发现了以下内容:

$func = $_GET['func'] . '_xyz123';
if(function_exists($func)){
   $result = $func($_GET);
   echo(json_encode($result));
}

这让我想知道,是否有可能将 php 内置函数 + 一些垃圾传递给 $_GET['func'],以便抵消 _xyz123 导致 RCE 利用.

这可能吗,还是我多疑了?

保留该代码确实存在风险。

I tried 查找可能会过早剪切字符串的字符。但是虽然我没有找到办法做到这一点,但这并不是决定性的,可能还有其他方法可以篡改函数名。由于 PHP 提供命名空间语法(使用 \),创意用户也可以利用它。

但没有理由冒险允许用户输入包含不应出现在函数名称中的字符。函数名称必须遵循 rules:

Function names follow the same rules as other labels in PHP. A valid function name starts with a letter or underscore, followed by any number of letters, numbers, or underscores. As a regular expression, it would be expressed thus: [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*

因此,您可以确保拒绝任何具有违规字符的参数(包括命名空间语法中的反斜杠)。使用引用的正则表达式,您可以按如下方式执行此操作:

function isValidName($name) {
    return preg_match("/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/", $name);
}

$func = $_GET['func'] . '_xyz123';

if(isValidName($func) && function_exists($func)){
    $result = $func($_GET);
    echo(json_encode($result));
}

另一种保护应用程序安全的方法是将所有可以这种方式调用的函数定义为 class 的静态方法。假设 class 被称为 _xyz123,并且您的函数不会有此后缀,那么代码可能如下所示,使用 method_exists:

$func = $_GET['func'];
if(isValidName($func) && method_exists('_xyz123', $func)){

或者您可以在特定命名空间中定义所有这些函数,例如_xyz123,然后这样做:

if(isValidName($func) && function_exists('\_xyz123\$func')){