下载补丁后可以看到只有两个module发生了改变
权限绕过
和18beta1比对后发现common/mode.php
有一处改动
由echo
=>die
,看其所在函数名为checkPriv
,推测其为权限绕过的补丁
在index.php
中调用了其函数,没修复前的echo
则对执行流程没有影响,会继续向下执行。
再来看下checkPriv
函数有哪些操作,
大概流程就是获取调用模块的名字和方法,定义了一些不需要权限的白名单调用方法
如果存在$this->app->user
变量则将session
中的user
赋值给$this->app->user
检查用户如果没有调用功能的权限则进入到deny
函数,最后抛出异常,而在catch
里仅仅是输出了异常并没有终止流程。
重点就是$this->app->user
怎么获取到
commonModel#__construct->commonModel#setUser
可以看到$this->app->user
获取有两种方式
- 从
session
中获取 - 如果开启了匿名访问或是从终端访问则会设置
session
匿名访问默认是关闭状态的所以利用有限
现在来看下$this->session->user
怎么获取
搜索一下发现在module/misc/control.php
中函数captcha
中session名可控
获取到session后访问下后台接口试下
验证成功
GetShell or RCE
现在再来看下另一个patch的module
发现是对sql语句做了预处理,那么这里的应该就是存在sql注入,因为zentao的数据库使用的pdo所以可以多语句执行。
sql注入怎么到rce呢,在这里猜测下
- 多语句执行可以在知道web的绝对路径下写入shell
- 结合其他功能进行操作
SQL To Shell
导出shell前提条件是,绝对路径在sql报错时已经爆出来了,还有一个条件是secure_file_priv
没有设置值
docker起一个官方镜像docker pull easysoft/zentao:18.0.beta1
满足利用条件。
Cron to RCE
如果secure_file_priv
被设置为NULL或其他值,则无法导出shell,那么怎么解决呢,粗略看了下后台的其他功能发现有一处计划任务存在利用。module/cron/control.php#ajaxExec
大致流程:
遍历zt_cron
表中的状态不为nostop
的数据,如果数据中type
为system
则直接执行命令
但是在创建计划任务时会对type
进行检测如果为system
则返回错误
那么要执行命令需要将新增的计划任务type
修改为system
,结合上面的SQL注入即可实现。
创建计划任务
修改type
执行命令
等待触发
在日志中看到成功触发