不确定 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 漏洞利用。

这可能吗,还是我只是偏执?

保持该代码不变确实是有风险的。

我试图找到一个可以过早夹住字符串的角色。但是,尽管我没有找到这样做的方法,但这并不是决定性的,可能还有其他方法可以篡改函数名称。由于PHP提供了命名空间语法(使用'),这也可以被创造性的用户利用。

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

函数名称遵循与 PHP 中其他标签相同的规则。有效的函数名称以字母或下划线开头,后跟任意数量的字母、数字或下划线。作为正则表达式,它将表示为:[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));
}

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

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

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

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