Zentao RCE
2024-10-14 08:32:30

下载补丁后可以看到只有两个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获取有两种方式

  1. session中获取
  2. 如果开启了匿名访问或是从终端访问则会设置session

匿名访问默认是关闭状态的所以利用有限

现在来看下$this->session->user怎么获取

搜索一下发现在module/misc/control.php
中函数captcha中session名可控

获取到session后访问下后台接口试下

验证成功

GetShell or RCE

现在再来看下另一个patch的module

发现是对sql语句做了预处理,那么这里的应该就是存在sql注入,因为zentao的数据库使用的pdo所以可以多语句执行。

sql注入怎么到rce呢,在这里猜测下

  1. 多语句执行可以在知道web的绝对路径下写入shell
  2. 结合其他功能进行操作

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的数据,如果数据中typesystem则直接执行命令

但是在创建计划任务时会对type进行检测如果为system则返回错误

那么要执行命令需要将新增的计划任务type修改为system,结合上面的SQL注入即可实现。

创建计划任务

修改type

执行命令


等待触发
在日志中看到成功触发

poc验证


Prev
2024-10-14 08:32:30
Next