ZZCMS代码审计
ZZCMS代码审计
: : 最近有空,闲来无事想挖个洞提提cnvd,想要获得证书当然就得提交通用型漏洞啦!于是做了一次代码审计,洞是提了,就是不知道啥时候能过 : )
审计版本:ZZCMS 2019
漏洞发现:
白盒审计zzcms源码时,发现在uesr/adv2.php文件中第67行代码:
$rs=query("select * from zzcms_ad where id=".$_POST["id"]."");
其中变量$_POST[“id”]可被用户控制且未做过滤操作!!!(直觉告诉我,必有漏洞!冲它!!!)

逆向分析发现当62行代码查询语句:
$rs=query("select * from zzcms_ad where username='".$_COOKIE["UserName"]."' or nextuser='".$_COOKIE["UserName"]."'");
查询结果为0时才会进入66行执行危险查询语句

继续逆向分析代码发现要想执行62行代码,必须满足$a+$c==0为假,即38行代码和46行代码的查询语句:
$rs=query("select * from zzcms_zh where editor='".$_COOKIE["UserName"]."'");
至少有一个不为0,则表明网站数据库对应数据表中必须存在$_COOKIE["UserName"]传入的用户

继续逆向分析发现,以上代码都被封装在setAdv($ispay)函数中,接下来在文件中寻找调用该函数的位置

审计该页面代码发现当判断if ($action=="modify")为真时会进入下面代码块调用setAdv()函数;
首先会利用函数check_user_power("set_text_adv")检测用户是否有设置广告的权限(新用户默认为no)
然后在判断常量jifen是否为yes(新用户默认为yes);
最后才会调用setAdv()函数;

补充一下:check_user_power("set_text_adv")函数是通过$_COOKIE["UserName"]携带的用户名来查询其是否拥有对应权限并返回yes或no

最后构造攻击信息时发现会被检测,debug了一下后发现,当url框中存在siteconfig.php、label、template.php等字符串时会跳过敏感字符检测;

到这里代码分析的差不多了,归纳一下信息:
在进入user/adv2.php页面时存在一个POST或GET传输的参数,参数名为action,值为modify;该参数用来进入102行的if语句中,进入if语句中后,会调用check_user_power("set_text_adv")来查询$COOKIE["UserName"]所携带的用户是否具有权限,然后再通过switch选择对应流程,当权限为no时,常量jifen为yes也会调用setAdv()函数,这时进入到setAdv()函数中;这时会查询zzcms_main数据表和zzcms_zh数据表中是否有$COOKIE["UserName"]的数据,只要有其中一个表有就会进入到if($a+$c==0)语句中;当执行完查询数据表zzcms_ad的语句后,如果未取到值,就会进入危险代码位置,执行危险代码:
$rs=query("select * from zzcms_ad where id=".$_POST["id"]."");
这里的$_POST["id"]由用户控制且未被引号包裹,是一个典型的数字型注入点,可用联合查询语句爬取数据库;
攻击演示:
首先注册一个用户

提交一个广告
在自助广告处随便提交一个广告(不用通过审核)

发布一个展会
随便发布一个展会(不用通过审核)

此时数据表zzcms_zh和数据表zzcms_textadv存在test用户信息可以利用


构造数据包
访问/user/adv2.php并抓包,将GET请求包转为POST请求包;
构造$_POST参数:
UserName=test为满足54和64行代码的判断条件
action=modify作用为进入102行的代码执行函数
id为攻击语句,利用联合注入查找显示位
Url框中的A=siteconfig.php是为了绕过敏感字符检测
发包以后发现回显位:

可通过该注入点爬取数据库任何数据

漏洞POC:
Ps:注意一定要有存在的用户名且发布了广告和会展
1 | POST /user/adv2.php?A=siteconfig.php |





