Notice
同上文
https://hackerpoet.com/index.php/archives/785/
敏感函数回溯
这种方法应该是线下awd比较常见的测试方法,比如想看看有没有什么sql注入,就搜索一下mysql_query、mysqli_query 找到函数位置,回溯下参数来源,此时的来源如果可控,我们就能挖到漏洞,当然随着现在扫描器的发展,可以用扫描器或者是特定的代码审计工具来搜索,然后回溯是否存在漏洞
还是phpcms
/phpsso_server/phpcms/libs/functions/global.func.php
我们可以看到这个文件优一个string2array函数,调用了eval方法
function string2array($data) {
if($data == '') return array();
@eval("\$array = $data;");
return $array;
}
现在要做的就是要回溯这个传进来的$data 所以我们只需要找一下谁调用了string2array函数
目录下的/phpsso_server/phpcms/modules/admin/credit.php调用了类
public function creditlist() {
$appid = isset($_GET['appid']) ? $_GET['appid'] : exit('0');
$applist = getcache('applist');
$url = isset($applist[$appid]) ? $applist[$appid]['url'].$applist[$appid]['apifilename'] : exit('0');
$data['action'] = 'credit_list';
$res = ps_send($url.'&appid='.$appid, $data, $applist[$appid]['authkey']);
if(!empty($res)) {
$creditlist = string2array($res);
$str = '';
foreach($creditlist as $k=>$v) {
$str .="<option value=".$k.'_'.$v[0].'_'.$v[1].">".$v[0]."(".$v[1].")</option>";
}
echo $str;exit;
} else {
exit('0');
}
}
}
穿进去的$res变量调用了ps_send 函数 看着这形式就知道大概是路由解析
$res = ps_send($url.'&appid='.$appid, $data, $applist[$appid]['authkey']);
从上面的代码我们可以知道$appid可控 $applist过了一层getcache函数,我们跟进
首先加载配置 pc_base::load_config('cache') 在configs文件夹下找cache.php
然后调用cache_factory::get_instance() 跟进get_instance()函数
再跟进get_cache()函数
在里面找到load()关键字样 继续跟进
load方法根据传入的缓存配置信息来决定是加载文件缓存还是memcache,而默认情况是加载文件缓存。回到前面的getcache函数,获取到缓存类的实例后,调用该类的get方法。
因为默认使用cache_file类 我们直接定位里面的get方法
$filepath = CACHE_PATH.'caches_'.$module.'/caches_'.$type.'/';
这条代码告诉我们了 缓存文件的路径
在/caches/caches_模块名/caches_$type/下,默认情况下通过require引入并将结果复制给$data返回。
总结下在credit调用的链
$applist来源于缓存文件,那如果能找到写入缓存的点,没准就能控制缓存的内容,配合前面的creditlist方法实现代码执行。找到写入缓存的方法为set,文件路径拼接跟get差不多。
在applications类的add方法,39行处,将url写入数据库,回溯$url的来源,发现在26行处通过post传入。
大致利用方法如下,因为mamp下mysql扩展编译太费劲了,所以没有动手尝试,只是跟着走一遍链