Java code, Being Secure - java

I am creating a client program that talks to a server (which I programmed). I am making a little game for myself in which I roll a dice and the server does also. Whoever gets the higher numbers wins. However within my code, I send the server commands when the user presses a button, and then the server responds by sending back what it rolled, so it can be shown in the GUI window. However, I find this a very insecure method. For example, a person could just simply decompile the jar file, and make it so they always roll a 12. Since the only place that both rolls are together (the users and the servers) is the users screen, I have to evaluate the game from the client, obviously not very secure. I am trying to make my game more secure, and have found 2 options.
Obfuscators
Unless someone knows of a very easy one to use, I cannot figure out how to set any of them up, as they rarely come with a gui that I can easily "pop" my .jar file into
Binding to an .exe
I honestly dont know how secure this is. There are programs in which I can "bind" two things (mostly for making viruses which I am obviously not doing), into a single .exe file. I can bind my .jar into an .exe, but I still dont know if the .exe could be decompiled back into the .jar file and from there back into the .java code.
By the way, another security issue is that it connects to the server from my ip adress (which I do not want the client user to know about)

Never trust client input.
The only truly "secure" method is to have the server generate both its own roll and a roll for the client.
Of course, if the outcome of the comparison of the rolls has no impact beyond what the user sees (in other words, the client does not report back who won), then really, who cares? I could patch Solitaire to let me always win, but that's no fun.

If the code is on someone's computer, you should consider it compromised and exploited already. In the race between crackers and developers, the crackers always win because the crackers have everything they need. Jars can be (easily) decompiled and deobfuscated, .exes can be picked apart, and at extreme levels the OS can be modified to go behind your back - literally.
Instead, you should reconsider your architecture: do you really need the client to roll the dice? Could the server roll both?

Both obfuscation and compiling to a ".exe" can be defeated relatively easily. Hackers / crackers, and anti-virus security experts do this kind of thing every day.
Basically, you cannot trust any application that is running on any machine that could be controlled by someone you don't trust. In practice, this means anything that isn't in your (locked and firewalled) server room.
(Aside: even systems based on TPM are potentially vulnerable, since there have been successful attacks on TPM chips. And that wouldn't be practical anyway, since TPM is not available for securing application-level code. AFAIK, it is not even used at the OS level ... though I've heard that the next version of Windows is going to require hardware that is TPM encumbered.)

Related

How to check that my jar file is not modified?

I hope you're doing well in these complicated times, good containment all around :D
So I come to my problem, currently I'm working on a game in Java and I know that it's possible to modify the jar file of my game which annoys me a little bit because it can give cheating possibilities for malicious players... I had thought of a solution even if it's not infallible, it would be to make sure to check if the jar file has not been modified. But the problem is that I don't know how to check this, I had thought of a system that would check the point of the file even if I doubt it would be the best solution.
If you have any other ideas to secure my game I would be interested :D
It is possible to check if a JAR file on your machine has been modified. Simply compare a cryptographic hash of the current JAR file with a previously recorded hash for a pristine copy. (Or just do a byte-by-byte comparison with the pristine copy.)
But you can't do this for JAR file on the user's machine:
You can't login to the user's machine and access their file system to look at the JAR file. (Even if you could, there is no guarantee that you would see the file that the cheater is actually using.)
If your application (running on the user's machine) tries to report on the integrity of its JAR files, this can be defeated by the cheater. All they need to do is to modify the JAR file containing the reporting code to report a fake hash.
Basically, there is no reliable way to detect that a cheater is running a modified JAR ... apart from detecting the anomalous behavior of the cheat itself.
But think of it this way. If there was a good (reliable, no circumvention) mechanism for detect that a cheater is running a modified client, then cheats would not be a problem in the many online games that exist out there. And (by extension) there would be no way to defeat software license enforcement schemes ... because software vendors would use a similar mechanism.
So, my advice would be not waste too much time on this approach. It only works against people with limited technical expertise or limited motivation.
The only way to completely prevent cheats is to control the platform on which the client runs. That is usually impractical.
In regards to your question about other ideas, the best thing you can do is validate everything from the client. One thing you should always remember is that the client cannot be trusted because you cannot verify anything from it. All you can do is store the state on a remote server and when the client tells you something, validate it, and give a response if necessary or prevent the action if necessary.
You will need to somehow find out where the jar file is: Java - Search for files in a directory
Then you can check for the last modified date of the file: https://www.boraji.com/java-get-last-modified-date-of-a-file
However, I would not consider this a very powerful defense against cheating, because one can modify the jar file and remove the validation of the file date.
You will need to think about the kind of cheating that can occur and to come up with other security measures as well.
EDIT
As Dave Thompson pointed out, the modified timestamp can be changed as well, which makes the modification of the jar file unnecessary, even though reverse engineering is still needed by the hackers, because that's how they find out what the rules of the application are.

Prevent application from being copied/generate activation password

I made a Java (on IntelliJ IDEA) application and I want to give it to someone via USB or Dropbox.
However I don't want him to give it to someone else, like you know, he downloaded the file, so he can copy/paste it to his USB and give it to more people.
Is there any way to prevent the application from being copied after I give him the application? At first I thought of making a login window, but then I thought "hey, if he knows the password to login to application, he can just give the application to someone and give him the password as well", so login window is not an option (I think?). Can I disable the copy/cut functions with If statements after being copied once?
Or I can only prevent it by linking my application with a database and generating unique passwords to activate my application? Like for example, someone requested to use my application, so I will give him the application but he won't be able to run it. Then I generate a password and sent him the password. However that password can only be used once so if he will try to use the same password on 2 different PCs, it will give him an error. Is there any guide/tutorial/tips of making something like that on Java?
You could create some kind of "activation code" for your software that is generated based on some information about the hardware it's running on. I've seen some people using, for example, the MAC address, that you can obtain in a platform-independent way in Java.
However, keep in mind that those techniques will only work against the most basic users. MAC addresses can be easily changed by anyone that knows how to use Google and even if you use something incredibly complicated instead of MAC addresses, Java programs are dead simple to decompile and once the attacker knows what function is checking if the program is correctly activated, he/she can easily replace it. Yes, you can obfuscate your bytecode, but it only makes the task a little harder, not impossible.
You can do what you suggested and use passwords that can only be used once, but then your program needs to know that it has been activated, by storing that information somewhere (a file or something like that). And once the user knows where that information is stored, it can be replicated on other computers.
Unfortunately, once the user has your program, you have no control over what he/she can do. You can make sure that the user is not going to do stuff he/she is not supposed to do with your program by not giving him/her the program at all. You can, for example, expose your program's features through the web. But, as you said, nothing stops an user from sharing login credentials with another person. Yes, you could check if the user is accessing the page from a different IP address, but then a legitimate user could have problems when, for example, accessing your program from a different wifi network. And in this case, your protection not only fails in solving the problem, but also becomes annoying to a honest user.
In summary, brilliant engineers at huge software companies have been working on protections for their software for years and I'm yet to see a software that cannot be illegally activated given enough time and effort.

Preventing fake client data Java?

I am writing a plugin for the popular Minecraft server software, Bukkit.
My plugin will require sending player scores to my server, to work out a global leaderboard.
Seeing as Java can be decompiled, someone can decompile the plugin, and find out how it works (It's open source anyway). I am looking for a method of sending data to my server (player scores), in such a way so it can not be spoofed, and the leaderboards cannot be rigged.
I was considering making the plugin's users (server owners) sign up to the leaderboards site, and then use their own username/password combination to connect to my leaderboards. If it was abused, I could simply block that server from the leaderboards. This is not the most efficient method however, as I would have to administrate the joins and approve the amount of kills.
How would I go about making sure the client (Bukkit Server Plugin) can't spoof kills?
If your concern is that a legitimate user is educated enough to decompile your jar, understand your code and figure out how to send wrong data from your plugin, authentication methods are of no use (the user is already legitimate) and I assume the logic that calculates what you want can not reside in the server. In this case your best option would be to obfuscate your code
Making it open source is what's stopping you. If it was closed source you could obfuscate your jar and it would be much harder to decompile your code.
If you still want it to be open source, you could keep an eye on rapidly growing servers or very high scored servers. But like you said, that's very inefficient.
Post on the Bukkit forums, they might have a better answer for you.

Call Unix Shell commands from Servlet/JSP

I need to call some Unix commands from my Servlet.
I have some Perl script, but I want to "translate" them into Java.
Here is something that I want to do on Java, but that I've made in Perl:
system("myfolder/myscript.sh > /myfolder/logs/myscript.log");
Is it possible to do this on a Servlet?
Yes, but note that redirect is part of the shell you will want:
ProcessBuilder pb =
new ProcessBuilder("/bin/sh", "-c", "myfolder/myscript.sh > /myfolder/logs/myscript.log");
pb.start();
Short answer:
it's possible but it's bad design, and can pose a security risk.
better to flag somehow that the script needs to run and check the flag via script
Long answer (following the commments):
Servlets are usually used to provide a user interface (or api) to something, for example accessing data or in your case triggering an action. As such, they imply the possibility of access from a remote resource such as a remote computer. In some (actually most) cases, that remote computer may even be out of the network, for example somebody's home.
Every server which is exposed to the outside world has the potential of being hacked or attacked in some way, with the risk being directly related to the level of interest this resource poses.
For example, if you work for a big company (which is then noticeable by hackers), and this servlet is used to trigger a build in your local repository, and you decide that developers will be able to work from home and need to login in order to trigger a build or check their build status, it means that anyone with the right credentials can potentially access the servlet, from anywhere in the world. Now lets assume that your perl script needs to access your CI server for some data, and your source repository for another data (maybe it even copies the sources instead of letting the CI server do it). In this case, you just created a direct link between someone sitting somewhere in the world, to the company's source code. It also means that even if it's too hard to penetrate your incredibly secure service because you spent a vast amount of time closing all potential gaps, they may still be able to trigger many unnecessary builds, and if you work in Continuous Deployment even make those builds go to production (maybe causing a DOS attack or service disruption). If at some point someone decides that the script also needs to get a parameter from the servlet, you've even made the hacker's life easier and could eventually give him access to your system.
All I described in the previous paragraph may be completely irrelevant to your case, you might be developing a service which will run on your home computer and won't interest anyone but yourself, but this does not change the fact that this is bad design (which might be ok for home use by the way).
What I said in the short answer is that it's better to have servlets flag the system that an action is needed, for example set a flag in DB or even in a file, in this case a hacker's life would be much more difficult, as there's no direct link. This also makes the servlet respond immediately, possibly automatically updating on status, instead of waiting for the perl script to finish running.
Did u try Jsch.It can do ssh and execute shell commands.

Installed Programs/Computer Info for Web Application

I'm currently developing a support system for a university. The system is written in PHP and I would like to be able to get a current list of software and basic computer information on a computer. Basically when one of the faculty or staff creates a ticket from our web interface, I would like to have a Java Applet or similar that could be run and would return the information to the help desk PHP script. Does something like this exist?
There are lots of programs that do this sort of thing. Googling for "CMDB" should give you a reasonable start -- a couple of them are open source, though others aren't even close to free (e.g., BMC Atrium).
To keep things closer to topical (i.e., programming related), one of the main frameworks for this sort of situation is called Web-Based Enterprise Management (WBEM). On Windows this is implemented as WMI. On Linux there are a couple of implementations including OpenWBEM and HP WBEM.
In Java? You'd probably have a hard time even finding, let alone making, an applet that can get that info without already having some software installed on the user's end. The biggest features of java are (1) that it runs in a virtual machine (read: getting to the underlying OS/hardware is not something it likes to do), and (2) that in a browser, applets generally run in a "sandbox" that keeps the applet from doing anything remotely dangerous. Basically the most it can do is tie up resources.
Number 2 can be worked around by signing the applet, but that'll require you either buy a code signing certificate or install a self-signed certificate on any computer that'll run your app.
Number 1 might be worked around with some help from Runtime.exec and ...\wmic.exe, but that assumes the WMI stuff is installed -- which is rarely the case unless someone does a full install.

Categories