Tomcat半通用回显分析

admin 2022年5月21日16:26:44评论31 views字数 2398阅读7分59秒阅读模式

Tomcat半通用回显分析

扫一扫关注公众号,长期致力于安全研究Tomcat半通用回显分析


0x01 前言

最近一直在看回显相关的东西,相当于是本人的笔记分享一下。如有误请及时指正~

2020年3月kingkk师傅提出一种基于调用栈中获取Response对象的方法,该方法主要是从ApplicationFilterChain中提取相关对象,因此如果对Tomcat中的Filter有部署上的变动的话就不能通过此方法实现命令回显。


0x02 分析

首先可以看到,在ApplicationFilterChain中,发现了存储request和response的变量

Tomcat半通用回显分析


但在其对象中,有一个static方法调用,主要是对上方的的变量做初始化用,但断点分析可以发现,ApplicationDispatcher.WRAP_SAME_OBJECT为false,所以变量就会赋值为null。

Tomcat半通用回显分析


所以的话整体思路如下:
        1. 将ApplicationDispatcher.WRAP_SAME_OBJECT通过反射修改为true
            2. 存储request和response的两个变量进行初始化(这里为什么初始化后面会将)
            3.从lastServicedResponse获取response并最终进行回显内容            


0x03 代码实现

      代码如下,其实是非常简单的。

public class Myservlet extends HttpServlet {    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {        try{            Field WRAP_SAME_OBJECT_FIELD = Class.forName("org.apache.catalina.core.ApplicationDispatcher").getDeclaredField("WRAP_SAME_OBJECT");            Field RequestField = ApplicationFilterChain.class.getDeclaredField("lastServicedRequest");            Field ResponseField = ApplicationFilterChain.class.getDeclaredField("lastServicedResponse");
//取消Final属性 Field modifiersField = Field.class.getDeclaredField("modifiers"); modifiersField.setAccessible(true); modifiersField.setInt(WRAP_SAME_OBJECT_FIELD,WRAP_SAME_OBJECT_FIELD.getModifiers()&~Modifier.FINAL); modifiersField.setInt(RequestField,RequestField.getModifiers()&~Modifier.FINAL); modifiersField.setInt(ResponseField,ResponseField.getModifiers()&~Modifier.FINAL);
WRAP_SAME_OBJECT_FIELD.setAccessible(true); RequestField.setAccessible(true); ResponseField.setAccessible(true);
//获取ServletRequest和ServletResponse 用作后面的回显 ThreadLocal<ServletRequest> requests = (ThreadLocal<ServletRequest>) RequestField.get(null); ThreadLocal<ServletResponse> responses = (ThreadLocal<ServletResponse>) ResponseField.get(null);
//如果为null,则通过反射进行初始化 if(requests==null || responses==null){ WRAP_SAME_OBJECT_FIELD.set(null,true); RequestField.set(null,new ThreadLocal<>()); ResponseField.set(null,new ThreadLocal<>()); }else{ responses.get().getWriter().write("By Met32"); }
}catch(Exception e){ e.printStackTrace(); } }}
        这里有一个小问题,既然26行已经设置为true,为什么27-28行还需要对变量进行初始化呢?
            断点跟一下,在初始化之后,是有一处判断。如果未初始化这两个变量的话,那么肯定会是刚开始的null。所以在进行调用set的时候,就会造成异常
       if (ApplicationDispatcher.WRAP_SAME_OBJECT) {                    lastServicedRequest.set((Object)null);                    lastServicedResponse.set((Object)null);              }

Tomcat半通用回显分析


那么来验证一下,首先将set进行注释

Tomcat半通用回显分析

可以看到是为null的

Tomcat半通用回显分析


最终效果如下

Tomcat半通用回显分析


0x04 结尾

为什么说是半回显呢,因为在shiro反序列化中,这个方法是行不通的。

11111
微信搜索关注 "安全族" 长期致力于安全研究


下方扫一下扫,即可关注Tomcat半通用回显分析

Tomcat半通用回显分析






原文始发于微信公众号(安全族):Tomcat半通用回显分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年5月21日16:26:44
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Tomcat半通用回显分析http://cn-sec.com/archives/1034053.html

发表评论

匿名网友 填写信息