0x00 Preface
---
In the previous article 'Setting Up Zimbra Vulnerability Debugging Environment', we mentioned enumerating JspServletWrapper instances through reflection. This article will take that as an example to detail the implementation approach and specifics, facilitating extrapolation to implement other functionalities.
0x01 Introduction
---
This article will cover the following:
- Common operations in reflection
- Obtaining all fields of a class
- Obtaining all methods of a class
- Invoking class methods
- Implementation details of enumerating JspServletWrapper instances
0x02 Common Operations in Reflection
---
1. Obtaining all fields of a class
getField():
Can retrieve public fields from both this class and its parent class
getDeclaredField():
Can retrieve all fields from this class
Here is an example code using the Zimbra environment as an example
(1) Get all fields of the request object
<%@ page import="java.lang.reflect.Field" %> |
(2) Get all fields of the parent class of the request object
<%@ page import="java.lang.reflect.Field" %> |
2. Get all methods of a class
getMethods():
Can obtain public methods (modified by the public modifier) from this class as well as its parent class or parent interface
getDeclaredMethods():
Can obtain all methods in this class, including private, protected, default, and public methods
Here, using the Zimbra environment as an example, provide sample code
(1) Get all methods of the request object
<%@ page import="java.lang.reflect.Field "%> |
(2) Get all methods of the parent class of the request object
<%@ page import="java.lang.reflect.Field "%> |
3. Invoking specific methods of a class
Here, using the Zimbra environment as an example, sample code is provided
After setting up the Zimbra vulnerability debugging environment, locate the getHeader(String name) method of the request object. The code details are as follows:
public String getHeader(String name) { |
Referring to the code details, the parameter type is String
Invoke the getHeader(String name) method of the request object with the parameter "User-Agent". The implementation code is as follows:
<%@ page import="java.lang.reflect.Field "%> |
0x03 Implementation Details of Enumerating JspServletWrapper Instances
---
1. Setting Breakpoints
Select the file servlet-api-3.1.jar, then navigate to javax.servlet->http->HttpServlet.class. Set a breakpoint at an appropriate location. When execution reaches the breakpoint, you can view the complete structure of the request object, as shown in the figure below.

By examining the structure of the request object, we ultimately located the position of the JspServletWrapper instance. The intuitive mapping is: request->_scope->_servlet->rctxt->jsps
Next, we need to follow this mapping and obtain the JspServletWrapper instance through multiple reflections.
(1) Reading all fields of the request object
<%@ page import="java.lang.reflect.Field" %> |
Find _scope in the echoed results
(2) Obtain the _scope instance from the request object and enumerate its fields again
<%@ page import="java.lang.reflect.Field" %> |
Find _servlet in the echoed results
(3) Obtain the _servlet instance and enumerate its fields again
<%@ page import="java.lang.reflect.Field" %> |
The echo result is: serialVersionUID
There is no rctxt field here
Attempting to find the cause: Start the debugger and locate the key position, as shown in the figure below

As can be seen from the figure, the class of _servlet is JettyJspServlet
JettyJspServlet inherits from JspServlet, and the only member variable is serialVersionUID, which is consistent with the results we obtained by accessing the JSP page
Review the relevant implementation code of JspServlet, as shown in the figure below

As can be seen from the figure, rctxt is a member variable of JspServlet, with a private attribute, so the subclass JettyJspServlet cannot inherit the member variable rctxt
Here we can directly select the parent class of the _servlet instance to enumerate fields
(4) Select the parent class of the _servlet instance to enumerate fields
<%@ page import="java.lang.reflect.Field" %> |
jsps can be found in the echo results
(5) Obtain the jsps instance and enumerate fields
Open the debugger and check the type of jsps, as shown in the figure below

As can be seen from the figure, the class of jsps is ConcurrentHashMap. Here, only all Keys need to be enumerated.
After adding the required import packages, the final implementation code is obtained:
<%@ page import="java.lang.reflect.Field" %> |
Note: Delete the specified JspServletWrapper instance
Simply call the remove method of ConcurrentHashMap
Example code:
<%@ page import="java.lang.reflect.Field" %> |
0x04 Summary
---
This article introduces the specific implementation of enumerating JspServletWrapper instances through reflection, documenting the approach and details to facilitate extrapolation for modifying other content.