![3341bf480eba6c9b64f452d60a58f517.png](https://img-blog.csdnimg.cn/img_convert/3341bf480eba6c9b64f452d60a58f517.png)
本文作者:霾
团队交流群:673441920
-----------------------------------------------------------
前言
POC镇楼!!!
http://www.xxx.xxx/index.php?admin_filemanager-uploadfile
漏洞演示过程:
首先我们利用D盾去监听下当前项目目录。
![1403dd98dc48c3880d59a059da012f1c.png](https://img-blog.csdnimg.cn/img_convert/1403dd98dc48c3880d59a059da012f1c.png)
然后我们在后台文件管理上传一个木马。
![f9b9a91e4913d291918f32114348a2d8.png](https://img-blog.csdnimg.cn/img_convert/f9b9a91e4913d291918f32114348a2d8.png)
然后我们在点击上传,去D盾看看。
![e8c731608a14d8c45dbecac79150079d.png](https://img-blog.csdnimg.cn/img_convert/e8c731608a14d8c45dbecac79150079d.png)
已经成功上传,然后我们直接去访问下这个木马。
![a4a9f0fe07fd6269b198c7ac3de95c89.png](https://img-blog.csdnimg.cn/img_convert/a4a9f0fe07fd6269b198c7ac3de95c89.png)
成功getshell。
代码审计过程:
路径:controladmin_filemanager.php
![ffebca65739b88fa9e910ce24d93116d.png](https://img-blog.csdnimg.cn/img_convert/ffebca65739b88fa9e910ce24d93116d.png)
第260行,if($this->post['dosubmit']),判断post中是否传入dosubmit值。
第261行,$currentdir= string::hstripslashes($this->post['currentdir']);,这里进入自定义函数区间。
路径:libstring.class.php
![562b41dee53c71606840947257985ed8.png](https://img-blog.csdnimg.cn/img_convert/562b41dee53c71606840947257985ed8.png)
第139行,if(is_array($string)),is_array代表判断是否是数组。
第140行,while(@list($key,$var) = @each($string)) ,list函数用于在一次操作中给一组变量赋值,each函数返回当前元素的键名和键值,并将内部指针向前移动。
第141行,if ($key != 'argc' && $key != 'argv' && (strtoupper($key) != $key || ''.intval($key) == "$key")),strtoupper把所有字符转换为大写,或者intval强制转换int类型。
第142行,if (is_string($var)),判断是不是string类型。
第143行,$string[$key] = stripslashes($var);,stripslashes删除反斜杠。
第145行,if (is_array($var)),is_array代表判断是否是数组。
第146行,$string[$key] = string::hstripslashes($var);,这个又重新进入区间。
第151行,$string=stripslashes($string);,stripslashes删除反斜杠。
我们在回到第一张图片。
![ffebca65739b88fa9e910ce24d93116d.png](https://img-blog.csdnimg.cn/img_convert/ffebca65739b88fa9e910ce24d93116d.png)
第262行到第264行,这里接收POST变量。
第265行到266行,这里声明个变量。
第267行到第273行,声明数组,赋值为$_FILES参数。
第274行,if(file_exists($savepath.$fileArr['name']) && !isset($newname)),file_exists代表检查文件或者目录是否存在,isset代表判断变量是否设置。
第275行,$this->message($this->view->lang['find_same_file'],'index.php?admin_filemanager-default');,这个是提示错误信息。
第276行,$newname = $newname ? $newname : $_FILES['uploadfile']['name'] ;,3元运算符。
第77行,$_ENV['upload']->upload('uploadfile', $savepath, $newname, $upfile_size, $overfile);,这里进入自定义区间。
路径:modelupload.class.php
![f5a71bd70e68d45faae76fcc4feed4e8.png](https://img-blog.csdnimg.cn/img_convert/f5a71bd70e68d45faae76fcc4feed4e8.png)
第29行,$alowexts = 'php|jpg|jpeg|gif|bmp|png|doc|docx|xls|ppt|pdf|txt|rar|zip';,这里我们就可以看到自定义了一串字符。
第30行,if(!isset($_FILES[$inputname]) && !is_array($_FILES)) return false;,判断$_FILES是否设置,在判断$_FILES是否是数组。
第31行,$savepath = str_replace("", '/', $savepath);,str_replace字符串替换。
第32行,$savepaths = $this->set_savepath($savepath);,那么这里就是设置存储路径。
第33行,if($isftp==1),判断是否FTP上传。
第34行,$savepaths = str_replace("", '/', HDWIKI_ROOT);,把目录设置为根目录。
第36行-第40行,这里是设置变量。
第41行,if(1 == $this->uploads),判断是否上传1个文件。
第42行,$this->uploads = 1;,设置定义变量。
第43行,$uploadfiles[0] = array('tmp_name' => $_FILES[$inputname]['tmp_name'], 'name' => $_FILES[$inputname]['name'], 'type' => $_FILES[$inputname]['type'], 'size' => $_FILES[$inputname]['size'], 'error' => $_FILES[$inputname]['error']);,这里定义一个数组。
第48行,foreach($_FILES[$inputname]['name'] as $key => $error) ,foreach循环。
第50行,这里代表循环存入数组。
第54行,if(!is_dir($savepaths) && !mkdir($savepaths, 0777)),判断目录是否存在,创建目录。
第60行,@chmod($savepaths, 0777);,设置权限。
第61行,if(!is_writeable($savepaths) && ($savepaths != '/')),判断是否可写。
我们回到第一张图片。
第279行,if($_ENV['upload']->up($isftp)),这里又进入自定义区间。
路径:modelupload.class.php
![4d90e2aa9abf87bfeed4ea96a6d92e2d.png](https://img-blog.csdnimg.cn/img_convert/4d90e2aa9abf87bfeed4ea96a6d92e2d.png)
第70行,if(empty($this->files)) return false;,判断$this->files是否为空。
第73行,foreach($this->files as $k=>$file),foreach循环。
第75行,$fileext = $_ENV['filemanager']->fileext($file['name']);,获取文件名点后面的后缀。
第76行,if(!preg_match("/^(".$this->alowexts.")$/", $fileext)),正则匹配。
第81行,if($this->maxsize && $file['size'] > $this->maxsize),这里判断文件大小。
第86行,if(!$this->isuploadedfile($file['tmp_name'])),判断临时文件是否上传。
第91行-第92行,定义变量。
第93行,if($isftp==1),判断是否FTP上传。
第94行,$savefile = str_replace("", '/', HDWIKI_ROOT)."/".$savename;,把目录设置为根目录。
第96行,if(!$this->overwrite && file_exists($savefile)) continue;,判断文件或者目录是否存在。
第99行-第118行,他这里是FTP上传文件。
第121行,if(move_uploaded_file($file['tmp_name'], $savefile) || @copy($file['tmp_name'], $savefile)),判断文件是否上传成功,并copy成功。
第123行,$this->uploadeds++;,$this->uploadeds加加。
第124行,@chmod($savefile, 0644);,赋予权限。
第125行,@unlink($file['tmp_name']);,删除临时文件。
漏洞修复建议:
1. 判断文件上传内容是否是二进制。
2. 判断文件内容是否有危险函数。
本文仅供学习,请勿用于违法用途。