不确定利用

问题描述:

我最近遇到在我们的代码库以下跌跌撞撞:不确定利用

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

这让我想,如果有可能的PHP内置函数+一些垃圾传递给$_GET['func'],所以它会取消掉_xyz123导致RCE利用。

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

+0

空字符可能做到这一点,但是这让我不知道为什么他们会打扰。它似乎是一个非常奇怪的方式来构建一个漏洞,但是“奇怪”的是很多漏洞未被发现的方式。 – samlev

+0

A \ 0字符不会:https://3v4l.org/6vsmJ – VolkerK

+0

unicode范围内的任何其他字符都不在0x0 ... 0xFFFF:https://3v4l.org/3MlSg – trincot

离开代码确实是有风险的。

I tried找到可能过早剪切字符串的字符。但是,尽管我没有办法做到这一点,但这不是确定性的,并且可能有其他方法来篡改函数名称。由于PHP提供名称空间语法(使用\),因此也可以被创意用户利用。

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

函数名称遵循与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')){ 
+0

感谢您的调查!相当有帮助。 – jjb