Bytecode injection countermeasures in jar files - java

I have a jnlp application that loads and executes a jar file ( client ) on a users computer. The user uses this jar to communicate with a server that provides a services. I've seen users using javassit and javasnoop to alter the functionality of the client. Is there any way I can remotelly detect changes created by the previously mentionted utilities ? For example, can I checksum the classes locally and send the result to the server ( who knows the correct checksum of each class ) ?

There is no way in general to prevent the client from running any code they wish to. The security of your system should never rely on assuming that clients are running specific code or are not aware of specific information contained in the jars you send them.
Furthermore, attempts to impose DRM tend to cause problems for legitimate users and alienate your customers while doing little to prevent people who actually do want to hack the system.

You can for example create a check sum of your java file and make your application to calculate the checksum at runtime and send it for verification to server. The simplest checksum is a hash code of whole jar.
The only question is why? And who is the super user that takes your jar and performs instrumentation on it? And why is he doing this? And even if he has reasons, who cares? If you are afraid that somebody is going to hack your server make it secure enough and do not care about client (IMHO).

You can open a classfile named p1.p2.ClName with Classloader.getResourceAsStream("/p1/p2/ClName.class"), read it, and compute its checksum.
But, as user can change the functionality, he can also remove that checksum checking.

Related

Secret Information in Programs

So I read this question on Programmers SE and I got a little confused. In short, the solution is to keep all secret information in config files. Now this is where I'm confused. Couldn't a user just go searching for this file?
What methods are used to prevent users from finding the file? I'm using Java on Windows if that changes the answer at all.
I would think Encryption would come up but I'm not sure how that helps if the user can just decompile your source.
EDIT: To clarify further, my intention is to use API Keys (in this case 1, singular key) in an executable JAR file.
This depends what you are trying to achieve. I will assume here that the user has access to the enviroment in which your software is running. If you need to store some secret information, then you can use encryption, where the user has to supply a key. This is difficult to implement yourself correctly, but there are plenty of libraries and resources for this.
If your problem is exactly as described in the Programmers SE- you want to share code without sharing the 'secret' settings- extract the settings into a configuration file and don't share the configuration file. You can give a template, but with the secrets missing.
You can't really protect your informations if they are somehow available to the end-user - even if they are somehow crypted as long as your software is also available on the client. It only depends on the criminal energy the attacker will invest to get them.
One possibility could be to use ie. connection pooling for a database connect.
With this technique you get the connection object remote without the knowledge of the password - so you can use the connection within your app but the user cannot use informations to connect to the database with some sql tool.
See here for details: https://en.wikipedia.org/wiki/Connection_pool
Having read the link you provided I can think of the following below. Also please feel free to check the Security network (one interesting question here).
For a example in a database config file you could have an entry like
<%= ENV['USER_NAME'] %>
<%= ENV['PASSWORD'] %>
and those two variables are environment variables that you set.
Using encryption would be similar. You'd store an encrypted/hashed key in a config file and you use that data to see if there is a match when needed.
Encrypted data can be decrypted with a corresponding key
Cryptographically hashed data is very hard to crack
You'd need to design that appropriately whatever your requirements are.
And you can combine both methods too if you wish.
Example
I invite to have a look at my GitHub project's config folder. In particular the yaml files. I use the first method above mostly. It is a RoR project.

Download Java Class File & Run?

Okay, so pretty much I'm trying to add security to my Java class file. I don't want it to get decompiled. So what I've done is created a login system where the java app checks it through a web request. If the login information is correct then it will run the script. However, I want to further improve security and have the class file hosted online.
How can I make it download & run the online hosted file?
Also, when the app/script stops running or it's closed the .class file is deleted.
I'd prefer where it did not have to download the file, just get from an online server and compile/run.
Let's go through the things you have done, and the things you are proposing to do and see if they will really work:
Asking for a password. This is easily to defeat:
Capture the classfile.
Decompile it.
Identify the place where it makes the remote call does the login check, and checks the response.
Modify the bytecodes to remove all of that.
Rather than installing the class file, download it on demand and delete it when it finishes. Also easy to defeat.
Capture network request made to download the file.
Replay the request using (say) curl or wget and capture the downloaded class file.
Proceed as above.
And variations are relatively easy to defeat too:
Obfuscation can always ultimately be defeated by manual decompilation and/or running the bytecodes using a debugger.
Downloading using one-time key or something can be defeated by reverse engineering the procedure and extracting the one-time key ... before it is used.
Encrypting the bytecodes can defeated because the JVM has to have the bytecodes in decrypted form at some point. So the means of decryption of the bytecodes must be embedded in code ... that can be reverse engineered.
The bottom line is that it is impossible to prevent a skilled and determined person from defeating security schemes that depend on keeping things secret from a user who controls his / her own execution platform.
The best you can hope to do is stop low-skilled attackers, and slow down skilled ones. You need to ask yourself ... is it really worth the effort?
(Note: you have the same problem no matter what implementation language you use.)
Create a new URLClassLoader (the "default" Java classloader) and point it at wherever you saved the file:
// the directory where you're saving the .class file
File tmpDir = new File("/tmp/yadda/blah/");
ClassLoader cl = new URLClassLoader(new URL[] { tmpDir.toURI().toURL() }, Thread.currentThread().getContextClassLoader());
Class<?> cls = cl.loadClass("SuperSecretClass");
// use reflection to instantiate cls, call methods, etc.
(Passing in the parent class loader might not be necessary in a non-webapp, but I'm too lazy to test that detail. Using the thread's classloader explicitly will work one way or the other.
This assumes that your secret class is not in a package, if it is you'll have to create the appropriate directory structure inside the temporary directory and point the classloader at the root of the package tree, as usual.
Also: this sort of security-by-obscurity sounds like a bad idea. You're still downloading the file, if it's over an unsecured connection a determined attacker can sniff it, and there's still the period of time during which it's on disk. You could create a completely custom ClassLoader that directly reads the stream, but even the class file could probably be recovered with a little more effort. (Like pointing a debugger at your main app and intercepting stream reads.) The javadoc for ClassLoader provides an example of how to do this.

How to incremental update Java EE web application?

I have a typical web application deployed in Tomcat. The requirement is to provide incremental update way instead of full-package delivery (a war file) when update the application.
For example, once I finish a bug fix which changed a jar file, an XML file and jpg file. I call these 3 files as a patch. I am supposed to deliver the patch file. Even when customers want to rollback to original version, I have to provider a way to rollback the patch.
All the process is supposed to automatically.
From my perspective, the requirement doesn’t make sense. full-package delivery is easy and reliable way to update a web application, I don’t want to introduce complex and error-prone way to update.
Do you have idea to implement incremental update requirement? Thanks!
When you deploy the .war or .ear, the application server usually unpack it into an internal directory. You can change files in this directory directly, with a finer granularity. However, for changes to take effect consistently, you will need to restart the server.
Your perspective is indeed fully correct. Nowadays, sizes of files don't play a significant role, I don't see the problem with whole updates. Why isn't the customer happy with whole updates?
Note: If what he wants is dynamic updates, i.e. without restarting the server, then this is anyway a complete different problem, and mostly impossible for production systems in java (but doable during development, with solutions like JRebel).
You can create a Java Program that uses Delta-Sync protocol i.e. Only those files need to uploaded which are updated. If you have used Dropbox then you will understand pretty well.
Dropbox uses Delta-Sync protocol to update file and sync data.
Either way for time being you can use Dropbox by installing on your client (mapping to server's WAR folder) and your local machine and share that folder. Then whenever you change the files in your local machine it will automatically upload and sync those CHANGED (PATCH) files to your client's machine.

How to encrypt a .jar file

I'm working in a project where we need to encrypt the .jar file so no one can access to the .class files which inside the jar file.... is there any java coding which can help me to encrypt the .jar file ?
Even if you encrypt the jar file, it must be decrypted before the JVM is able to run it, so you'll need another jar file containing classes that decrypt and loads in the JVM.
Since this second jar file cannot be itself encrypted, a malicious user wanting to see you class files, can simply look at classes in this second jar file, and then decrypt your super-secret jar file and have access to it.
Maybe you can increase security of your code using an obfuscator, but it will eventually protect (make it harder but not impossible) your class files from decompilation, not from being used.
If obfuscation is not enough, you could consider compiling your jar file to a DLL for windows or a SO for unix/linux, that will make it much harder to decompile, but it's not always possible to do that correctly and it's generally a PITA. GCJ is able to do this somehow, and there are other commercial products that will actually compile .class/.jar directly to machine code.
However please consider that it does not matter how much security you put in it, since the client computer MUST be able to execute it, it must be able to read it, so no matter what your code will be exposed, you can only make it harder.
If you really have an algorithm so secret you don't want to disclose no matter what, consider converting it to a web service, hosting it on your server, so that you don't have to send the actual code to the client machines and can also better prevent unauthorized copies of your application by checking access to that vital part of it.
I assume you are aware of the fact that any skilled java coder can reverse-engineer the Java tool you use (or write) and still decode the app's jars? Also writing custom classloaders which read your "encrypted" code can be decompiled and a tool could be written to bypass it.
Even with obfuscation and bytecode modification and custom classloaders, java is hackable/decompileable and the source can almost always be brought to a somewhat readable state.
You want to obfuscate, not encrypt, the jar file.
A popular choice for doing this in Java is ProGuard.
No. Since your program needs to be able to run the code it would be pointless anyway.
You can obfuscate your code though so decompiling the .class files results in less readable code (meaningless variable/class names etc).
As far as I know this is not supported by standard JVM. But you can do the following. Separate your application into 2 parts. First will not be encrypted. It will be a simple loader that will instantiate the rest using custom class loader. This class loader will get Classes as arrays of bytes, decrypt and load them.
if you don't want to provide an access to the class files inside the jar, why should you supply your jar with the application?
It feels like your question is kind of wrong conceptually...
If you need some custom way of loading the classes, consider to use custom classloader.
if you are packaging in jar -> just rename it to jarname.ABCD or any misleading extension or even take off the extension, and accordingly specify the jar name in your application.
i prefer jCrypt!
It is a simple tool where you can crypt the classes(and ressources)

Load jar from URL

I've been searching for days but I have not found a clear answer. How would I go about writing a small jar file to give to my users that simply gets a jar file from a URL (with multiple classes in it) and run it. It would be great if the end user never actually has the jar on his computer at anytime. I am doing this as a small security measure.
If the user is going to execute your code, it must exist on their computer. It's just the way it works.
If you wanted to re-write your code to perform most of the work on your servers, that'd be one mechanism to combat piracy, but it does mean that you need to duplicate all the input verification checks: perform them once on the client side, for reasonable response time, and again on your own servers, to ensure that your users aren't trying to use your services improperly.
Another mechanism would be to run a VNC server on your servers, and ask your users to VNC in. The software executes completely on your servers. It is a draconian step though, one your users will likely detest.
I am not sure how you'd go about it, but I know that using Maven allows you to access things without having the jar locally. You can just specify the URL. So maybe look into how they do their repositories.
Another option would be to encrypt your JAR file and write a custom class loader that decrypts it on the fly on client machines. This won't prevent a power user from attaching a debugger to the JVM and examining your byte code, but it prevents the typical user from having access to your code.

Categories

Resources