weblogic远程调试和T3反序列化简单分析

最近一直在学习cc链,总感觉学了但是又好像没学,于是想着复现cve来了解一下这些链子的实际使用。在复现的过程中,突然想仔细分析一下它exp的攻击流量,后面发现这个流量似乎使用反序列化去触发rmi连接恶意服务器,但是这里rmi的了解也不是很深,遂简单记一下idea远程调试的配置和t3中一些数据的分析。

自行搭建

GitHub - QAX-A-Team/WeblogicEnvironment: Weblogic环境搭建工具

1
2
3
4
5
6
7
构建镜像
docker build --build-arg JDK_PKG=jdk-7u21-linux-x64.tar.gz --build-arg WEBLOGIC_JAR=fmw_12.1.3.0.0_wls.jar -t weblogic:v1 .


运行
docker run -d -p 7001:7001 -p 8453:8453 -p 5556:5556 --name weblogic we

然后需要使用docker命令将需要调试的目录从虚拟机复制出来,然后作为依赖引入,就可以调试了。

vulhub_weblogic的idea调试

首先在docker-compose.yml添加一个端口映射,这个端口映射是用来debug连接的。
然后启动容器,进入容器;
进入

1
2
/root/Oracle/Middleware/user_projects/domains/base_domain/bin

然后在setDomainEnv.sh中添加

1
2
3
debugFlag="true"
DEBUG_PORT=44444
export debugFlag

然后回到宿主机重启docker

1
2
3
sudo service docker restart

docker-compose up -d

然后进入docker将需要的文件复制出来。

1
docker cp 镜像名:/root/Oracle ./

这里复制整个就可以,然后通过find命令将其中的jar包提取出来即可。但是这一步我不是很理解,按理来说可以直接将想要查看断点的文件add as lib即可查看,这样会比较方便,但是包不完整。获取上面这一步就是为了解决包不完整的问题吧。
具体操作流程如图:
image.png

然后从外面就可以看到test中的所有jar包可以直接查看了。
image.png

当然也可以图方便直接将需要看的jar包进行下图操作,这样就可以直接在项目文件夹中查看了。
image.png

最后只需要配置一下远程调试即可

image.png

因为我这里在之前docker-compose中设置的是44444端口,所以这里就是虚拟机ip加这个端口即可。
然后调试,因为我这里是cve-2018-2628所以我就找了个漏洞的调用栈中的函数断一下。
image.png

发送paylaod就会发现被断下来了。
这里可以参考我们jrmp服务器上设置的payload然后根据使用的攻击链在对应的函数执行点下断点,然后发送paylaod即可,这里我们使用的是cc1的攻击链,所以直接断在transform相关函数即可看到全部的调用栈了。但是如果想要查看t3的实际连接过程就不能断在这里,因为实在找不到调用栈在哪层调用栈。最好是直接定位到
image.png

简单分析

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
26
27
28
void init(Chunk var1, MsgAbbrevJVMConnection var2) throws ClassNotFoundException, IOException {  
super.init(var1, 4);
this.connection = var2;
this.responseId = -1;
this.user = null;
this.header.readHeader(this, var2.getRemoteHeaderLength());
if (this.connectionManager.thisRJVM != null) {
this.header.src = this.connectionManager.thisRJVM.getID();
}

this.header.dest = JVMID.localID();
if (KernelStatus.DEBUG && debugMessaging.isDebugEnabled()) {
}

this.mark(this.header.abbrevOffset);
//这里会跳过很长一段字节,但是原因不是很清楚,但是它刚好跳到了fe01这个位置,这是每个反序列化数据流的前缀,应该算是加了T3特征的反序列化流
this.skip((long)(this.header.abbrevOffset - this.pos()));
var2.readMsgAbbrevs(this);
this.reset();
if (JVMID.localID().equals(this.header.dest)) {
if (!this.header.getFlag(8)) {
this.read81Contexts();
} else {
this.readExtendedContexts();
}
}

}

当然喽,虽然我觉得能定位到握手包那里然后一路跟进才是最好的。但是自己实力实在不是很行,看底层通信的实现实在有点费劲,只好定位到网上师傅们说的位置了。这里就是对t3流量进行解析的地方,首先他会初始化一些变量,例如header和pos等参数,这里的pos是用来观测该数据流在代码中解析的重要依据。

数据解析的第一步:

  • 初始化变量
  • 跳过表示长度的四个字节

image.png
然后就是readHeader这个函数,通过读取流来完善连接信息(这些信息并不是反序列化数据,而是在后续代码中还要作为处理依据的标志)
具体的含义可以参考:这位大佬的文章
image.png

然后这里readByte是读取消耗一个字节,readInt则是四个,readInt中的具体操作是依次从字节流中读取四个字节然后进行左位移操作,不是很懂,但是只知道很牛逼。因为得到的abbrevOffset值,是从连接信息(header)到真正需要反序列化的数据间的距离。

image.png

然后就是走完上述流程就会进去InboundMsgAbbrev#readMsgAbbrevs,开始真整的反序列化过程。依次进入同一个类中的read和readObject,最后在

1
2
3
4
5
6
7
8
9
10
11
private Object readObject(MsgAbbrevInputStream var1) throws IOException, ClassNotFoundException {  
int var2 = var1.read();
switch (var2) {
case 0:
return (new ServerChannelInputStream(var1)).readObject();
case 1:
return var1.readASCII();
default:
throw new StreamCorruptedException("Unknown typecode: '" + var2 + "'");
}
}

进入在这里的case0中进入正式反序列化。这里本来是想继续分析的,但是仔细看了一下,发现在没有连接JRMP服务端时,打的就是cc1,使用rmi服务去请求我设置好的JRMP服务端,这就是exp所作的事。因为想做流量分析但是对rmi了解不是很深刻,所以打算后续深入学习一下rmi后再一并进行流量的分析。


weblogic远程调试和T3反序列化简单分析
http://example.com/2024/04/14/weblogic远程调试和T3数据简单分析/
Author
ghh
Posted on
April 14, 2024
Licensed under