一个合法程序的反病毒检测

22

基本上,我的程序与另一个jar文件一起运行。这是下载函数的代码:

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();
        }
    }
}

开始新过程的第一步

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

然而,即使有用户提示并需要批准下载,当我在eclipse环境外进行测试时,我的反病毒软件立即检测到了它。

它被检测为“trojan.downloader”。我认为这可能与下载功能有关?我并不是真的想打败反病毒程序。我没有试图做任何非法的事情。

也许一些混淆会起作用?


2
我认为你已经实现了一个基本病毒:一个应用程序,它会加载可执行文件并执行它。你尝试过其他环境或杀毒软件吗?也许只是某个杀毒工具的问题。 - Christian Kuetbach
1
你的代码存在问题,任何在同一台计算机上运行的程序都可以轻易地在运行时劫持你的“已批准”代码,并更改例如下载另一个可执行文件的URL。这必须被绝对避免。通常,你需要提供一个单独的更新程序,例如Windows的.msi,该程序可以进行认证等,并在运行时进行内存保护(因为你可能会以管理员权限运行它)。 - BeyelerStudios
@BeyelerStudios 嗯,那其他程序如何检测和安装升级,比如Firefox、Skype等等? - Robert
1
你需要安装它们,它们在后台运行单独的更新服务 - 或者需要你在管理员模式下执行更新命令(弹出管理员密码窗口)来运行它们的安装程序 - 最重要的是:它们不是在Java中运行,也不会下载代码并执行。 - BeyelerStudios
如果是Skype M$,每次操作系统自动更新时都会强制升级您的系统。 - BeyelerStudios
显示剩余2条评论
5个回答

12

您的编译器生成的字节码符合 AV 寻找的某些特定代码模式/签名,这意味着他们在过去发现/逆向的某些恶意软件具有类似于这个代码的可靠性。

最好的选择是识别和重写触发检测的任何方法,直到它不再与 AV 寻找的内容匹配。混淆并不是解决此问题的好方法(但如果混淆器进行控制流混淆,则可以执行),因为无法保证它会产生与原始字节码不太相同的字节码(某些混淆器,如 ProGuard,甚至不执行控制流混淆)。


1
很奇怪的是它不再被检测到了。有人私信我建议我随意更改名称并添加一堆假字符串和垃圾代码,其中包括不起作用的方法调用,以便绕过它。实际合法的实现方式是什么?我无法为我的应用程序获得官方证书(这不需要花钱吗?)。 - Ben
1
@Ben 你想要实现什么功能?你是想在你的应用程序中添加自动更新的功能吗? - biziclop
是的,只是一个自动更新功能。在调用这个类之前就有用户输入,所以它不会在没有用户批准的情况下进行更新。 - Ben
1
@Ben,问题不在于用户的批准,而在于你盲目地信任返回的内容。虽然这在内部网络中可能有效(尽管即使在那里也有点靠不住),但如果你从互联网上下载东西,任何人都可以劫持连接或黑掉你正在下载的网站。缓解这种情况的方法是使用HTTPS加密连接并验证服务器的身份,还要确保下载的代码也被签名。 - biziclop
好的,我刚刚完成了这个实现。客户端程序会生成一个Base64编码的密钥,并将其返回给服务器构建器。然后服务器构建器会生成一个密钥文件和我想要执行的可执行文件。接着,在客户端程序中,它会比较密钥文件和生成的密钥,并执行应用程序。 - Ben
取消那个计划。我会添加某种身份验证来防止中间人攻击,但如果用户的系统已经被入侵,没有什么可以保护他们。 - Ben

3
你可以尝试使用代码签名证书(例如来自 Digicert)对JAR文件进行签名。
这样可以以可信的方式将公司名称添加到JAR中,从而被防病毒程序信任。但是,并不保证每个防病毒程序都会这样做。
请注意,这样做也会产生一些影响:
- 可能会进行CRL(证书吊销列表)检查。这将从互联网下载数据。如果计算机有物理网络连接(本地),但没有互联网连接,则可能会遇到显着的超时。 - 您需要熟悉时间戳,否则在证书过期时签名将变为无效状态。

1
是的,我知道这一点,但对于一个完全免费的项目来说,这需要花费大量的资金。 - Ben
1
@Ben:感谢您的反馈。像“我尝试过证书,但它们太贵了”这样的信息最好添加到问题中,因为它会缩小答案的范围。无论如何,我会把它留在这里供其他能购买证书的读者参考。 - Thomas Weller

2

反病毒厂商会寻找比特中的模式,如果与数据库中已知的匹配,则会将其标记为有害。当然,这给开发者/公司(小型/大型)带来了问题。

一些厂商有自动机制来标记“误报”。请使用适当的渠道报告此类情况。

以下是一些起点。辛达诺AVG

对于某些情况,您必须通过其他方式联系厂商:例如http://www.avast.com/contact-form.php?subject=VIRUS-FILE

VirusTotal正在研究一种更简单的标记方法-我想尚未投入生产

无论如何,其他答案中提到的选项并不总是有效。我们使用更新的编译器和最新的API创建了更新的可执行文件。还尝试了签署可执行文件。所有这些都提高了程序成为“反病毒”程序的可能性。但是,最合适的方法是检查厂商。Th


0
我将把这个作为答案添加。让你的程序合法签名将为您解决此问题。您也可以伪造签名,但是像ESET这样的反病毒软件几乎会立即发现这一点。
最好的解决方法是诚实地尝试欺骗反病毒软件。更改所有字符串名称...添加一堆不起作用的虚假字符串。
int asdgsal = 1 + 2; 

还可以添加几个循环方法调用,这些方法基本上什么也不做。

对我来说是有效的。虽然它有点靠不住,可能会被试图实际造成伤害的人利用,但它确实有效。

另外,不要下载到临时文件夹或appdata中。将其放在%userprofile%或我的文档中,就可以安全使用。


1
编译器应该在发布版本中优化这样的语句。或者你提供调试版本吗? - Thomas Weller

0

我认为你可以使用多个文件进行测试,找出是否所有文件都无法下载。如果所有文件都返回相同的结果,那么我认为问题出在你的代码上。这时你可以参考其他人的代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接