Preventing Deserialization Attacks

Jason Shepherd

Red Hat Product Security

on Java applications

http://bit.ly/deserialize

Jason Shepherd

Software Engineer

 

  • Red Hat Product Security
  • 5 years in JBoss Tech Support
  • Java Developer Previously

Welcome to the Oracle Web sites (the "Site"). Through the Site, you have access to a variety of resources and content. These include: (a) software and software as a service offerings ("Software"); (b) Web pages, data, messages, text, images, photographs, graphics, audio and video such as podcasts and Webcasts, and documents such as press releases, white papers and product data sheets ("Materials"); and (c) forums, discussion groups, chat areas, bulletin boards, blogs, wikis, e-mail functions, and other services in connection with which you can upload, download, share, email, post, publish, transmit or otherwise access or make available Content (as defined below) ("Community Services"). Software, Materials, Community Services, and other information, content and services are collectively referred to as "Content." The following are terms of a legal agreement between you ("You" or "Your") and Oracle Corporation and its affiliated companies ("We" or "Oracle"). By accessing or using the Site or the Content provided on or through the Site, you agree to follow and be bound by the following terms and conditions concerning your access to and use of the Site and the Content provided on or through the Site ("Terms of Use") and our Privacy Policy. Oracle may revise the Terms of Use and Privacy Policy at any time without notice to you. The revised Terms of Use and Privacy Policy will be effective when posted. You can review the most current Terms of Use at https://www.oracle.com/legal/terms.html and Privacy Policy at http://www.oracle.com/legal/privacy/index.html.

Agenda

What is deserialization?

How does the exploit work?

Are we vulnerable?

How do we protect ourselves

JBoss EAP 5 Attacks

JBoss EAP 6 Attacks

What is Deserialization

Serialization in Java

  • Save an object as binary

 

 

  • Restore it as an object
public class Cake {}

1010101

public class Cake {}
  • Transfer it across the network
  • Save it to disk

What is serialization

import java.io.Serializable;

public class Cake implements Serializable{
    private String icing;
    private String sponge;
    
    public Cake(String icing, String sponge){
        this.icing = icing;
        this.sponge = sponge;
    }
    
    public String getIcing(){
        return icing;
    }
    
    public String getSponge(){
        return sponge;
    }
}

Object to be serialized

What is serialization

public class SerializeExample {

    public static void main(String[] args){

           FileOutputStream fileOut =
                   new FileOutputStream("/tmp/cake.ser");

           ObjectOutputStream out = 
                   new ObjectOutputStream(fileOut);

           out.writeObject(new Cake("pink", "vanilla"));
    }
}

Create an ObjectOutputSteam

Stream the object to disk

What is deserialization

public class DeserializeExample {
    
    public static void main(String[] args) {
    
        FileInputStream fileIn = 
                new FileInputStream("/tmp/cake.ser");

        ObjectInputStream ois = new ObjectInputStream(fileIn);

        Cake myCake = (Cake) ois.readObject();
    }
}

Restore it as an object

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

How does it work?

Code reuse during deserialization

Gadget Chain

Gadget Chain

  • Code reuse attack
  • Relies on code loaded by application
  • Create chain of objects
  • Start with a 'kick-off' gaget
    • starts building the chain
  • Serialize chain and send to application
  • End with a 'sink' gadget
    • Ends the chain in target Java call

Gadget Chain

  • Kick-off
    • BadAttributeValueException
  • Sync
    • Runtime.exec()

Kick-off Gadget

BadAttributeValueExpression

    private void readObject(ObjectInputStream ois) {
        ObjectInputStream.GetField gf = ois.readFields();
        Object valObj = gf.get("val", null);

Set "val" to the next object to create

Called during deserialization

Sink Gadget

Runtime.exec()

Run any command as Java system user

* Relies of commons-collections library

Runtime.exec()

Proxy Object

LazyMap.get()
    ChainedTransformer.transform()
        ConstantTransformer.transform()
        InvokerTransformer.transform()
            Method.invoke()                
                Class.getMethod()
        InvokerTransformer.transform()
            Method.invoke()
                Runtime.getRuntime()
        InvokerTransformer.transform()
            Method.invoke()
                Runtime.exec()  

ysoserial tool

Precanned gadget chains for exploitation

  • Hibernate
  • Commons-Collections
  • Spring
  • Commons-Beanutils
  • ...
  • (More to come)

Are we vulnerable?

Are you using any of these Java libraries?

BeanShell

C3P0

Commons Collections

Commons Beanutils

Commons Fileupload

Groovy

Hibernate

JBoss Interceptors

net.sf.json

JBoss Weld

Jython

Mozilla Rhino

MyFaces

ROME

Spring

Wicket

Are you doing Java deserialization?

java.io.ObjectInputStream->readObject()

 ObjectInputStream

 MyObjectInputStream

->readObject()

Add tracing to find Java deserialization

notsoserial

  • java agent
  • trace deserialization
  • reject deserialization

How about your HTTP traffic?

JBoss EAP 5 / AS 5 Attacks

Legacy Invoker Servlet

"It was discovered that the LegacyInvokerServlet is exposed on all network interfaces and deserializes objects sent to it. An attacker could use this flaw to cause remote code execution in the JVM running it."

JBoss EAP 5

Some of the available class libraries:

  • Hibernate
  • Commons-Collections
  • Remoting (JDK)
  • Commons-Beanutils
  • ...

JBoss EAP 5 exploit

1098
1099
3873
4444
4445
4446
4712
4713
4457
8009
8080
8083
35951
cat /tmp/exploit.ser | nc example.com 4445
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

JBoss EAP 6 & 7

Wildlfy Attacks

JMS Object Message

"It was found that use of a JMS ObjectMessage does not safely handle user supplied data when deserializing objects. A remote attacker could use this flaw to execute arbitrary code with the permissions of the application using a JMS ObjectMessage."

Thanks: Matthias Kaiser from Code White

Consumer vulnerable

Middleware

Producer

Consumer

JMS

Queue

  • Deserialization occurs in the message Consumer
  • Gadget Chain classes must exist in the classpath

MDB Vulnerable

Middleware

Producer

Consumer

Message Driven Beans

  • Deserialization occurs on the middlware (EAP) server
  • Gadget chain must be on MDB classpath

Trusted producers

Middleware

Producer

Consumer

JMS

Queue

  • Producer needs to authenticate to connect

Trust

Zone

ActiveMQ and Artemis Whitelist

Middleware

Producer

Consumer

JMS

Queue

  • Check whitelist at time of deserialization
  • Optional blacklist also possible

White

List

"A flaw was found in the way JGroups handles authentication. Successful exploitation of this flaw could allow a remote attacker to execute arbitrary code on a Java Virtual Machine running JGroups. It could also lead to integrity problems with JGroups communications, and confidentiality of the data transmitted."

JBoss Clustering

What is clustering?

JGroups is a group communication tool which facilitates things such as HTTP Session replication in a cluster

Requirements for exploitation

  • Can broadcast UDP traffic on network
    • ​Dropped by most routers
    • ​Sometimes cluster is over WAN via TCP
  • Have to be using clustering features

Only accepts trusted data?

  • Requires authenticaton
    • ​only on request to join cluster
    • not checked when receiving messages
  • Supports Encryption
    • doesn't prevent replay attacks
  • Uses Java Serialization
    • ​UnmarshallingObjectInputStream extends ObjectInputStream

Deserialize on message receive

                <stack name="udp">
                    <transport type="UDP" socket-binding="jgroups-udp"/>
                    <protocol type="PING"/>
                    <protocol type="MERGE3"/>
                    <protocol type="FD_SOCK" socket-binding="jgroups-udp-fd"/>
                    <protocol type="FD_ALL"/>
                    <protocol type="VERIFY_SUSPECT"/>
                    <protocol type="pbcast.NAKACK2"/>
                    <protocol type="UNICAST3"/>
                    <protocol type="pbcast.STABLE"/>
                    <protocol type="pbcast.GMS"/>
                    <protocol type="UFC"/>
                    <protocol type="MFC"/>
                    <protocol type="FRAG2"/>
                </stack>

UDP

PING

MERGE3

UnmarshallingObjectInputStream

.readObject()

JGroups exploit client

<config xmlns="urn:org:jgroups"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="urn:org:jgroups http://www.jgroups.org/schema/JGroups-3.0.xsd">
	<UDP bind_addr="127.0.0.1" mcast_addr="230.0.0.4" mcast_port="45688"/>
</config>
  • Create a minimal JGroups configuration
    private void sendObject(Serializable maliciousObject) throws Exception {
        setChannel(new JChannel("jgroups.xml"));
        getChannel().connect("ee");
        sendPayload(maliciousObject);
        getChannel().close();
    }
  • Send your malicious payload

How can I exploit it?

Whitebox method: Tracing deserialization

  • Print a stack trace on deserialization
  • Requires
    • installation of a Java agent
    • comprehensive test suite

Can I deliver a malicious payload?

  • Stack trace should give you a an idea of which endpoint to target
  • Generate a payload using ysoserial
    • use a gadget available in the application
  • Profit!
  • email secalert@redhat.com and get acknowledged

Are they using any of these gadget chain libraries?

BeanShell

C3P0

Commons Collections

Commons Beanutils

Commons Fileupload

Groovy

Hibernate

JBoss Interceptors

net.sf.json

JBoss Weld

Jython

Mozilla Rhino

MyFaces

ROME

Spring

Wicket

Blackbox method:

Java serialized data in HTTP traffic?

ac ed 00 05

How can I prevent it?

General Advice

  • Don't use Java Serialization
    • Prefer JSON
  • If you must deserialize
    • Add authentication to endpoints
    • Whitelist approved classes to be deserialized
    • Restrict the classes on your classpath

Security Hardening

Remove gadget chain libraries

CVE-2015-7501

  • Disabled commons-collections deserialization
  • Not really a vulnerability, just a hardening fix

Don't deserialize 

Legacy Invoker Servlet (LIS)

CVE-2016-3690

  • Advised customers to remove LIS

Add authentication

CVE-2016-2141

  • Do clustering on a dedicated VLAN
  • Unencrypted messages are dropped
  • Need to configure encryption

Add whitelisting

  • ActiveMQ and Artemis added whitelisting
  • EAP 6 and layered products: WONTFIX
    • Authentication required to send messages

Thanks

Questions?

 

secalert @ redhat.com

Deserialization - 30min

By Jason Shepherd

Internal

Deserialization - 30min

More from Jason Shepherd