Tapestry4 RCE分析

    渗透测试 lz520520 7个月前 (04-29) 250次浏览

    前言

    遇到有人问起这个漏洞,我去查了下Tapestry 4,这尼玛在2008年就停止更新了,现在是5,这算是一个上古时代的框架了,他类似于springMVC,也是有一个特殊的servlet做请求处理分发。

    基本找不到这个漏洞的分析,只有一段关于该漏洞的描述( 2020年12月8),source是sp参数,sink看描述应该是readObject
    https://lists.apache.org/thread/mcl3xzw50vjb7rv76nsgq5zorhbg5gyy

    在 Apache Tapestry 4 中发现了一个 Java 序列化漏洞。Apache Tapestry 4 甚至会尝试反序列化“sp”参数在调用页面的 validate 方法之前,导致反序列化无需身份验证。

    Tapestry4 RCE分析

    环境搭建

    要测试漏洞,得找个环境,这里搜了一篇文章,顺利搭建成功
    https://blog.csdn.net/lovebunny/article/details/83222881
    几个注意事项吧

    1. Tapestry4 在 github有份源码,但我用mvn死活编译不出来,幸好maven仓库有,项目直接引用就行了。
      1. https://mvnrepository.com/artifact/org.apache.tapestry/tapestry-framework/4.1.6
    2. 因为类似springMVC,可以用tomcat、resin等容器部署,我选择了tomcat,web.xml如下

    <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee&quot; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance&quot; xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"&gt;
    <servlet>
    <servlet-name>ApplicationServlet</servlet-name>
    <servlet-class>org.apache.tapestry.ApplicationServlet</servlet-class>
    </servlet>
    <servlet-mapping>
    <servlet-name>ApplicationServlet</servlet-name>
    <url-pattern>/app</url-pattern>
    </servlet-mapping>
    </web-app>

    Tapestry4 RCE分析
    这篇文章有提到一些 https://blog.csdn.net/CSDN__Java/article/details/49100277,这里用的service是page
    Tapestry4 RCE分析

    再仔细看看/app?service=external&sp=[param 0]对应的刚好是类名前缀小写,是IEngineService接口的实现
    Tapestry4 RCE分析

    这个接口有很多实现类,包括page啥的
    Tapestry4 RCE分析
    尝试构造访问,可以看到和我们默认访问的页面是一样的,说明默认就是PageService请求。
    Tapestry4 RCE分析
    而service=external也其实可以访问到ExternalService
    Tapestry4 RCE分析
    这里提示home未实现IExternalPage
    Tapestry4 RCE分析
    因为我Home.class是IPage的实现,正常开发external服务,就实现IExternalPage即可
    Tapestry4 RCE分析

    接口的描述,getLink主要用于构建一个service的URL,而service方法就是处理请求,并返回一个page。
    Tapestry4 RCE分析

    ExternalService在getLink里有获取sp参数,但只是构造link,而service里却没看到获取sp参数的代码

    Tapestry4 RCE分析
    看了下这个代码内部实现

    内部是有sp参数获取的。(上面说是用PARAMETER,这里是找的编译好的jar包,所以是sp)
    Tapestry4 RCE分析

    关于sp参数的调用,大概搜了下源码,先排除getLink里的

    tabby搜索

    用tabby搜索一下调用

    有几个IEngineService实现类是有调用的

    Tapestry4 RCE分析

    具体代码看了下如DirectService也是如此调用
    Tapestry4 RCE分析

    然后就可以进一步搜索extractListenerParameters方法是否有进一步的利用,如下搜索,可以发现确实有一条调用readObject的调用链。
    PS: 这里用ALIAS避免一些接口实现调用的问题,可以看到如下确实有接口实现问题,没有ALIAS是找不到完整利用链的。

    Tapestry4 RCE分析
    调用链打印如下,最终是在SerializableAdaptor里调用了readObject

    利用链构造

    对于传入的encoded,base64解码直接反序列化,接下来就看是否可以触发利用了。
    Tapestry4 RCE分析

    上面三个source,找一个比如DirectService.class,如下,想走到extractListenerParameters,那么他对应的page页面中,应该存在IDirect组件,component是tapestry里的一个概念,是一组特殊的标签,用来动态生成页面。
    Tapestry4 RCE分析

    如下jwcid里就设置了组件类型,内置的几个常用组件有@PageLink@DirectLink@Insert@Form,这里没有指定组件名,一般格式是test@DirectLink,那么组件名就是test,下面例子是匿名组件,需要调用的话,传参如component=$Form
    Tapestry4 RCE分析

    而DrectService需要的组件类型必须是实现了IDirect,如下Form和DirectLink都行。
    Tapestry4 RCE分析
    尝试传参service=direct&sp=123&page=Form&component=%24Form,成功进入下面。
    Tapestry4 RCE分析
    进一步到如下位置,这个函数就是对参数解码的,可以看到他会根据首字母-33来判断使用哪个adaptor进行解码
    Tapestry4 RCE分析

    我们需要的SerializableAdaptor也是其中一个,所以接下来就需要知道this._adaptorByPrefix哪个索引对应的是SerializableAdaptor
    Tapestry4 RCE分析
    如下46和57对应的就是SerializableAdaptor,也就是传入79=O或90=Z
    Tapestry4 RCE分析
    为啥有两个值其实之前已经提示了,传入Z则会进行GZIP解压,O则只是Base64
    Tapestry4 RCE分析

    接着就可以构造反序列化数据了,先看下默认依赖,可以看到里面有commons-beanutils,如此甚好。
    Tapestry4 RCE分析

    这里不用GZIP,简单Base64编码,发送,触发利用,进一步回显、内存马就是一些常规操作了。
    Tapestry4 RCE分析

    利用条件

    上面只测试了DirectService的Form组件,其实sp想要正确传参,Form组件需要设置允许提交String类型,否则会存在sp转换报错。
    总结下
    DirectService

    1. 页面中存在Form或DirectLink组件,也就是jwcid设置,并且知道componentId
    2. 组件设置允许用户输入String类型数据

    那么黑盒如何找Form这种页面了,其实这种页面很正常,在Tapestry里,遇到表单提交的场景,基本都是用的Form,比如我本地测试的
    Tapestry4 RCE分析
    再看一下html代码,有几个hidden的属性,根据seedids、component这些就能确认目标是否使用了Form,并且可以根据这个判断是Tapestry
    Tapestry4 RCE分析

    总结

    这个洞其实看分析,调用链比较明显,但其实蛮多坑的,最开始自己搭建Tapestry环境,存在不少问题,Form组件要能够接收用户输入,这个还是找了个demo才搞定的。
    最开始分析这个洞的时候,没有补丁也没有分析,调了一会没耐心就放弃了,害不知道是不是太晚了、还是因为项目没结束,总感觉太急躁了,其实仔细看看他的使用文档,应该能很快找到sp参数的利用,棋差一步,搞研究还是得静下心来。

    还有tabby还是蛮好用的,之前没发现利用链也是因为忘了ALIAS,算是又学习了一些cypher的使用技巧吧。之前使用tabby太过粗糙,因为他还没有污点跟踪,所以不能完全依赖他做分析,像这个漏洞,最好手动搜索下sp参数的相关方法,这些方法是否可被路由到,这时候就需要学习应用框架,比如Tapestry里的service,然后找到sp可用方法,进一步搜索是否存在到sink(readObject)的调用链,这样就能比较快速找到利用链了。

    这个方法是在知道source的情况下去分析的,一般来说需要先人工分析sink,最好是项目里的sink(也就是对更底层sink的封装),对一些可用的项目类中的方法做提取,然后以这些方法为sink,可以大大缩小范围。然后再看端点到这些sink的调用链是否存在。
    如果找项目类中sink太麻烦,也可以先结合tabby去筛选,找到可用sink。

    补充

    关于tapestry里的一些问题,比如某个类为什么无法调试,他很可能是tapestry动态创建了你当前类的子类
    Tapestry4 RCE分析

    参考


    Security , 版权所有丨如未注明 , 均为原创丨
    转载请注明原文链接:Tapestry4 RCE分析
    喜欢 (0)