代码审计之 zzzphp

代码审计 2019-11-10

本文作者:0x584A(信安之路作者团队成员)

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

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

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

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

SQL 注入

版本:

zzzcms php 1.5.5 181018

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

img

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

img

在跟进 db_load_one 方法看看:

img

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

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

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

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

img

img

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

img

正常访问:

http://127.0.0.1/?about/22_1

img

注入查询:

http://127.0.0.1/?about/22&1=2_1

img

此时的 SQL:

img

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

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

img

img

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

首先搜了一下 cnvd:

img

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

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

img

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

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

img

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

这是正常的包:

img

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

img

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

img

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

img

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

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

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

img

后台上传 GETSHELL

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

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

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

img

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

img

验证下:

img

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

img


本文由 信安之路 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

楼主残忍的关闭了评论