22

Basically, my program runs along side another jar file. Here is the code for the download function:

public void saveUrl(final String filename, final String urlString) throws MalformedURLException, IOException {
    BufferedInputStream in = null;
    FileOutputStream fout = null;
    try {
        in = new BufferedInputStream(new URL(urlString).openStream());
        fout = new FileOutputStream(filename);

        final byte data[] = new byte[1024];
        int count;
        while ((count = in.read(data, 0, 1024)) != -1) {
            fout.write(data, 0, count);
        }

    } catch (Exception e) {
        return;
    } finally {
        if (in != null) {
            in.close();
        }
        if (fout != null) {
            fout.close();
        }
    }
}

And the to start the new process

public void runUpdate() throws IOException{
    String folder = fileLocation;
    ProcessBuilder p = new ProcessBuilder();
    p.command(folder);
    p.start();
}

However, even with user prompts and having to approve the download, when I tested it outside of the eclipse environment, my anti-virus picked it up right away.

It was detected as a "trojan.downloader". I'm thinking it has something to do with the download function? I'm not really trying to beat an anti-virus program. I'm not attempting to do any illegitimate.

Perhaps some obfuscation would do the trick?

Danielson
  • 2,605
  • 2
  • 28
  • 51
Ben
  • 749
  • 1
  • 7
  • 18
  • 2
    I think you have implemented a basic virus: An application, which will load an executable and executes it. Have you tried other environments or antivirus software? Maybe it is a problem with only one antivirus tool. – Christian Kuetbach Jun 25 '15 at 16:15
  • 1
    the problem with your code is that any programme running on the same computer may easily hijack at runtime your "approved" code and change for example the url to download another executable. that must be avoided at all cost. usually you'll have to provide a separate update programme, e.g. a .msi for windows, which can be certified etc. and memory-protected at runtime (since you'll probably run it with admin privileges) – BeyelerStudios Jun 25 '15 at 16:18
  • @BeyelerStudios Hm, then how do all those other programs detect and install upgrades, like Firefox, Skype, and so on? – Robert Jun 30 '15 at 14:53
  • 1
    you were required to install them, they run separate update services in the background - or they require you to execute an update command in administrator mode (the admin-pw popup) to run their install - and most important: they're not running in java, nor downloading code and executing it – BeyelerStudios Jun 30 '15 at 14:59
  • or in case of Skype M$ simply forces an upgrade onto your system every time your OS autoupdates – BeyelerStudios Jun 30 '15 at 14:59
  • @BeyelerStudios That's exactly what they are doing though. Lets say spotify prompts you for an update. You hit yes and it downloads, prompts you to restart and then executes. Which is exactly what I do. The difference is they are on approved lists on pretty much any anti-virus and also use digitally signed certificates. – Ben Jul 02 '15 at 00:55
  • they don't download code and execute it - replacing a dll and restarting your programme requires the programme downloading the resource to have the rights of overwriting an application specific resource - you either gave that right to your programme during installation or during the update - or the application loads dlls from very questionable places on your computer - which is a security thread in itself – BeyelerStudios Jul 02 '15 at 10:25

5 Answers5

12

The bytecode generated by your compiler matches some specific code pattern/signature the AV is looking for, meaning some malware they had found/reversed in the past had code similar to this that they could reliably find.

The best option would be to identify and rewrite whichever method is triggering the detection until it no longer matches whatever the AV is looking for, obfuscation would not be a good idea (but can be done, if the obfuscator does control flow obfuscation) for fixing this problem as there's no guarantee it would produce bytecode different enough from the original (some obfuscators, like ProGuard, also do not even do control flow obfuscation).

Alan
  • 468
  • 3
  • 9
  • 1
    What's weird is that it doesn't get detected anymore. Someone PM'd me and suggested that I just changed random names around and add a bunch of fake strings and junk code with method calls that do nothing in order to get around it. What's the actual legitimate way to implementing this? I can't really get an official certificate for my application (doesn't that cost money?). – Ben Jun 25 '15 at 19:01
  • 1
    @Ben What are you trying to implement? Are you trying to add some kind of auto-update feature to your application? – biziclop Jun 25 '15 at 19:08
  • Yeah just an auto-update feature. There is user input before it even calls this class, so it's not like it is updating without user approval. – Ben Jun 25 '15 at 19:11
  • 1
    @Ben It isn't the user approval that is the problem, it's the fact that you blindly trust whatever is returned. While that may work on an intranet (though even there it's a bit iffy), if you're downloading something from the internet, anyone can hijack the connection or hack the website you're downloading from. The way to mitigate this is to use HTTPS both to encrypt the connection and to verify the server's identity and also make sure the downloaded code is signed too. – biziclop Jun 25 '15 at 19:15
  • Alright so I just implemented this. The client side program generates a base64 encoded key that is returned to the server builder, which then generates a keyfile and the executable that I want executed. Then on the client side program it compares the keyfile to the generated key and executes the application. – Ben Jun 25 '15 at 19:31
  • Cancel that actually. I'll add in some sort of authentication that will prevent man in the middle attacks, but nothing is going to protect the user if their system is already compromised. – Ben Jun 25 '15 at 19:37
3

You can try to sign your JAR with a code signing certificate, e.g. from Digicert.

This adds your company name to the JAR in a trusted way and thus could also be trusted by the Antivirus program. However, there's no guarantee that every Antivirus program will do so.

Note that there is also some impact of doing so:

  • CRL (certificate revocation list) checks might be done. This will download data from the Internet. In case the PC has a physical network connection (local) but no Internet connection, this may run into a significant timeout.
  • You need to become familiar with timestamping, otherwise the signature becomes invalid when the certificate expires.
Thomas Weller
  • 55,411
  • 20
  • 125
  • 222
  • 1
    Yeah I'm aware of this, but it does cost a large amount of money for a completely free project. – Ben Jul 02 '15 at 00:57
  • 1
    @Ben: thanks for the feedback. Information like "I have tried certificates, but they are too expensive" is best added to the question since it narrow the scope of answers. Anyway, I'll leave it here for other readers who can afford certificates. – Thomas Weller Jul 02 '15 at 07:18
2

Anti-Virus vendors look for patterns in bits; if anything matches with known ones in database, they will flag it as bad. Ofcourse this has created problems to developers/companies (small/big)

Some vendors have an automated mechanism to flag "false-detection". Please use appropriate channel to report such cases.

For starters, here are some.symantec or avg

For some you have to contact the vendor by other means:For example http://www.avast.com/contact-form.php?subject=VIRUS-FILE

VirusTotal is working on an easier way to flag -Not yet in production, I guess

In any case options mentioned in other answers does not work always. We created updated executables with newer compiler and recent APIs. Also tried with signing the executable. All these improves the chance of program being a good one for "anti-virus" program. However, most appropriate way is to check with the vendor. Th

Jayan
  • 18,003
  • 15
  • 89
  • 143
0

I'm going to add this as an answer. Having your program legitimately signed will fix this issue for you. You can also fake a signature, but anti-viruses such as ESET will pick this up pretty much instantly.

The best work around for this is honestly just try to cheat the anti-virus. Change all of your string names... Add a bunch of fake strings that do nothing such as

int asdgsal = 1 + 2; 

And also add a few looping method calls that do pretty much nothing.

Works for me. It's sketchy and can be abused by people trying to do actual harm, but it works.

Also, don't download to temp or appdata. Throw it in %userprofile% or my documents and you will be fine.

Ben
  • 749
  • 1
  • 7
  • 18
0

I think that you can use many files to test, find out whether all files can't be download. If all files return same. I think that the reason is your code. Then you can refer to other person's code.

simple
  • 43
  • 3