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 可能会导致严重后果。