0x01 代码执行
PHP代码执行漏洞可以将代码注入到应用中,最终到webserver去执行,该漏洞主要存在于eval()、assert()、preg_replace()、call_user_func()、array_map()以及动态函数中
- eval();
- assert();
- preg_replace();
preg_replace():加上模式修饰符也会造成代码执行
关于模式修饰符:https://www.php.net/manual/zh/reference.pcre.pattern.modifiers.php
//preg_replace([正则表达式], [要替换的内容], [被查找的字符串]); //preg_replace([1], [2], [3]);
[1]可控时:
$a=$_GET['a'];// /e preg_replace("/<php>(.*?)<\/php>$a",'\\1', "<php>phpinfo();</php>");
使$a=/e,会造成代码执行(php版本为5.5以下)
模式修饰符/e:如果设置了这个被弃用的修饰符, preg_replace() 在进行了对替换字符串的 后向引用替换之后, 将替换后的字符串作为php 代码评估执行(eval 函数方式),并使用执行结果 作为实际参与替换的字符串。单引号、双引号、反斜线(\)和 NULL 字符在 后向引用替换时会被用反斜线转义.
[2]可控时:
$a=$_GET['a'];//phpinfo(); preg_replace("/php/e", $a, 'php');
使$a=phpinfo();,成功代码执行
[3]可控时:
$a=$_GET['a'];//{php}phpinfo(){/php} preg_replace("/\s*\{php\}(.*?)\{\/php\}\s*/ies", '\\1', $a);
使$a={php}phpinfo(){/php},成功代码执行
模式修饰符/i:如果设置了这个修饰符,模式中的字母会进行大小写不敏感匹配。
模式修饰符/s:如果设置了这个修饰符,模式中的点号元字符匹配所有字符,包含换行符。如果没有这个 修饰符,点号不匹配换行符。这个修饰符等同于 perl 中的/s修饰符。 一个取反字符类比如 [^a] 总是匹配换行符,而不依赖于这个修饰符的设置。
0x02 修复
preg_replace()放弃使用/e修饰符
preg_replace_callback()使用该函数代替preg_replace()函数(preg_replace()函数使用/e修饰符的用法在PHP5.5之后被抛弃使用)
$a=$_GET['a'];//{php}phpinfo(){/php} preg_replace_callback("/\s*\{php\}(.*?)\{\/php\}\s*/ies", '\\1', $a);