首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >目录穿越漏洞修复之后再利用

目录穿越漏洞修复之后再利用

作者头像
信安之路
发布2019-11-26 14:45:34
1.8K0
发布2019-11-26 14:45:34
举报
文章被收录于专栏:信安之路信安之路

前段时间看到安全狗海青实验室发的一篇关于压缩文件解压导致 getshell 的文章。其中一个漏洞是在 zzzcms1.73 版本。而这款 CMS 自己也算是审过几次,虽然小众,但的确是学习审计的好例子~

安全狗的文章中介绍了 zzzcms 的后台由于上传时存在目录穿越,可以上传到任意路径下,再配合后台解压的功能,就完成了 webshell 的植入。有意思的是,上传功能做了相对严格的后缀检测,而解压功能也只能解压指定文件夹里的压缩包文件,两个功能其实各自都不存在什么大问题,而却因为目录穿越问题导致两个功能点串联在一起,从而完成了 getshell。具体细节可以去看看原文《文件解压引发的 getshell》

目录穿越的助攻

在 zzzcms 的官网上看到做了更新,并且修补了上面提到的漏洞。

下载了最新版的源码,试图绕过修补。然鹅,在尝试数次后,无果。于是,转而看看其他代码。因为之前出现过目录穿越的问题,那么很可能在其他也存在相同的问题。简单翻阅以后,看到如下代码。

很显然,在 69 行我们可以控制一个变量,而这个变量参与了一个路径的构造,因此我们可以控制这个路径跳转到任意目录。而在 78 行处调用了 simplexml_load_file 进行解析 XML,而并没有禁用引用外部实体,所以如果控制了 plug.xml 里的内容,就可以造成一个 XXE 漏洞。

为了控制 plug.xml 文件的内容,需要找到上传功能处。有意思的是,尽管上传功能的目录穿越已经被修补了无法利用,但是这里却存在目录穿越的问题,所以只要上传一个 plug.xml 文件,再控制解析 XML 文件的路径即可完成 XXE。而大多数的上传文件功能都会把文件进行重命名,找到上传功能的代码,如下:

function upload( $file, $type, $folder, $format = NULL, $max_width = NULL, $max_height = NULL ) {
  if ( isset( $file ) ) {
    $files = $file;
  } elseif ( !isset( $_FILES[ $file ] ) ) {
      $files = $_FILES[ $file ];
    } else {
      return array();
    }
    // 定义允许上传的扩展
  if ( !isset( $type ) ) {
    return array( 'state' => '上传类型不能为空' );
  } else {
    switch ( $type ) {
      case 'file':
        $array_ext_allow = explode( ',', Conf( 'fileext' ) );
        $format = Conf( 'fileformat' );
        break;
      case 'video':
        $array_ext_allow = explode( ',', Conf( 'videoext' ) );
        $format = Conf( 'videoformat' );
        break;
      case 'image':
        $array_ext_allow = explode( ',', Conf( 'imageext' ) );
        $format = Conf( 'imageformat' );
        break;
      default:
        $array_ext_allow = explode( ',', strtolower( $type ) );
        break;
    }
  }
  if ( !$files[ 'error' ] ) {
    $upfile = $files[ 'name' ];
    $file_arr = explode( '.', $upfile );
    $file_ext = safe_word(strtolower( end( $file_arr )),'4');        
    $file_name = str_replace( '.' . end( $file_arr ), '', $upfile );
        if(empty($file_ext)) {
            return array( 'state' => '上传类型不能为空!' );
        }elseif ( in_array( $file_ext, array('php','asp','aspx','exe','sh','sql','bat') ) ) {
      return array( 'state' => $file_ext.'格式的文件不允许上传,请重新选择!' );
    } elseif ( !in_array( $file_ext, $array_ext_allow ) ) {
      var_dump($file_ext);
      return array( 'state' => $file_ext . '格式的文件不能上传,请重新选择!');
    }
    $savefile = array( 'state' => 'SUCCESS', 'ext' => $file_ext, 'title' => $file_name, 'url' => handle_upload( $files[ 'name' ], $files[ 'tmp_name' ], $array_ext_allow, $folder, $format, $file_name, $file_ext, $max_width, $max_height ) );
    return $savefile;
  } else {
    return $files[ 'error' ];
  }
}

上面的 代码看到用黑名单限制了后缀名,显然这个黑名单是不严格的,随意上传 php5 这类后缀。检查完后缀之后就来到了 handle_upload 函数,这个函数的主要功能就是将文件进行保存。代码如下:

function handle_upload( $file, $temp, $array_ext_allow, $folder, $format, $file_name, $file_ext, $max_width, $max_height ) {
  // 检查文件存储路径
  if ( conf( 'datefolder' ) == 1 ) {
    $save_path = SITE_DIR . conf( 'uploadpath' ) . $folder . '/' . date( 'Ymd' );
    check_dir( $save_path, true );
  } else {
    $save_path = SITE_DIR . conf( 'uploadpath' ) . $folder;
    check_dir( $save_path, true );
  }
  if ( $format == 'pinyin' ) {
    $newname = pinyin( $file_name );
  } elseif ( $format == 'yuanming' ) {
    $newname = toutf( $file_name );
  } else {
    $newname = time() . mt_rand( 100000, 999999 );
  }
  $file_path = $save_path . '/' . $newname . '.' . $file_ext;
  if ( is_file( $file_path ) ) {
    if ( conf( 'covermark' ) == 1 ) {
      del_file( $file_path );
    } else {
      $file_path = $save_path . '/' . $newname . mt_rand( 1000, 9999 ) . '.' . $file_ext;
    }
  }
  move_uploaded_file( $temp, $file_path ); // 从缓存中转存  
  $save_file = str_replace( SITE_DIR, SITE_PATH, $file_path );
  if ( $format == 'yuanming' )$save_file = togbk( $save_file );
  // 如果是图片进行等比例缩放
  if ( is_image( $file_path )) {
    resize_img( $file_path, $file_path, 0, Conf( 'compresswidth' ), Conf( 'compressheight' ),Conf( 'compressquality') );
  }
  return $save_file;
}

文件名是否随机取决于变量 $format,当 $format 的值为 pinyin 时,则就保存为原文件名。因此,已经可以通过上传一个 plug.xml 来控制 XML 解析的内容。

利用

为了方便验证漏洞,在 C 盘下建立一个目标文件,内容如下。

利用漏洞:

首先先准备一个 plug.xml 文件用于上传。

然后准备一个 a.dtd 文件,放在可控服务器的 web 目录下,

然后编写一个上传页面,

将文件上传

然后触发 XXE 漏洞

POST:

http://127.0.0.1/zzzphp/admin/save.php?act=plugkey
plugpath=../upload/file&plugkey=e10adc3949ba59abbe56e057f20f883e

查看 web 日志,可以发现 flag.txt 的内容被携带的传送到了服务器上。

最后

目录穿越其实只是个小问题,有种打辅助的感觉。就像这个漏洞,如果禁用了外部实体,同样也不能进行 XXE,不过也正是因为目录穿越,这个 XXE 才可以被利用。一直以来分享的文章都很基础很简单,充其量只是个入门的水平,让各位大佬见笑了。:)

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 信安之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 目录穿越的助攻
  • 利用
  • 最后
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档