来源:自学PHP网 时间:2015-04-16 23:15 作者: 阅读:次
[导读] 暑假写的文章了,最近博客没干货,发出来娱乐一下。为了响应爱慕锅(Mramydnei)、撸大师(索马里的海贼)、fd牛( fd)的号召成立的parsec团队,以及各位老师多年来对我的教育,我要...
暑假写的文章了,最近博客没干货,发出来娱乐一下。 为了响应爱慕锅(Mramydnei)、撸大师(索马里的海贼)、fd牛(/fd)的号召成立的parsec团队,以及各位老师多年来对我的教育,我要写篇回忆稿。看标题大家可能觉得,这陈芝麻烂谷子的事你还拿出来说啥。当然,我自己搓一点都无所谓,但怎么能丢了parsec的脸,各位还是且听我娓娓道来~
//存储flashpost图片
$filename = $dir.$this->uid.'.zip';
file_put_contents($filename, $this->avatardata);
//此时写入压缩文件夹内容
//解压缩文件
pc_base::load_app_class('pclzip', 'phpsso', 0);
$archive = new PclZip($filename);
if ($archive->extract(PCLZIP_OPT_PATH, $dir) == 0) {
die("Error : ".$archive->errorInfo(true));
}
//568 行
//判断文件安全,删除压缩包和非jpg图片
$avatararr = array('180x180.jpg', '30x30.jpg', '45x45.jpg', '90x90.jpg');
if($handle = opendir($dir)) {
while(false !== ($file = readdir($handle))) {
if($file !== '.' && $file !== '..') {
if(!in_array($file, $avatararr)) {
@unlink($dir.$file);
} else {
$info = @getimagesize($dir.$file);
if(!$info || $info[2] !=2) {
@unlink($dir.$file);
}
}
}
}
所以我就创建了一个包含phi文件夹的压缩包,phi里面放上webshell.php,上传上去。 这就是phpcms最早的头像上传漏洞。这个漏洞影响的不只是phpcms,也包括抄袭其代码的finecms。 finecms是一个很喜感的cms,在phpcms出问题以后,finecms偷偷将漏洞修复了,当然修复方法就是直接拷贝了phpcms的补丁。 0×02 finecms前台getshell(phpcms补丁绕过) 纯属抄袭自己不动脑子的人,最容易出问题,比如finecms的开发者。自以为自己反应速度得当,在迅雷不及掩耳盗铃的时间内将phpcms的补丁抄了过来,然后就安然度过了半年的悠闲时光。 phpcms的补丁被绕过了无数次难道你不知道么?你这么屌你的用户们知道么? 那么,我们来看看finecms(phpcms代码类似)是怎么修补这个漏洞的: public function upload() { if (!isset($GLOBALS['HTTP_RAW_POST_DATA'])) { exit('环境不支持'); } $dir = FCPATH.'member/uploadfile/member/'.$this->uid.'/'; // 创建图片存储文件夹 if (!file_exists($dir)) { mkdir($dir, 0777, true); } $filename = $dir.'avatar.zip'; // 存储flashpost图片 file_put_contents($filename, $GLOBALS['HTTP_RAW_POST_DATA']); // 解压缩文件 $this->load->library('Pclzip'); $this->pclzip->PclFile($filename); if ($this->pclzip->extract(PCLZIP_OPT_PATH, $dir, PCLZIP_OPT_REPLACE_NEWER) == 0) { exit($this->pclzip->zip(true)); } // 限制文件名称 $avatararr = array('45x45.jpg', '90x90.jpg'); // 删除多余目录 $files = glob($dir."*"); foreach($files as $_files) { if (is_dir($_files)) { dr_dir_delete($_files); } if (!in_array(basename($_files), $avatararr)) { @unlink($_files); } } // 判断文件安全,删除压缩包和非jpg图片 if($handle = opendir($dir)) { while (false !== ($file = readdir($handle))) { if ($file !== '.' && $file !== '..') { if (!in_array($file, $avatararr)) { @unlink($dir . $file); } else { $info = @getimagesize($dir . $file); if (!$info || $info[2] !=2) { @unlink($dir . $file); } } } } closedir($handle); } @unlink($filename); 所以补丁就采用了递归删除的方式,将压缩包中所有非法文件删除。就是这个dr_dir_delete函数。 我们就不研究这个函数了,我们考虑一种情况,那么如果我上传包含这样代码的压缩包: 这是乌云白帽子@felixk3y 在乌云上提出的绕过方法(http://www.wooyun.org/bugs/wooyun-2014-049794),当然我们应用到这里,也成功绕过finecms的补丁,造成getshell(http://wooyun.org/bugs/wooyun-2010-063369)。 0×03 突破程序员的小聪明,phpcms补丁的继续绕过 于是finecms意识到自己的问题,偷偷修补了这个安全问题。当时的他们是这样修复的:
// 创建图片存储的临时文件夹
$temp = FCPATH.'cache/attach/'.md5(uniqid().rand(0, 9999)).'/';
if (!file_exists($temp)) {
mkdir($temp, 0777);
}
$filename = $temp.'avatar.zip'; // 存储flashpost图片
file_put_contents($filename, $GLOBALS['HTTP_RAW_POST_DATA']);
// 解压缩文件
$this->load->library('Pclzip');
$this->pclzip->PclFile($filename);
if ($this->pclzip->extract(PCLZIP_OPT_PATH, $temp, PCLZIP_OPT_REPLACE_NEWER) == 0) {
exit($this->pclzip->zip(true));
}
@unlink($filename);
但是实质上这也只是解决了一个芝麻小的问题,而真正出现漏洞的点他们并未进行修复。 我们看到这段代码: 这也是一个很平常的思路,失败了肯定要报错并退出,因为后面的代码没法运行了。但是,程序员不会想到,有些压缩包能在解压到一半的时候出错。 发包的时候,将这个压缩包带上,会发现返回了500,出错信息: 但你的webshell已经解压完毕了。这个漏洞造成了finecms官网的沦陷: http://www.2cto.com/Article/201409/332918.html 。 if (!isset($GLOBALS['HTTP_RAW_POST_DATA'])) { exit('环境不支持'); } // 创建图片存储文件夹 $dir = FCPATH.'member/uploadfile/member/'.$this->uid.'/'; if (!file_exists($dir)) { mkdir($dir, 0777, true); } // 创建图片存储的临时文件夹 $temp = FCPATH.'cache/attach/'.md5(uniqid().rand(0, 9999)).'/'; if (!file_exists($temp)) { mkdir($temp, 0777); } $filename = $temp.'avatar.zip'; // 存储flashpost图片 file_put_contents($filename, $GLOBALS['HTTP_RAW_POST_DATA']); // 解压缩文件 $this->load->library('Pclzip'); $this->pclzip->PclFile($filename); if ($this->pclzip->extract(PCLZIP_OPT_PATH, $temp, PCLZIP_OPT_REPLACE_NEWER) == 0) { @dr_dir_delete($temp); exit($this->pclzip->zip(true)); } @unlink($filename); 但finecms的开发者依旧是没有能看到真正造成这个漏洞的原因。 原因就出在解压压缩包的这个操作上。这个类你就把别人的代码拿来一抄就觉得完毕了,你知道这个类真正的用法么?大家猜猜我这次怎么绕过上诉补丁的。 压缩包中通常是不含有诸如“../”、“..”这种文件名的,但通常不含有不代表不能含有。我如果把压缩包中某文件名改成../../../../../index.php,是不是就能直接把你首页变成我的webshell呀? 这就是因为抄袭者并没有真正领悟zip这个类的使用方法,导致了这个安全问题。我在本地用notepad++即可修改、构造一个压缩包。 先把自己的shell改名字成aaaaaaaaaaaaaaaaaaaa.php 之所以起这个名字,就是预留一些空间,方便我之后将文件名改成../../../aaaaaaaaaaa.php而不用怕字符串长度不对。 把文件直接打包成zip,用notepad++打开: 将我画框的俩文件名的前9个字符改成../../../ 然后,网站根目录下就会有你的shell了:aaaaaaaaaaa.php 通过这个方法,就能无限制地getshell:http://www.2cto.com/Article/201409/332919.html |
自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习
京ICP备14009008号-1@版权所有www.zixuephp.com
网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com