51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

phpcms上传导致getshell详解及案例

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

0x01 什么是上传漏洞 {#0x01}

很多cms为了丰富自己的功能都提供了上传头像、上传图片等功能。但如果上传的内容没有做好过滤,则等于说给了攻击者一个执行任意代码的途径。比如攻击者可以在上传一个含有恶意代码的文件,伪装成图片,来绕过后台的检测机制。

以前一般的上传漏洞主要有以下几个方式造成:

  1. 在客户端用javascript或flash验证用户上传的文件格式,但上传到服务器后没验证。
  2. 对用户上传的文件只检查了ContentType,但ContentType是可以被用户修改的,所以用户上传的脚本文件可以将ContentType改成image/gif来绕过检查。
  3. 黑名单机制。检查用户上传的文件的后缀,如果是处于黑名单中的后缀,就返回错误信息。但黑名单机制很不好,不够完善,当黑名单中有遗漏的时候,攻击者就能够生虚而入。
  4. 没有对用户上传的文件改名。网站有时候检查了用户上传的文件后缀是.jpg或.gif,于是就上传成功了,不对上传的文件进行改名。但一旦服务器存在解析漏洞,攻击者就可以利用畸形文件名来上传恶意代码。比如IIS6.0的解析漏洞,攻击者即可上传文件名类似"muma.asp;.gif"的文件,虽然看起来是一个gif格式,但IIS6.0就会把它解析成asp脚本运行。
  5. 解压缩功能造成问题。有些网站有这样的功能,比如wordpress和emlog后台支持上传压缩包(上传后自动解压),这样我们把恶意代码写在压缩包中某文件里,就能在上传解压后被运行。

像一些大型的CMS,用户量很多,他们的安全也做的较好,前台直接上传绕过执行任意代码的漏洞很少。一旦前台存在这种漏洞,任何人都能上传webshell到网站中。

但据说一年前phpcms就有这个0day了,知道昨天才被公开。

0x02 过程演示 {#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 漏洞原理 {#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 防范上传漏洞 {#0x04}

首先必须在服务器验证用户上传,可以不用检查ContentType,直接检查后缀,如果在白名单中,就对该文件重命名后再复制到网站目录中,重命名时就用白名单里的后缀。重命名的方式可以是 "时间戳 + 随机数.jpg"等。

尽量不允许前台用户上传压缩包,如果上传压缩包,一定要递归检查压缩包中所有文件后缀,删除非法的文件。

最后,将上传目录设置成不可执行。这样就算webshell被上传了也不能被执行,比如我测试的某大型黑客网站,虽然xm.php上传成功了,但被禁止执行了:

10.jpg

0x05 附加篇:怎么找到使用phpcms的网站 {#0x05-phpcms}

我前两篇都有这个栏目,因为大家处在web安全初期,平时要多练手,所以可以找一些网站进行实战。

phpcms是一个大型的cms,用的人很多,基本上是以万计数,所以找起来很容易。

直接百度 powered by phpcms即可:

09.jpg

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

赞(5)
未经允许不得转载:工具盒子 » phpcms上传导致getshell详解及案例