代码审计之zzzcms

前言

想想很久都没有发布代码审计的文章了,最近忙于开发任务加上最近状态不太好,哎研发dog。

这里给去中心化漏洞平台拉个广告,因为有朋友在里面工作,之前叫我去一起挖交易所漏洞,然后被狠狠打击了一波自信。

周五的时候打赌看谁挖的多,周末两天我提交了14个洞,不是撞洞就是不符合规则。而大佬呢?猛的一B,四个号全部上了10月榜单前十

有机会去北京一定要揍…吃…他一顿狠的,气啊!!!

SQL注入

版本:zzzcms php 1.5.5 181018

安装好环境后跟入口文件,至此处:

ParseGlobal(G('sid'), G('cid')); 跟进去后是这样的:

在跟进 db_load_one 方法看看:

到此凭经验来看,ParseGlobal() 方法内传递的参数会造成SQL注入,db_load_one() 方法中的130行会将 & 符号替换成 and ,而 ifnum() 方法仅是一个判断 $where 是否是整形。

接下来就是向上查找传递的 $sid、$cid ,注意到在进 ParseGlobal() 时,先用了 G() 方法,而它实践上是在获取 $GLOBALS['sid']

随后在 ParseGlobal(G('sid'), G('cid')); 的上面一行,$location = getlocation(); 中找到了 sid

下面代码的关键位置我已经加了注释说明:

可以看到,sid 是通过URL赋值的,通过 $arr1 中的 about 定位到漏洞出现位置

正常访问:http://127.0.0.1/?about/22_1

注入查询:http://127.0.0.1/?about/22&1=2_1

此时的SQL:

综合上面的东西,组合URL时不能使用 /**/ 注释来充当空格,现在让我们来爆下数据库名称:

payload:?about/22&ascii(mid(database(),1,1))=122_1

未修复的后台管理万能密码

首先搜了一下cnvd:

先看了看当前的版本是 1.5.5 ,所有想验证下这个漏洞是否被修复了。

首先找到后台登录处的代码:

用户名是 $adminname,这里的 getform() 是去 POST 中找 adminname 这个参数,如果没找到则返回 null

getform() 里面还有一个 txt_html() 转义函数,但是在这里并没有什么luan用。

可以看到有个 htmlspecialchars 函数,但设置第二个参数,导致它不会过滤单引号,然后就沦陷了。

这是正常的包:

这是SQL注入导致的万能登录包:

虽然最终弹出了一个 script,但 cookie 已经被写入,我们去前台刷新下页面就可以直接进入后台。

zzzcms_loginAdmin

原因是,当然我们绕过第一段账号密码判断的SQl后,存在一个 login_in($adminname);

可以看到,这里是一个 foreach 循环,当 $username 传入含 or 的恶意SQL时,查询出来的 $data 是多条记录。

这里存在逻辑错误,首先判断账号是否具备管理员,如果不是会 exit 退出。也就说,查出来的 $data 在前面的循环中成功写入 cookie 的一定是管理员账号。

不仅如此,这里还会输出后台所有管理员的账号。我特意去后台新增了一个账号,admintest

后台上传GETSHELL

我不怎喜欢审计后台的东西,可是已经审计到这了,那就看看有没有后台可以 getshell 的地方。

答案当然是有的,前提是你拿到的管理组有 上传设置 的编辑权限。

首先在 文件简历->上传设置->附件类型 中,加入一个php。

然后在任意文章或者内容管理页面,上传图片并抓包:

验证下:

关键代码在 inc/zzz_file.php 中的 upload() 方法,会取出我们刚才加在附件类型中的php,进行文件名后缀的白名单比对。

题外话

两个不认真工作的家伙:


版权声明

除非另有说明,本网站上的内容均根据 Creative Commons Attribution-ShareAlike License 4.0 International (CC BY-SA 4.0) 获得许可。