nicky bloor - barmie - poking java's back door - 44con 2017

Post on 22-Jan-2018

1.790 Views

Category:

Technology

5 Downloads

Preview:

Click to see full reader

TRANSCRIPT

BaRMIe – Poking Java’s Back Door

Nicky Bloor 44CON 2017

whoami

Nicky Bloor

• Managing Security Consultant at NCC Group

• Ex software developer

• Desktop, web, games, industrial control systems

• Problem solver, breaker, builder, hacker

• Hiker and rock climber

• @NickstaDB on the Interwebz

A Story of Pwn

• On-site Java application assessment

• No credentials provided until day 3…

• Supporting infrastructure was in scope

• One network service stood out…

A Story of Pwn

Java Remote Method Invocation???

…gave me the server before I got those credentials.

Too easy! This left me really intrigued!

RMI?

• How common is RMI?

• How often is it so insecure?

• What else can we do with it?

Java Remote Method Invocation

A Brief Introduction to RMI

• Remote Method Invocation

• RPC for Java

• Execute methods within another Java virtual machine (JVM)

• Local or remote

• Simple to implement

• RMI takes care of connection and transport

• Developer does not need to be aware that RMI is in use

• RMI != arbitrary remote code execution

• Only execute methods that are implemented within the other JVM

8

A Brief Introduction to RMI

Client Application

IFoo.Bar()

RMI RMIServer Application

FooImpl.Bar()

IFoo.Bar();

The RMI Registry Service

• Directory of Java objects

• Maps Java objects to names

• Listens on TCP port 1099 by default

• Interaction via java.rmi.Registry class

• void bind(String name, Remote obj)

• String[] list()

• Remote lookup(String name)

• void rebind(String name, Remote obj)

• void unbind(String name)

The RMI Registry Service

• void rebind(String name, Remote obj)

• Rebind a bound object name to another object

• Potential free man-in-the-middle attack?

• void unbind(String name)

• Unbind an object from the registry

• Potential free denial of service attack?

The RMI Registry Service

• void rebind(String name, Remote obj)

• Rebind a bound object name to another object

• Potential free man-in-the-middle attack?

• void unbind(String name)

• Unbind an object from the registry

• Potential free denial of service attack?

• Cannot bind/rebind/unbind from non-localhost

Implementing RMI

• Very easy – perhaps part of the problem!

• Server-side

• Implement java.rmi.Remote

• Instantiate object

• Bind object to RMI registry

• Client-side

• Lookup object from RMI registry

• Use as normal

What’s the Problem?

• Fairly reasonable looking method

• Authenticate first, then read the file

What’s the Problem?

What if ApplicationObjectFactory returns a remote object?

What’s the Problem?

Client Server

authenticateUser(user,pass)

readFile(filename)

true

file contents

What’s the Problem?

Client ServerreadFile(filename)

file contents

RMI Security?

• Authentication?

• No.

• Session management?

• No.

• Encryption?

• No.

• Message integrity checking/anti-tampering?

• No.

• Access controls?

• Yes. Kind of… Fine. No.

RMI Security?

• Encryption

• SSLSocketFactory can be used

• Access controls

• bind/rebind/unbind can only be called from localhost

• Risky code executes BEFORE the localhost check…

• (Pre-Java 6u131, 7u121, 8u112)

RMI Security

RMI Security

• This is a bit unfair

• RMI wasn’t designed to be secure

• RMI was designed to facilitate remote method invocation

• To compare:

• HTTP wasn’t designed to be secure

• HTTP was designed to facilitate the transfer of textual information

RMI Security

• HTTP is far more prevalent

• HTTP has evolved to support security

• Web application frameworks improve security by default

• Authentication, session management, access controls etc…

• Developers don’t need to be particularly security aware

• RMI has none of this!

• Security must be explicitly incorporated in remotely exposed classes

Insecure Use of RMI

Insecure Use of RMI

• RMI not a secure protocol

• Original attack:

• Ignore authenticate method

• Call readFile/writeFile/executeQuery directly

• How often is RMI used this insecurely?

Insecure Use of RMI

• First step: Identify software using RMI

• Little success initially searching Google & Github

• Can I identify RMI software packages remotely?

Insecure Use of RMI

• Recalled an early test program which called Registry.lookup()

• Exception reveals fully-qualified class names

• Often identifies vendor

• Sometimes identifies the application itself

• Can we identify RMI software packages remotely?

• Yes!

• Internet search for fully-qualified class names

Insecure Use of RMI

• So, we can extract fully-qualified class names…

• What else can we learn from RMI network traffic?

• How can we extract this information?

RMI Enumeration

RMI Enumeration

RMI Enumeration

RMI Enumeration

RMI Enumeration

Insecure Use of RMI

• A lot of time was spent in these tools

• Along the way code was produced to parse RMI traffic and extract

useful data…

BaRMIe - Enumeration

BaRMIe - Enumeration

• Proxy-based enumeration of RMI registries

• Start TCP proxy for RMI registry connection

• Request remote objects

• Buffer RMI ‘ReplyData’ packets

• Parse the packet contents to extract useful data

Knocking on Java’s Back Door

• Find RMI software

• Found over 14,000 RMI services on Shodan

• Over 27,000 Java objects exposed over RMI

Knocking on Java’s Back Door

• Find RMI software

• Found over 14,000 RMI services on Shodan

• Over 27,000 Java objects exposed over RMI

• Not all exposed externally

Knocking on Java’s Back Door

• Find RMI software

• Found over 14,000 RMI services on Shodan

• Over 27,000 Java objects exposed over RMI

• Not all exposed externally

Knocking on Java’s Back Door

• Find RMI software

• Found over 14,000 RMI services on Shodan

• Over 27,000 Java objects exposed over RMI

• Not all exposed externally

• Many probably shouldn’t be exposed

Knocking on Java’s Back Door

• Find RMI software

• Found over 14,000 RMI services on Shodan

• Over 27,000 Java objects exposed over RMI

• Not all exposed externally

• Many probably shouldn’t be exposed

DbVehicleSearchService drivingLicenseManagercarUseRecordManager

Knocking on Java’s Back Door

• Find RMI software

• Found over 14,000 RMI services on Shodan

• Over 27,000 Java objects exposed over RMI

• Not all exposed externally

• Many probably shouldn’t be exposed

DbVehicleSearchService drivingLicenseManagercarUseRecordManager

CameraCapturedImages CCPaymentService superviseOilManager

Knocking on Java’s Back Door

• Find RMI software

• Found over 14,000 RMI services on Shodan

• Over 27,000 Java objects exposed over RMI

• Not all exposed externally

• Many probably shouldn’t be exposed

DbVehicleSearchService drivingLicenseManagercarUseRecordManager

CameraCapturedImages CCPaymentService superviseOilManager

SecurityServer ROOT_TERMINAL AdminAPI system UserConfigAPI

Knocking on Java’s Back Door

• Find RMI software

• Found over 14,000 RMI services on Shodan

• Over 27,000 Java objects exposed over RMI

• Not all exposed externally

• Many probably shouldn’t be exposed

DbVehicleSearchService drivingLicenseManagercarUseRecordManager

CameraCapturedImages CCPaymentService superviseOilManager

SecurityServer ROOT_TERMINAL AdminAPI system UserConfigAPI

chainGunAPI

Knocking on Java’s Back Door

• Find RMI software

• Found over 14,000 RMI services on Shodan

• Over 27,000 Java objects exposed over RMI

• Not all exposed externally

• Many probably shouldn’t be exposed

DbVehicleSearchService drivingLicenseManagercarUseRecordManager

CameraCapturedImages CCPaymentService superviseOilManager

SecurityServer ROOT_TERMINAL AdminAPI system UserConfigAPI

chainGunAPI beerMachineApi

Knocking on Java’s Back Door

• Find RMI software

• Found over 14,000 RMI services on Shodan

• Over 27,000 Java objects exposed over RMI

• Not all exposed externally

• Many probably shouldn’t be exposed

DbVehicleSearchService drivingLicenseManagercarUseRecordManager

CameraCapturedImages CCPaymentService superviseOilManager

SecurityServer ROOT_TERMINAL AdminAPI system UserConfigAPI

chainGunAPI beerMachineApi praiseService

Knocking on Java’s Back Door

• Find RMI software

• Found over 14,000 RMI services on Shodan

• Over 27,000 Java objects exposed over RMI

• Not all exposed externally

• Many probably shouldn’t be exposed

DbVehicleSearchService drivingLicenseManagercarUseRecordManager

CameraCapturedImages CCPaymentService superviseOilManager

SecurityServer ROOT_TERMINAL AdminAPI system UserConfigAPI

chainGunAPI beerMachineApi praiseService

Knocking on Java’s Back Door

• Honestly, no idea what any of these do!

• These are just examples of what people expose over RMI.

• This is bad if these services are implemented as insecurely as

that first ‘writeFile’ example

Examples of Insecure RMI

Apache JMeter

• org.apache.jmeter.engine.RemoteJMeterEngineImpl_Stub

• Open source!

• Download source and review

• Locate classes that implement java.rmi.Remote

Apache JMeter

Apache JMeter

• Looks like anyone can configure this service!

Temis RemoteAdminServer

• com.temis.admin.remote.RemoteAdminServer_Stub

• Unable to locate source code or client jar

• BaRMIe revealed an interesting annotation…

Temis RemoteAdminServer

• Remote methods:

• UserProfile authenticate(String, String)

Temis RemoteAdminServer

• Remote methods:

• UserProfile authenticate(String, String)

Looks like they thought about security?

(UserProfile – could be a session-like object?)

Temis RemoteAdminServer

• Remote methods:

• UserProfile authenticate(String, String)

• boolean configure(Properties)

…or not!

Temis RemoteAdminServer

• Remote methods:

• UserProfile authenticate(String, String)

• boolean configure(Properties)

• String getAdminKey()

Temis RemoteAdminServer

• Remote methods:

• UserProfile authenticate(String, String)

• boolean configure(Properties)

• String getAdminKey()

• int addUser(String, String, String, String)

Temis RemoteAdminServer

• Account takeover?

• List<UserProfile> getAllUserList()

• int changePassword(UserProfile, String)

Temis RemoteAdminServer

• Account takeover?

• List<UserProfile> getAllUserList()

• int changePassword(UserProfile, String)

• UserProfile methods:

• String getPassword()

Temis RemoteAdminServer

• More remote methods:

• String getDatabaseIP()

• String getDatabasePort()

• String getDatabaseName()

• String getDatabaseType()

Temis RemoteAdminServer

• More remote methods:

• String getDatabaseIP()

• String getDatabasePort()

• String getDatabaseName()

• String getDatabaseType()

• String getUsername()

• String getPassword()

RMI: What’s the Problem?

RMI: What’s the Problem?

It gets worse…

Deserialization

Deserialization

• Process of converting data into runtime objects

• Often implemented/used insecurely

• Deserializing untrusted data is usually bad

• RMI is heavily dependent on Java serialization

Adobe ColdFusion

• Most commonly exposed RMI service in my scans

• coldfusion.flex.rmi.DataServicesCFProxyServer_Stub

• No strikingly interesting remote methods

Adobe ColdFusion

• Most commonly exposed RMI service in my scans

• coldfusion.flex.rmi.DataServicesCFProxyServer_Stub

• No strikingly interesting remote methods

• Except…

Adobe ColdFusion

• Most commonly exposed RMI service in my scans

• coldfusion.flex.rmi.DataServicesCFProxyServer_Stub

• No strikingly interesting remote methods

• Except…

Adobe ColdFusion

• Most commonly exposed RMI service in my scans

• coldfusion.flex.rmi.DataServicesCFProxyServer_Stub

• No strikingly interesting remote methods

• Except…

Adobe ColdFusion

• Most commonly exposed RMI service in my scans

• coldfusion.flex.rmi.DataServicesCFProxyServer_Stub

• No strikingly interesting remote methods

• Except…

• Call fill() to deserialize any object…

Demo Time!

• Adobe ColdFusion 2016, fully up-to-date as of 11th September 2017

• Default install except for one setting

• Unauthenticated remote method invocation…

Demo Time!

Deserialization

It’s worse than that…

Java’s Back Door

Java’s Back Door

• Testing some code

• Suddenly realised I’d made a mistake…

• …but the code worked…

Full RMI Proxy

• Successfully proxying RMI registry connections

• RMI registry does not handle method invocations

• Invocation handled by remote objects

• Different port

• Potentially different host

• Built a proxy to MitM method invocations

Proxying RMI

RMI Client

RMI Registry

RMI Object

Proxying RMI

RMI Client

RMI Registry

RMI Object

Registry Proxy

First, we create an RMI registry proxy

Proxying RMI

RMI Client

RMI Registry

RMI Object

Registry Proxy

Which is configured to connect directly to the target RMI registry

Proxying RMI

RMI Client

RMI Registry

RMI Object

Registry Proxy

Our RMI client requests an object via the proxy

Proxying RMI

RMI Client

RMI Registry

RMI Object

Registry Proxy

The object data is intercepted and parsed

Proxying RMI

RMI Client

RMI Registry

RMI Object

Registry Proxy

Object Proxy

3) Creates Object Proxy

The RMI registry proxy then creates an RMI object proxy

Proxying RMI

RMI Client

RMI Registry

RMI Object

Registry Proxy

Object Proxy

3) Creates Object Proxy

Which is configured to connect directly to the RMI object

Proxying RMI

RMI Client

RMI Registry

RMI Object

Registry Proxy

Object Proxy

3) Creates Object Proxy

We modify the object data to point at the new proxy and return it to the client

Proxying RMI

RMI Client

RMI Registry

RMI Object

Registry Proxy

Object Proxy

3) Creates Object Proxy

We can now MitM remote method invocation traffic!

Java’s Back Door

• So, what was that mistake?!

• Experimenting with network-level payload injection and ysoserial

• Called obj.foo(String) in RMI client, rather than obj.foo(Object)

Java’s Back Door

• So, what was that mistake?!

• Experimenting with network-level payload injection and ysoserial

• Called obj.foo(String) in RMI client, rather than obj.foo(Object)

• Proxy replaced the parameter…

Java’s Back Door

• So, what was that mistake?!

• Experimenting with network-level payload injection and ysoserial

• Called obj.foo(String) in RMI client, rather than obj.foo(Object)

• Proxy replaced the parameter…

Poking Java’s Back Door

• Invoking void printString("AAAAAAAAAA") looks like this:

Poking Java’s Back Door

• Invoking void printString("AAAAAAAAAA") looks like this:

• A simple serialized object, new Dummy(), looks like this:

Poking Java’s Back Door

• The proxy did this (with a ysoserial payload):

Poking Java’s Back Door

• The proxy did this (with a ysoserial payload):

• Remotely invoked an illegal method call

Poking Java’s Back Door

• The proxy did this (with a ysoserial payload):

• Remotely invoked an illegal method call

• void printString(new Dummy()):

Poking Java’s Back Door

• The proxy did this (with a ysoserial payload):

• Remotely invoked an illegal method call

• void printString(new Dummy()):

• Server-side exception

• Dummy is not compatible with java.lang.String

Poking Java’s Back Door

• The proxy did this (with a ysoserial payload):

• Remotely invoked an illegal method call

• void printString(new Dummy()):

• Server-side exception

• Dummy is not compatible with java.lang.String

• Payload had already been deserialized

Java’s Back Door

If we invoke a remote method, we can replace parameters with incompatible payloads

Caveat

• Slight caveat, due to Java serialization format/protocol

• Method parameter that we replace must be non-primitive

• int, long, boolean etc cannot be replaced

• Integer, int[], ArrayList, and objects of arbitrary classes can

BaRMIe

BaRMIe

• RMI often exposes legitimate but dangerous methods

• writeFile(), executeQuery()

• Proxy-based attacks can introduce further risk

• Vulnerabilities where there wouldn’t otherwise be a vulnerability

• Requires knowledge of remote classes/method signatures

BaRMIe

• Written a lot of code during this research…

• Enumeration of remote objects (identify classes)

• Attacks for various targets

• Executing legitimate methods

• Deserialization attacks using Object type parameters

• Deserialization attacks through illegal parameter replacement

• BaRMIe is an all-in-one RMI enumeration and attack tool

Conclusion

Conclusion

• RMI lacks maturity

• Often used very insecurely

• Object injection/deserialization attacks are almost always a

possibility

• Old and ‘uninteresting’ technology can be a fun and fruitful

research target!

Questions?

https://nickbloor.co.uk/

top related