CVE-2021-2109 Weblogic Server Remote Code Execution vulnerability analysis


1. Vulnerability background

1. Basic application of JNDI

​ JNDI is the English abbreviation of Java Naming and Directory Interface (JAVA Naming and Directory Interface). It is an API (Application Programing Interface) that provides naming and directory access services for JAVA applications.

2. The concept and application of naming

​ Naming in JNDI is to bind Java objects to a container environment (Context) in the form of a certain name, and then call the container environment (Context) lookup method to find out The Java object bound to a certain name . In a real project application, usually the system program or frame plus program first binds the resource objects to the JNDI environment, and then the module program running in the system or framework can find these resource objects in the JNDI environment. For example, the Tomcat server can create a data source (DataSource) object connected to a certain database system when it starts, and bind the data source (DataSource) object to the JNDI environment. The Servlet and The JSP program can query the data source (DataSource) object from the JNDI environment for use, regardless of how the data source (DataSource) object is created . This method greatly enhances the maintainability of the system. When the connection parameters of the system are changed, this is only a matter for the Tomcat system administrator to care about, and has nothing to do with all application developers.
​ The container environment (Context) itself is also a Java object, and it can also be bound to another container environment (Context) by a name. Bind a Context object to another Context object, which forms a parent-child cascade relationship. Multiple Context objects can eventually be cascaded into a tree structure, and each Context object in the tree can be bound Several Java objects

2. Vulnerability analysis

1. Environment setup

The shooting range adopts one-click express

The tool uses

Prepare Burpsuite and IDEA and you can happily carry out remote debugging~

2. Vulnerability debugging

You can see some initialization operations in public JndiBindingHandle(String objectIdentifier) ​​and public JndiBindingHandle(String context, String binding, String server).


Return newInstance(args) is instantiation


At this time, the value of key is _nfpb in POC,


When _nfpb does not meet the condition that the end is a handle, it comes to check whether his next bit meets the condition that the end is a handle.


At this time, _pageLable is not satisfied, then continue to check the next key JNDIBindingPageGeneral.

The condition that the end is the end of the handle is satisfied here


Going down, here is the handle object produced according to the parameters of the request request, through (Handle)ConvertUtils.convert(HttpParsing.unescape((String)queryMap.get(key), enc), Handle.class);


ObjectType needs to be filtered here


Each handle has a type, but here objectType is not null and the handle is instantiated, so there is actually no filtering here. The value of our JNDIBindingPortlethandle is stored in the handle. So in this method, any value can be passed in the key at the end of the handle.


Go in and see if the handle is not empty,


Take the 0th Component here, “ldap://xxx”


It is judged in getBinding. When the context is not empty, it returns the value of context +. +getBinding(), and getBinding() takes getComponent(1); After coming out, the value of name is

Coming to the code of JNDIBindingAction.execute, when serverMBean is not empty, the lookup function can be used.


The context, biding, and server are connected together to form the address of ldap://xxxx/classname, and the servername is AdminServer. ser


ServerName can establish Connect here, such as RMI connection

When c is not empty, c will search for context splicing’.’ splicing bindName, which is in the original POC; here is replaced with a dot


After entering the lookup function mentioned above, there is a run method, where TreeNode childNode = new TreeNode(name + “Node”, name, this.contextPath + “/consolejndi.portal?_pageLabel=JNDIBindingPageGeneral&_nfpb=true&JNDIBindingPortlethandle=” + bindingHandle, root );


After entering, the string is generated in the toString() method for format conversion and can be put in the URL.


Convert the special symbol%


The derived treeNode is /console/consolejndi.portal?_pageLabel=JNDIBindingPageGeneral&_nfpb=true&JNDIBindingPortlethandle=com.bea.console.handles.JndiBindingHandle%28%22ejb.mgmt%3BMEJB%3BAdminServer%22%29,

urldeocde is finished as /console/consolejndi.portal?_pageLabel=JNDIBindingPageGeneral&_nfpb=true&JNDIBindingPortlethandle=com.bea.console.handles.JndiBindingHandle(“ejb.mgmt;MEJB;AdminServer”) Add the generated treenode to the list


In setComponents(String[] components), you can see that the value of sb is composed of context, binding, and server. After a series of appends, the value of sb eventually becomes the structure of context; binding; server, which is ldap:/ /xxx;x/class;AdminServer


3. Vulnerability recurrence

Vulnerability recurrence