aj-report 二次就业
前提
 最新先知有人发了aj-report文章,看了看,是一个filter绕过,还有jwt,竟然还没修,这是两年前发表的AJ-Report_RCE。aj-report是我两年前学习代码审计审计的第一套代码,那时候藏了一些洞没写,所以现在重新看一看。 环境v1.4.1。
0x01 filter 绕过
com.anjiplus.template.gaea.business.filter.TokenFilter.java

这获取了URL,然后判断是否包含“swagger-ui”或着”swagger-resources”,包含直接放行。
没什么好说的,鉴权绕过。
0x02 sql 信息泄漏
com.anji.plus.gaea.curd.controller.GaeaBaseController#pageList

直接查询dataSource的信息,然后把Dto信息全部直接放回,造成泄漏


Dto里面存在Collections集合,直接把配置信息放回出来。

结合一下,可以拿到数据库账号密码
1  |  | 
0x03 js执行命令
 参考两年前发表的AJ-Report_RCE,(https://mp.weixin.qq.com/s/HsH_nEI5SyOP_Y9Qbm0A1w)
没有修复。
第一个点 (validationRules参数校验点)
com.anjiplus.template.gaea.business.modules.dataset.service.impl.DataSetServiceImpl#testTransform

看方法实现


然后执行。
第二个点(js脚本)
com.anjiplus.template.gaea.business.modules.datasettransform.service.impl.JsTransformServiceImpl#getValueFromJs.java



这里两个地方都可以,也根本不用绕过。
1  |  | 
0x04 validationRules 命令执行
com.anjiplus.template.gaea.business.modules.datasetparam.controller.DataSetParamController#verification。java
其实看上面就知道,js的规则,然后走到eval。

com.anjiplus.template.gaea.business.modules.datasetparam.service.impl.DataSetParamServiceImpl#verification(com.anjiplus.template.gaea.business.modules.datasetparam.controller.dto.DataSetParamDto)

对应实现类,有绕过,套娃就行。
dto里面设置validationRules就行。

1  |  | 
0x05 zip-spilf
com.anjiplus.template.gaea.business.modules.dashboard.controller.ReportDashboardController#importDashboard.java

对应的controller,传file流何code就好
com.anjiplus.template.gaea.business.modules.dashboard.service.impl.ReportDashboardServiceImpl#importDashboard 实现类


没有的zipEntry进行../ 过滤,导致zip目录穿越。


然后ssh 指定私钥连接。
0x06 大屏分享信息泄漏
com.anjiplus.template.gaea.business.modules.reportshare.controller.ReportShareController#detailByCode

对象实现类

根据shareCode可以获取到查询信息,然后加密后直接放回

jwt可以直接解密

直接可以获得分享密码。
0x07 java代码执行
 还是数据集那个点,走java方式。
com.anjiplus.template.gaea.business.modules.dataset.service.impl.DataSetServiceImpl#testTransform

对应实现类
com.anjiplus.template.gaea.business.modules.datasettransform.service.impl.DataSetTransformServiceImpl#transform

com.anjiplus.template.gaea.business.modules.datasettransform.service.impl.GroovyTransformServiceImpl#transform

最后会来到GroovyClassLoader,进行处理,也就是我们写一个类给GroovyClassLoader加载就好了
1  |  | 

能写代码,那就打下内存马吧。
1  |  | 

成功.
0x08 jwt 绕过登录
com.anjiplus.template.gaea.business.modules.accessuser.service.impl.AccessUserServiceImpl#login

com.anji.plus.gaea.utils.JwtBean#createToken(java.lang.String, java.lang.String, java.lang.Integer, java.lang.String)

com.anji.plus.gaea.GaeaProperties.Security#jwtSecret
这里密钥是写在依赖包下,无法修改

这一块得修改一下

jwt验证只校验用户名,这边key没法改,随便伪造
具体参考(https://mp.weixin.qq.com/s/HsH_nEI5SyOP_Y9Qbm0A1w)
0x09 sql问题
 本质是没做用户权限校验,导致任何人都能操作,由于有filter绕过,就写出来吧
com.anjiplus.template.gaea.business.modules.dataset.service.impl.DataSetServiceImpl#testTransform
还是这个点

从DTO里面获取参数,然后查询
1  |  | 

也就是可以直接利用sql修改账号密码。
修复意见
接口健全确实,主要靠filter,一些重要的接口,权限缺失,如/dataSource、/dataSet下的接口,匿名用户也可以操作,filter建议直接使用getServletPath(),或者重写一下。
jwt的认证密钥是写在依赖包里面,无法修改.
返回包里面的DTO,把敏感字短执行加密。
声明
此文章 仅用于教育目的。请负责任地使用它,并且仅在您有明确测试权限的系统上使用。滥用此 PoC 可能会导致严重后果。