0x00前言上一篇《Zimbra漏洞调试环境搭建》提到了通过反射枚举JspServletWrapper实例的实现,本文将以此为例详细介绍实现的思路和细节,从而可以类推,实现其他功能。0x01简介本文将介绍以下内容:?反射中的常用操作?获取类的所有字段?获取类的所有方法?调用类的方法?枚举JspServletWrapper实例的实现细节0x02反射中的常用操作1.获取类所有字段getField():可以获取该类中的公共字段和父类getDeclaredField():可以获取该类中的所有字段这里以Zimbra环境为例,给出示例代码(一)获取请求对象的所有字段(2)获取请求对象父类的所有字段2.获取类的所有方法类中的所有方法,包括private、protected、default和public方法这里,取以Zimbra环境为例,给出示例代码(1)获取请求对象的所有方法(2)获取请求对象的父类的所有方法3.调用类的指定方法。这里我们以Zimbra环境为例,给出示例代码。Zimbra漏洞调试环境搭建完成后,定位到请求对象的getHeader(Stringname)方法。代码细节如下:对比代码细节,参数类型为String调用请求对象。getHeader(Stringname)方法,参数为“User-Agent”,实现代码如下:0x03枚举JspServletWrapper实例的实现细节1.在下一个断点选择文件servlet-api-3.1.jar,并选择javax.servlet->http->HttpServlet.class,在合适的位置打断点,运行到断点处,可以查看到request对象的完整结构,如下图查看结构request对象,我们最终定位到了JspServletWrapper实例的位置,直观的映射是:request->_scope->_servlet->rctxt->jsps接下来,我们需要按照这个映射,通过多次反射最终得到JspServletWrapper实例(1)读取request对象的所有字段,在回显结果中找到_scope(2)从request对象中获取_scope实例,再次枚举字段。在回显结果中,可以找到_servlet(3)获取_servlet实例,再次枚举字段。回显结果为:serialVersionUID这里没有rctxt字段。尝试查找原因:打开调试器,定位关键位置,从下图可以看出,_servlet的类是JettyJspServlet,JettyJspServlet继承自JspServlet,成员变量只有serialVersionUID,与我们的结果一致通过访问jsp页面获得。查看JspServlet的相关实现代码,如下图,rctxt是JspServlet的成员变量,属性是private的,所以子类JettyJspServlet不能继承成员变量rctxt,这里直接选择父类即可_servlet实例枚举字段(4)选择_servlet实例的父类枚举字段在回显结果中可以找到jsps(5)获取jsps实例并枚举字段打开调试器,检查类型jsps,如下图,jsps的类是ConcurrentHashMap,这里只需要枚举所有的key添加需要导入的包,然后得到最终的实现代码:补充:删除指定的JspServletWrapper实例,只需要调用ConcurrentHashMap的remove方法即可示例代码:0x04总结本文介绍通过refle枚举JspServletWrapper实例的具体实现动作,记录思路和细节,便于类比修改其他内容
