源码来源于别人,看他审计,所以自己也去看了下。
源码是基于ThinkPHP3.1.3的,本来想找个前台注入的,但是写法比较单调,存在如下写法:
第一种普遍存在的写法,简化下就是:
$down=M('xxx')->field('id')->where("url ='%s'",array($_GET['id']))->find();
这种是不存在注入的,因为:
public function where($where,$parse=null){
if(!is_null($parse) && is_string($where)) {
if(!is_array($parse)) {
$parse = func_get_args();
array_shift($parse);
}
$parse = array_map(array($this->db,'escapeString'),$parse);
$where = vsprintf($where,$parse);
}elseif(is_object($where)){
如果这样:->where("url =%s",array($_GET['id'])) 没有单引号包裹是存在的。
一顿操作后,没找到注入,于是我想着去看下后台权限验证(其实会出问题的可能性是比较小的)
后台所有控制器类继承于后台控制器基类,基类代码如下:
很直白的权限验证,就是需要SESSION中的uid,和uname两个键需要有值。
这个_initialize方法默认调用,实现:在tp框架中的Action基类中实现。
这个验证是比较硬性条件的,因为SESSION是存在服务器的,是我们没办法伪造的。
于是我想看下能不能直接设置session。(这个几乎是不可能存在的,概率很低的)
然后可能存在就是全局变量注册,或者类似TP5代码执行那种任意调用类中方法,
这些情况可以利用来设置一个session这种。然后我看了下设置session有一个专门的函数:
本质就是:
session('id','123456'); = $_SESSION['id']='123456';
然后我就全局搜索:session(
有4,5处,其他的都没用,就一处生成验证码处有用,如图:
这是什么意思啊,我一直觉得这可能是程序员故意留的一个后门,因为好像没一点用,而且刚好和后台验证对应,
这也太巧了吧。
随机码:$randval = substr(str_shuffle(str_repeat('0123456789',3)));
猜4个猜不到,猜1个还猜不到啊。
找调用,这肯定在登录的地方存在,但是还是直接搜索下这个函数:
直接控制器下的方法,所以直接访问该方法,传递一个:?rands=1 访问个20次差不多就可以碰对了,就可以直接进入后台了。
后台getshell就是:直接搜索file_put_contents(
直接写入,抬走。
该程序员:看到前面那片海没有,那就是劳资给你放的水。
漏洞利用:
想payload?没门。
附:重点在文章,而不在exp,开头给出了源码下载地址。
文章仅做学习交流,切勿用于非法操作,该漏洞很早以前已经提交cnvd了,并已修复。