专栏首页信安之路目录穿越漏洞修复之后再利用

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

前段时间看到安全狗海青实验室发的一篇关于压缩文件解压导致 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 才可以被利用。一直以来分享的文章都很基础很简单,充其量只是个入门的水平,让各位大佬见笑了。:)

本文分享自微信公众号 - 信安之路(xazlsec),作者:Z1NG

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-11-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • A站被黑-安全负责人们颤抖吧

    今天安全圈的一件大事,Acfun.cn 也就是大家简称的 A 站被黑了,数据库被人拖库并且在暗网兜售,售价 40万 元,截图如下:

    信安之路
  • 使用 Wave 文件绕过 CSP 策略

    CSP 全称 Content Security Policy,即内容安全策略。CSP 是一个额外的安全层,用于检测并削弱某些特定类型的攻击,包括 XSS 和注入...

    信安之路
  • 代码安全之文件包含

    PHP文件包含漏洞的产生原因是在通过PHP的函数引入文件时,由于传入的文件名没有经过合理的校验,从而操作了预想之外的文件,就可能导致意外的文件泄露甚至恶意的代码...

    信安之路
  • 研究人员如何使用Shhgit搜索GitHub中的敏感数据

    Shhgit能够帮助广大研究人员以近乎实时的方式寻找GitHub(包括Gists)、GitLab和BitBucket提交代码中的敏感数据和敏感文件。实际上,在G...

    FB客服
  • uni app 零基础小白到项目实战

    若本号内容有做得不到位的地方(比如:涉及版权或其他问题),请及时联系我们进行整改即可,会在第一时间进行处理。

    达达前端
  • file命令

    file命令用来探测给定文件的类型,file命令对文件的检查分为文件系统、魔法文件和语言检查3个过程。

    WindrunnerMax
  • Uploads-labs上传绕过(上)

    链接:https://pan.baidu.com/s/1lMRBVdQyFuKOgNlWPUoSSQ

    字节脉搏实验室
  • python3第七天(输入和输出)

    输出值的方式:1,表达式。2,print()函数。3,文件对象的write()函数

    py3study
  • 前端零基础入门:页面结构层HTML(2)

    达达前端
  • Linux shell ${}简单用法

    Linux shell ${}简单用法 [转]http://linux.chinaunix.net/techdoc/develop/2007/05/05/9...

    汤高

扫码关注云+社区

领取腾讯云代金券