常见的Java漏洞有哪些?

8
什么是可以被利用以获取系统访问权限的常见Java漏洞?我最近一直在思考这个问题,但没有找出很多内容。整数溢出 - 可能吗?竞争条件 - 它给你什么?我不是在寻找像“web应用程序中的SQL注入”之类的东西。我正在寻找类似于缓冲区溢出 - C / C ++的关系。有什么安全专家可以帮忙吗?谢谢。

1
只是出于好奇,为什么您将缓冲区溢出分类为C/C++漏洞?如果Java虚拟机具有相同的漏洞,也可能发生缓冲区溢出。 - Vineet Reynolds
通常,漏洞存在于应用程序中而不是语言本身。 - Jonas
@Vineet:说实话,在你编写的Java代码中创建缓冲区溢出的风险根本不存在;对于C#和其他托管语言也是如此。虚拟机本身发生缓冲区溢出的风险非常低,这消除了99.9%的风险。 - Lawrence Dol
我将BOs指定为c/c++漏洞,因为它们在Java语言本身中不可能被利用 - 被利用的是底层VM/core。该核心不是用Java编写的。我正在寻找解释性语言中的漏洞,这些漏洞对所有Java应用程序都是普遍的,类似于在c应用程序中向已定义的缓冲区使用strcp函数而没有进行健全性检查的关系。我想我并没有将缓冲区溢出定义为c/c++漏洞,而更多地是编程语言与漏洞之间的关系。 - wuntee
1
@wuntee,我们正在谈论什么类型的系统?Java Web应用程序,源代码在客户端机器上运行的应用程序等等?这将有助于更具体地回答您的问题。 - matt b
这更像是一个通用的问题 - Java解释语言存在哪些漏洞... - wuntee
4个回答

5
恶意代码注入。
由于Java(或任何在运行时使用解释器的语言)在运行时执行链接,因此可能在运行时将预期的JAR(相当于DLL和SO)替换为恶意JAR。
这是一种漏洞,自Java首次发布以来一直在使用各种机制进行打击。
以下是一些保护措施:
- 类加载器中有保护措施,以确保java.*类不能从rt.jar(运行时jar)之外加载。 - 此外,可以制定安全策略,以确保从不同来源加载的类仅限于执行某个特定的操作——最明显的例子是小程序。Java安全策略模型约束小程序无法读取或写入文件系统等;签名的小程序可以请求某些权限。 - JAR也可以被签名,并且这些签名可以在运行时加载时进行验证。 - 包也可以被封装以确保它们来自相同的代码源。这可以防止攻击者将类放入您的包中,但能够执行“恶意”操作。
如果想知道所有这些的重要性,想象一下将JDBC驱动程序注入到类路径中,该驱动程序能够将所有SQL语句及其结果传输到远程第三方。好了,我想你现在已经有了画面。

这个概念刚刚浮现在我的脑海中,我本来想提一下的。但是,我很难理解如何利用它...你能提供一个使用案例,说明有人如何注入恶意jar文件吗?很多溢出漏洞都是通过查看网页或处理图像来完成的。也许我只是想错了,这是一种全新的漏洞世界... - wuntee
好的,最后几句话涵盖了这一点。由于Java通常用在行业的企业端,即服务器农场,因此您通常需要一个愿意的系统管理员或被攻击的服务器来完成此操作。我将考虑第二种情况,因为它更有可能发生。想象一下一个面向互联网的服务器,它存在根访问漏洞或类似漏洞,使攻击者能够修改其上任何可能位置的文件。这样的攻击者将能够上传他的恶意负载,出现在javax.sql.*命名空间中(续)..... - Vineet Reynolds
如果他能够用自己的PreparedStatement.class替换掉现有的类,并在rt.jar之前加载它,那么如果存在这样的安全漏洞,他的想象力就可发挥到极限了。他可以记录应用服务器和数据库之间来回流动的所有数据,并可能定期将其上传到外部服务器。值得庆幸的是,目前已经采取了足够的保护措施。 - Vineet Reynolds
为了在这个话题上更有想象力,假设Swing类已经被客户端桌面上的攻击者入侵,并且所有密码字段现在都捕获明文密码并将其上传到另一个站点。这类似于几天前从插件列表中删除的Mozilla“sniffer”恶意软件。在Sun通过引导类加载器机制为java.*和javax.*类引入保护之前,一些这样的攻击是可能的。攻击将使用自定义类加载器执行,该加载器在从rt.jar加载类之前加载攻击者的类。 - Vineet Reynolds
例如,RMI会从远程系统下载存根类的代码。存根类可能是一些恶意的东西。 - stribika
1
作为注入恶意 jar 的例子,可以考虑近期 Spring 框架中出现的漏洞:http://www.springsource.com/security/cve-2010-1622 - Sami Koivu

1

我不是安全专家,但我们公司有一些模块不能用Java编写,因为Java字节码很容易被反编译。我们考虑过混淆,但如果想要真正的混淆,就会带来很多问题(性能损失/丢失调试信息)。

有人可以窃取我们的逻辑,用修改后的版本替换模块,返回不正确的结果等等...

所以与C/C++相比,我想这是一个突出的“漏洞”。

我们还在我们的Java模块中内置了软件许可机制,但这也可以通过反编译和修改代码轻松破解。


1
人们已经在C/C++代码中黑客和关闭软件许可机制30多年了。在Java中更容易吗?当然,但是C/C++并不免于这些问题。如果人们真的想要你的软件,他们会得到它。我宁愿用像Java这样的语言编写我的逻辑,使我的工作更轻松,可以更快地移动并为最终客户创造更多价值,而不是让知识产权的幽灵决定我的语言选择。请记住,几乎所有的事情都不是新的。 - chubbsondubs

1
包含第三方类文件并调用它们基本上意味着您正在运行不安全的代码。如果您没有启用安全性,那么该代码可以执行任何它想要的操作。

同样适用于安装第三方的C或C++库,并调用它们。那些代码可以做比Java代码更多的事情。 - Stephen P

1

阅读了大部分回答后,我认为你的问题已经以间接的方式得到了回答。我只是想直接指出这一点。Java不会遭受与C/C++中看到的相同问题,因为它保护开发人员免受这些类型的内存攻击(缓冲区溢出、堆溢出等)。这些事情不可能发生。由于语言安全性中存在这种基本保护,安全漏洞已经向上移动到了堆栈。

它们现在发生在更高的层面上。SQL注入、XSS、DOS等。你可以想出一种方法让Java远程加载恶意代码,但要做到这一点,就需要利用服务层中的其他漏洞来远程推送代码到目录中,然后通过类加载器触发Java加载。远程攻击在理论上是可能的,但使用Java更加复杂。而且通常如果你能够利用其他漏洞,那么为什么不直接去攻击并削弱Java的作用呢?可写入世界目录,其中加载Java代码,可能被用来对付你。但此时问题真的是Java吗?还是你的系统管理员或其他可利用服务的供应商呢?

多年来,我只看到Java中可能存在远程代码潜在漏洞的情况是VM加载的本地代码。libzip漏洞、gif文件解析等,这些问题都很少见,2-3年出现一次而已。而且这种漏洞存在于JVM加载的本地代码中,而不是Java代码中。
作为一种编程语言,Java非常安全。即使是我所讨论的这些理论上可以被攻击的问题,在平台上也有钩子来防止它们。签名代码可以挫败大部分的攻击。然而,很少有Java程序安装了Security Manager。主要是因为性能和可用性的原因,但最主要的原因是这些漏洞在最好的情况下非常有限。与C/C++的缓冲区溢出问题在90年代末/2000年代爆发的情况相比,Java中的远程代码加载并没有达到流行的水平。
Java作为一个平台并不是万无一失的,但是它的安全性比其他平台要高得多。黑客总是机会主义者,会选择那些易于攻击的目标。

很好的总结 - 从攻击者的角度来看,我想指出的一件事是Java可以被用作攻击面。由于它是一种解释性语言,您可以编写通用shell...直到我读了一篇关于它的文章,我才真正意识到这一点。 - wuntee

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