phpcms上传导致getshell详解及案例

这篇文章好几天前写了,给协会里新成员普及知识,看大家也都玩的差不多了,就发表到博客里,增加一点噱头和访问量,哈哈~

0x01 什么是上传漏洞
很多cms为了丰富自己的功能都提供了上传头像、上传图片等功能。但如果上传的内容没有做好过滤,则等于说给了攻击者一个执行任意代码的途径。比如攻击者可以在上传一个含有恶意代码的文件,伪装成图片,来绕过后台的检测机制。
以前一般的上传漏洞主要有以下几个方式造成:
0.在客户端用javascript或flash验证用户上传的文件格式,但上传到服务器后没验证。
1.对用户上传的文件只检查了ContentType,但ContentType是可以被用户修改的,所以用户上传的脚本文件可以将ContentType改成image/gif来绕过检查。
2.黑名单机制。检查用户上传的文件的后缀,如果是处于黑名单中的后缀,就返回错误信息。但黑名单机制很不好,不够完善,当黑名单中有遗漏的时候,攻击者就能够生虚而入。
3.没有对用户上传的文件改名。网站有时候检查了用户上传的文件后缀是.jpg或.gif,于是就上传成功了,不对上传的文件进行改名。但一旦服务器存在解析漏洞,攻击者就可以利用畸形文件名来上传恶意代码。比如IIS6.0的解析漏洞,攻击者即可上传文件名类似“muma.asp;.gif”的文件,虽然看起来是一个gif格式,但IIS6.0就会把它解析成asp脚本运行。
4.解压缩功能造成问题。有些网站有这样的功能,比如wordpress和emlog后台支持上传压缩包(上传后自动解压),这样我们把恶意代码写在压缩包中某文件里,就能在上传解压后被运行。

像一些大型的CMS,用户量很多,他们的安全也做的较好,前台直接上传绕过执行任意代码的漏洞很少。一旦前台存在这种漏洞,任何人都能上传webshell到网站中。
但据说一年前phpcms就有这个0day了,知道昨天才被公开。

0x02 过程演示
首先找到目标网站(使用phpcms搭建),注册一个账号。来到用户中心 – 上传头像
01.jpg

先选择一个正常的头像:
02.jpg

打开burp_suite,这是我很喜欢的一个工具,里面有一个抓包、改包的功能,我们就需要改我们上传时发送的数据包,绕过客户端的后缀验证。
具体的burp_suite怎么用就不是重点了,想了解的同学自己谷歌。
打开burp_suite后,监听8080,然后我们把浏览器代理开成localhost:8080,点击这里的“保存图片”。
这时,burp_suite中就截获了上传的数据包:
03.jpg

从那个“PK”到最后结尾,一大段东西,实际上就是我们上传的这个图片。我们把它们全部删掉,包括“PK”。
然后我们要构造一个包含恶意代码的数据包,我新建了一个zip压缩包,里面包含一个文件夹“phi”,这个文件夹里包含一个我的webshell:“xm.php”。就是/phi/xm.php
然后我们回到burp_suite中,在刚才PK的位置右键 – Paste from file:
04.jpg

选择我们这个压缩包:
05.jpg

然后点上面的Forward,将数据包放行。
然后来到历史记录,翻一下,应该会看到返回一个类似 phpsso_server/uploadfile/avatar/1/1/1/90*90.jpg的文件,这里就是我们的头像上传目录。
06.jpg

其实到这里我们已经上传成功了,我们上传的这个webshell就在这里:http://www.xxx.com/phpsso_server/uploadfile/avatar/1/1/1/phi/xm.php
红色的就是你的头像上传目录。蓝色的是你压缩包的文件结构。
访问这个地址发现OK了。
07.jpg

菜刀连一下成功,在剩下的事我就没兴趣了:
08.jpg

0x03 漏洞原理
说一下为什么我们构造一个这样的压缩包就能getshell。
phpcms对头像上传是这么处理,上传上去的zip文件,它先解压好,然后删除非图片文件。
关键地方代码:

//存储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);
      }
     }
    }
      }

可以看到,它删除的时候没有递归删除,也没有删除文件夹。这样,只要我们的webshell放在压缩包的文件夹中,即可避免被删除了。
所以我就创建了一个包含phi文件夹的压缩包,phi里面放上小马xm.php,上传上去。

0x04 防范上传漏洞
首先必须在服务器验证用户上传,可以不用检查ContentType,直接检查后缀,如果在白名单中,就对该文件重命名后再复制到网站目录中,重命名时就用白名单里的后缀。重命名的方式可以是 “时间戳 + 随机数.jpg”等。
尽量不允许前台用户上传压缩包,如果上传压缩包,一定要递归检查压缩包中所有文件后缀,删除非法的文件。
最后,将上传目录设置成不可执行。这样就算webshell被上传了也不能被执行,比如我测试的某大型黑客网站,虽然xm.php上传成功了,但被禁止执行了:
10.jpg

0x05 附加篇:怎么找到使用phpcms的网站
我前两篇都有这个栏目,因为大家处在web安全初期,平时要多练手,所以可以找一些网站进行实战。
phpcms是一个大型的cms,用的人很多,基本上是以万计数,所以找起来很容易。
直接百度 powered by phpcms即可:
09.jpg

大家学习的时候请低调,不要惹出什么事端,被请去喝茶。

相关推荐: 如何简单地找回保存在浏览器里的密码

    一个简单的议题,也是同学们比较常遇到的问题,怎样找回保存在浏览器的“自动填写表单”功能中的密码。最容易想到的当然是抓包。一般的网站数据包里密码就是明文的,不过有些却也不是,可能是经过hash之后传递的(多数大网站)。   …

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论