пятница, 12 января 2018 г.

Java Deserialization: Misusing OJDBC for SSRF

This year ZeroNights has got a new zone - Web Village. It was a special "track" for people who were interested in web security. The basic idea of the Web Village is to tell people about typical vulnerabilities and attack techniques. I made a speech about basics of deserialization vulns in various languages. I wanted to show common patterns which make serialization libs potentially vulnerable. There is that presentation.

In the presentation I showed an example of a new Java gadget in order to prove that it's stupid to "fix" gadgets or "blacklist" them instead of protecting/changing deserialization lib. Here I’d like to show some details of the example.

The gadget is a class in a library which is used to connect a Java application to a RDBMS Oracle - ojdbc. Actually, this exact class (OraclePooledConnection) is responsible for establishing a connection.
The example is very simple, because the class has a readObject method which goal is to reestablish connection to a database during a deserialization process.
In the bottom of the post you can read the code, but it's not necessary, because we are going to use it in the same way as it's supposed to be used.

As we control a field (connection_url) with a string where a java application tries to connect during deserialization process, it means that we have a SSRF vulnerability here.
At first glance, it looks pretty useless, because the Oracle's protocol is binary. But I played with Oracle DB some years ago and know that the client (and TNS protocol) is very flexible.
The "URL" consists of several fields:


I think almost all of them are self-describing.
An important feature for us is that the "service name" field can contain a very long value and almost any ASCII symbols. So, potentially we can interact with text-based services. Yes, there will be binary garbage before the service name and after, but many servers don't care much about such things ("errors friendly").

So step-by-step, we create a serialized object with a specific payload as service name, send it to an application. The application runs readObject of "OraclePooledConnection" class and it forces the application to connect to wherever we want and to send our payload.

So, my point is pretty clear, the class doesn't really have any vulns, but we still can misuse its features for our attacks.

PS: The same "SSRF-attack" you can perform if you have access to Oracle DB with privs that allow you to create DB links.

P.P.S: Potentially, the attack can be improved somehow... As we control the "url" for connection, may be we can steal NetNTLM credentials (because oracle auth supports it) or perform TNS Poisoning attack?

 Code of readObject method of OraclePooledConnection class