I'm creating an application that launches the JVM (using a copy of the JRE). If I edit rt.jar, for example to remove functionality that users shouldn't have access to, will it somehow break the JRE?
EDIT: The application involves downloading code onto a user's machine, so it would be restricting the code rather than the user. I probably should have clarified that.
There's a good chance you would break something that won't be noticeable until runtime.
But perhaps more important is the licensing problem: your app is shipping its own version of the JRE, which you're allowed to do, except you cannot modify the JRE you're distributing, as per the J2SE license:
[...]
(a) you distribute the Software complete and unmodified and only
bundled as part of Your applets and applications ("Programs"),
It's also questionable what is meant by "to remove functionality that users shouldn't have access to". Your application is executing in the context of a user account, and whatever functionality you removed from the JRE:
If the OS allows that particular action in the context of that user's session, then there's another way to do it - hence you're in the same position you were in before messing with rt.jar. Your user can just make a system call.
If the OS doesn't allow that action in the context of the user's session, then the JVM won't be able to do it either, whether the classes are present or not, so the whole question is moot.
Usually, the best way to remove functionality is to use a SecurityManager. This allows you to control what can be accessed or key action can be performed.
Completely depends on what you "remove". But its possible. As long as you dont break anything, remove dependencies etc...
And if you want to do something security wise. How can you ensure that you and only you have full control over the users JRE?
And if this is the case. What benefit would your doing do what you can't do in your application?
But its possible and a valid thought for some reasons. But they are mostly benchmarking, developing, debugging. For example dumping unencrypted bytecode
Also be aware of the licensing problem. You probably won't be legally able to sell or ship this.
why do you ask, you might potentially break some agreement/license, other than that it's ok.
I don't do so that but change the bootstrap loader's classpath to load my classes before rt.jar, etc. This is legal :)
In the end: Getting NoClassDefFoundError aint cool, no matter how you look at it.
If you're asking if it's legally okay, I don't know but chances are that it isn't. (If you're intending to sell your product, that is. For research or recreational uses it probably is.)
Is it okay technically? If you know what you're doing, it can be.
Does it make sense though? How hard it is for the client to install another VM or just replace your hacked rt.jar with an unhacked one?
And on a more abstract level: is it a good idea to treat your customers like potential criminals? To assume that the first thing they're going to try is to hack your system. (Mind you, I don't know your customers, so you might as well be right, but the question is worth asking nevertheless.)
Related
I need to activate SO_KEEPALIVE on an existing commercial java application because my firewall drops the connections after some inactivity. I do not own the source code so i can't change it (it would be rather easy when i had the source, just adding socket.setKeepAlive(true) ). So i was looking for some alternatives:
first i tried to work with libkeepalive.so ( http://libkeepalive.sourceforge.net/ ), putting this in de LD_PRELOAD seems to work for things like telnet & nc, but when i use it with my jrockit jvm, this LD_PRELOAD is totally ignored and every socket object is still being created without SO_KEEPALIVE
then i tried to search on the OS level if there was an option to activate this SO_KEEPALIVE per default for all TCP connections: unfortunately on redhat 6 enterprise there isn't such an option, although i found one for freebsd (net.inet.tcp.always_keepalive)
patching the linux kernel for adding this feature was a big no for my sysadmin ;)
searching for any java command line argument was unsuccessful
so last option: patching the existing JVM's java.net.PlainSocketImpl by adding setOption(SocketOptions.SO_KEEPALIVE, Boolean.valueOf(true)); in the protected synchronized void create(boolean stream) method and putting it before rt.jar via -Xbootclasspath/p
This last option works so far, but i'am a bit frustrated because i had to change a JVM for this! Anyone knows other / better ways to deal with such a problem? Why isn't there another simple way to activate SO_KEEPALIVE per default on all (java) applications?
Last question: why doesn't the java API let you set the keepAlive on serverSockets objects? It's only possible on Socket objects but in fact it also works on serverSockets
I run over the same problem and wondered why libkeepalive does not work. After some investigation I found, that libkeepalive has some 'limitations' (maybe somebody would call them bugs).
Because of the strange license (it comes with GPL), I decided to start over. The result is the libdontdie.
You can find a small Java test program there that works with (at least) openjdk7.
It is possible to redefine existing bootstrap classes during runtime using a java agent (http://docs.oracle.com/javase/6/docs/api/java/lang/instrument/package-summary.html) and ASM4 (http://asm.ow2.org/).
As you know the target class and method, all that is needed is to catch the return bytecode instruction of the relevant method and inject a method call before it.
This is one of the problems with commercial closed source software. If it doesn't work, your options are limited for fixing it. This is a COST of using closed source.
There is one obvious thing that you haven't tried yet.
Contact the support line for the product you are using and ask them to provide a solution for you. There may already be something in the product itself to solve this; e.g. some undocumented configuration option. Or they may be able to develop a custom workaround for your problem.
If customer support is unhelpful, you have a number of potential options:
You could attempt to reverse engineer the relevant part of the product (e.g. the place where it creates sockets), and figure out how to set "keepalive" by:
modifying one of their classes,
subclassing one of their classes, or
writing some kind of hook that uses reflection to dig out the socket objects from private variables, etcetera.
Reverse engineering could be a violation of your license agreement. However, if the reason you do it is to fix a problem in their code that makes it unusable for you, they would have a hard time convincing a court that what you were doing deserved to be punished. And the "court of public opinion" would most likely punish them if they tried that.
You could check your rights under your license agreement and relevant consumer protection law. Is the product "fit for use" if you can't get it to work for you?
You could threaten to cancel your support contract and stop using their product.
You could actually cancel your support contract and stop using their product. (And if you use a different product, prefer open source so that you don't get into the same bind all over again.)
The problems with your solution that "works" are:
You may have to repeat this every time you refresh your JVM.
It may interfere with other things in the application ... or other applications that use the patched JVM.
You can't redistribute this without violating your Oracle license ... unless you are using OpenJDK.
It is likely to make other folks who need to support your stuff nervous. (Understandably).
Last question: why doesn't the java API let you set the keepAlive on serverSockets objects?
You would need to ask the folks who designed the API. (Good luck with that!)
If you believe that this could and should be done, submit an RFE via the Java Bugs Database. Or better still, implement it yourself as patches to the latest OpenJDK codebase, and contribute the patch. Unlike your unnamed commercial product, Java is (basically) Open Source, and they welcome useful patches that improve the product.
I want to keep only java util, io, nioand math packages and want to remove all other packages like java.sql and others from my JDK.
How can I remove them?
So if I write some program which import removed packages it will give
error package doesn't exist.
Use a SecurityManager instead of hacking the JDK
I'm going to give you the best answer I can.
Why you really shouldn't be doing what you want to do
When you're writing code, it is commonly agreed to develop that code in a way that is extendable. That is, your code can be plugged into other applications, or it can be changed and added to, very easily. Now with that principle in mind, let's review what happens when you delete the possible functionality of your program. Say you delete the SQL package, and in the future, you want a backend database to provide some persistence in your program. You're screwed.
The idea of Java, in fact I'd go as far as to say the major advantage of Java, is it's commonality, consistency and standardization of patterns. A getter is always a getter. A variable (that isn't a constant) starts with a lower case letter. Classes have a standardized way of being structured. All these things make developing in Java quite intuitive.
The JDK is part of that consistency, and to edit it is to really impact one of the major points of Java. It sounds like you want to implement your program in a different, more compact language.
Finally, you have no idea how the client may want to extend your project in the future. IF you want to have some repeatable business from the client, and generate a good reputation at the same time, you want to design your code with good design practise in mind.
There is no such tool, AFAIK.
Removing stuff from the Java libraries can be technically tricky, 'cos it can be difficult to know if your code might directly or indirectly use some class or method.
There are potentially "licensing issues" if you add or remove classes from a JRE installer, and ship it to other people.
Concerning your proposed use case.
If you are building this as a web application, then you are going to have a lot of difficulty cutting out classes that are not needed. A typical webapp server-side framework uses a lot of Java SE interfaces.
If you accepted and ran code someone who wanted to try and bring down your service, they could do it without using only the Object class. (Hint: infinite loops and filling the heap.) Running untrusted code on your server is a bad idea. Period.
Think about the consequence for someone trying to run legitimate code on your server. Why shouldn't they be allowed to use library classes / methods? (I'd certainly be a bit miffed if I couldn't use "ordinary" library classes ...)
My advice would be reconsider if it was a good idea to implement such a service at all ... given the risks, and the difficulty you could have if your safeguards were ineffective. If you decide to proceed, I advise running the untrusted code within the JVM in a security box. As a second level of defence in case Java security is compromised, I'd recommend running the service "chrooted" or better still in an isolated virtual machine that can be turned off if you run into problems.
There are a lot of packages built in the jdk, and the size of jdk is biger and biger. But I found there are a lot of packages I never used, or they have a better 3rd party replacement.
So, which packages do you think can be removed from JDK, or we don't need to use them?
So, which packages do you think can be removed from JDK, or we don't need to use them?
Unless you mean this as an subjective question of what "we think is superfluous" (in which case the question should and will get closed quite quickly), you are the only one able to tell which packages you don't need.
I'm not sure though, why you would want to strip down the JDK. The JRE would perhaps make more sense to strip down on a system with really limited resources. If you wish to do this, Google provides many good urls.
So, which packages do you think can be removed from JDK, or we don't need to use them?
I don't think a cut down JRE is a good idea.
Lets think about the reasons why you might want a cut down JRE:
"The size of a JRE is getting bigger". But the size of hard disks is getting bigger more quickly.
"The size of JRE installers is getting bigger". But the speed of networks is getting faster more quickly.
"The JRE is using more and more memory". Most likely it isn't. A running Java application only loads the JRE classes that it actually uses. A command line "hello world" program does not pull in Swing, CORBA support, the XML parsers, or anything else that it doesn't use.
"But it is using too much memory". Really? If you think so, consider using Java ME .... and learn to live with the downside of a cut-down class library.
And to answer your question. I don't think any of them should be removed. They are all useful to a lot of people some of the time. And if any of these packages were removed, from the standard JRE it would break compatibility for many, many existing applications.
And the packages cost very little in the case where they are not actually needed. At least, not in most use-cases.
In reality, Sun/Oracle have done a lot of work to reduce footprints and improve JVM startup times. And last time I looked, more work on this was on the agenda for Java 8.
If you are considering doing this for yourself, here is some free advice:
DON'T DO IT.
IANAL, but I understand that creating and shipping a cut-down binary version of the JRE is a violation of the Java software license, and of the conditions under which you are permitted to use trademarked terms like Java, JRE and so on.
The first thing that comes to my mind is the project Jigsaw I'm not sure whether it is still active, but should still be a good starting point.
I am curious about what automatic methods may be used to determine if a Java app running on a Windows or PC is malware. (I don't really even know what exploits are available to such an app. Is there someplace I can learn about the risks?) If I have the source code, are there specific packages or classes that could be used more harmfully than others? Perhaps they could suggest malware?
Update: Thanks for the replies. I was interested in knowing if this would be possible, and it basically sounds totally infeasible. Good to know.
If it's not even possible to automatically determine whether a program terminates, I don't think you'll get much leverage in automatically determining whether an app does "naughty stuff".
Part of the problem of course is defining what constitutes malware, but the majority is simply that deducing proofs about the behaviour of other programs is surprisingly difficult/impossible. You may have some luck spotting particular patterns, but on the whole you can't be confident (and I suspect it's provably impossible) that you've caught all possible attack vectors.
And in the general sphere, catching 95% of vectors isn't really worthwhile when the attackers simply concentrate on the remaining 5%.
Well, there's always the fundamental philosophical question: what is a malware? It's code that was intended to do damage, or at least code that doesn't do what it claims to. How do you plan to judge intent based on libraries it uses?
Having said that, if you at least roughly know what the program is supposed to do, you can indeed find suspicious packages, things the program wouldn't normally need to access. Like network connections when the program is meant to run as a desktop app. But then the network connection could just be part of an autoupdate feature. (Is autoupdate itself a malware? Sometimes it feels like it is.)
Another indicator is if a program that ostensibly doesn't need any special privileges, refuses to run in a sandbox. And the biggest threat is if it tries to load a native library when it shouldn't need one.
But all these only make sense if you know what the code is supposed to do. An antivirus package might use very similar techniques to viruses, the only difference is what's on the label.
Here is a general outline for how you can bound the possible actions your java application can take. Basically you are testing to see if the java application is 'inert' (can't take harmful actions) and thus it probably not mallware.
This won't necessarily tell you mallware or not, as others have pointed out. The app could still do annoying things like pop-up windows. Perhaps the best indication, is to see if the application is digitally signed by an author you trust; if not -- be afraid.
You can disassemble the class files to determine which Java APIs the application uses; you are looking for points where the java app uses the OS. Since java uses a virtual machine, there are well defined points where a java application could take potentially harmful actions -- these are the 'gateways' to various OS calls (for example opening a socket or reading a file).
Its difficult to enumerate all the APIs, different functions which execute the same OS action should require the same Permission. But java's docs don't provide an exhaustive list.
Does the java app use any native libraries -- if so its a big red flag.
The JVM does not offer the ability to run arbitrary code, or use native system APIs; in particular it does not offer the ability to modify the registry (a typical action of PC mallware). The only way a java application can do this is via native libraries. Typically there is no need for a normal application written in java to use native code (unless it needs to use devices).
Check for System.loadLibrary() or System.load() or Runtime.loadLibrary() or Runtime.load(). This is how the VM loads native libraries.
Does it use the network or file system?
Look for use of java.io, java.net.
Does it make system calls (via Runtime.exec())
You can check for the use of java.lang.Runtime.exec() or ProcessBuilder.exec().
Does it try to control the keyboard / mouse?
You could also run the application in a restricted policy JVM (the instructions/tools for doing this are not as simple as they should be) and see what fails (see Oracle's security tutorial) -- note that disassembly is the only way to be sure, just because the app doesn't do anything harmful once, doesn't mean it won't in the future.
This definitely is not easy, and I was surprised to find how many places one needs to look at (for example several java functions load native libraries, not just one).
How does one secure the Java environment when running on a machine you don't control? What is to stop someone from creating a java agent or native JVMTI agent and dumping bytecode or re-writing classes to bypass licensing and/or other security checks? Is there any way to detect if any agents are running from Java code? From JNI? From a JVMTI agent?
If you don't control the environment, then I'm sorry - you're really stuck. Yes, you could look for trivial JVMTI agents via some sort of cmdline sniffing, but that's the least of your worries. Think about java/lang/Classloader.defineClass() being compromised directly. That's easy to do if you own the box - just replace the .class file in rt.jar. In fact, until JVMTI came around, that was a typical way that profilers and monitoring tools instrumented Java code.
Going back to JVMTI - the "Late attach" feature also allows for JVMTI agents to be loaded on the fly. That might not have happened when you scanned the first time around.
Bottom line - if someone can change the bytes of the JRE on disk, they can do anything they want. Is it ethical, no? Can they get caught? Possibly, but you'll never win the war.
It looks like I can go with a combination of checks inside some custom JNI native code.
1.) cmd line sniffing to search for agents.
2.) Ensure that the cmd-line parameter -XX:+DisableAttachMechanism exists. (this will prevent people from attaching to my running VM)
I remember I once made almost a silent Java Agent. I guess you better look for port scanners or something around that.
Java 2 security, signing of jars etc, gives some level of control over what gets loaded into your application.
However in the end if a malicious person has access to a machine such that they can write to disk then in all probability they have plenty of capacity to do harm without resorting to clever Java hacks.
Turn this round, in any language what can you do to detect Trojans?
Careful access control to the machines you care about is non-trivial but essential if you are serious about such issues. Security specialists may seem paranoid, but that often means that they really understand the risks.
If you can't control the platform, you can't control the software upon it.
Even if you could shut down all the avenues of inspection you've listed, Java is open source. They could just take the source code and recompile it with the necessary changes built-in.
Also, try to remember that while it is your code, it's their machine. They have a right to inspect your code to verify that running it on their machine does what they expect it to do, and doesn't perform "extra" actions which they might find undesirable. Less trustworthy companies in the past have scanned for non-relevant files, copied sensitive information back to their home servers, etc.
I would look at the command line and see, if there are any "-agent" parameters. All profilers, debuggers and other code modificators use this for introspection. You could also check for unusual jars on the bootclasspath, since those might also provide a threat (but be aware that you then also must deliver a custom JVM, since some software like Quicktime adds itself to the bootclasspath of ALL java apps running... (I couldn't belive my eyes when I saw that...))
Basically this is a loosing battle.
Have a look at how visualvm in the Sun JDK works and how it can attach to a running process and redefine whatever it pleases. It is extremely hard to detect that in a portable way, and unless you can do so, you might as well give up on this approach.
The question is, what is it you want to avoid?