30个月后,终于解决了软件开发Java反射库中的安全漏洞。

30个月后,终于解决了软件开发Java反射库中的安全漏洞。

* 来源: * 作者: * 发表时间: 2020-05-22 0:19:27 * 浏览: 0
30个月后,终于修复了Java开发软件反射库中的安全漏洞。 2013年7月,安全组织SecurityExplorations在Java7u25中发现了一个安全漏洞,攻击者可以通过该漏洞完全摆脱Java沙箱的攻击。 Oracle在更新后的7u40中包含了一个补丁程序,但是根据今年早些时候的SecurityExplorations,该补丁程序仅在概念上对其进行了纠正,并且在稍稍修改了代码之后,仍然可以利用此漏洞。此外,后续研究表明,此漏洞甚至比最初报告的更为严重。此问题公开后,Oracle发布了8u77的补丁程序。此漏洞可以在新的反射库中找到,该反射库从Java7开始可以使用,更具体地说,当使用新的MethodHandle类动态访问和调用方法时可以使用。它与ClassLoader加载类的方式有关。要理解此问题,您需要一些与JavaClassLoader的工作方法有关的基础知识,因为类加载是Java中鲜为人知的领域之一,因此在阐述问题本身之前,我们将首先概述该思想。 JavaClassLoaderJava可以在运行时从各种来源动态加载代码。此功能是通过一系列称为ClassLoader的特殊类实现的。标准Java实现提供了多个ClassLoader来加载类。他们可以从文件系统,URL或压缩文件中加载类。但是,Java还为开发人员提供了创建自定义ClassLoader以满足个人需求的能力。与ClassLoader交互的常用方法是调用其loadClass(String)方法。此方法将接受类的名称。如果可以找到,它将返回相关的Class对象。如果找不到,它将抛出ClassNotFoundException异常。 Java应用程序中的每个类都通过ClassLoader以这种方式加载。通过设置父ClassLoader,这些不同的ClassLoader可以彼此连接以形成层次结构。如果未设置父类ClassLoader,则默认将父类ClassLoader设置为用于加载ClassLoader的类加载器(ClassLoader本身也是一个类,因此也需要由ClassLoader加载)。如果提供了父ClassLoader,则ClassLoader的默认行为是将加载请求的类的任务委派给其父加载器。仅当父加载器(或祖父加载器)无法加载此类时,ClassLoader本身才会尝试加载请求的类。但是,自定义加载程序的创建者并非必须遵循此默认行为,而是可以选择实现不同的行为。 Java应用程序启动时,以下ClassLoader将按顺序运行:BootstrapClassLoader:JVM本身的一部分,因此其实现在每个JVM中都是唯一的。该ClassLoader没有父ClassLoader,它用于在java.lang包下加载核心类。 ExtensionClassLoader:负责在扩展库中加载类,在每个Java安装环境中可能有所不同。 ExtensionClassLoader将在java.ext.dirs变量指定的路径下加载所有内容。 ApplicationClassLoader:负责加载应用程序的主类和位于应用程序类路径中的所有类。 CustomClassLoader:应用程序中使用的所有其他ClassLoader。它是可选的,并且取决于应用程序,它可能不存在。在运行时,使用自定义的ClassLoader动态加载类为许多应用程序创造了可能性。否则,可能无法实现某些功能,但是不幸的是,这也会引起很多安全问题,尤其是在类模仿(classimpersonation)方面。从理论上讲,开发人员可以创建一个自定义的ClassLoader,让它加载原始类java.lang.Object的模拟实现,并在应用程序中使用此自定义对象。这可能以两种方式引起安全问题:此自定义对象可以访问java.lang包的包范围中可见的所有类的内容。其次,此自定义对象将由JVM用作标准对象对象,因此将其视为Java实现的受信任类。为了保护Java处理这些安全性问题,需要通过三个属性来标识Java类:类名,包和ClassLoader引用。如果两个不同租金类具有相同的类名和包名,但由不同的ClassLoader加载,Java将认为它们是不相等的,并且在它们之间分配值将导致ClassCastException。这样,可以保护环境免受伪造攻击。部分修复和由此产生的漏洞SecurityExplorations较早报告了此漏洞,并将其分类为CVE-2013-5838。此漏洞可以描述为,当通过MethodHandle调用方法时,对于被调用方法的类,它不会检查ClassLoader,这意味着攻击者可以根据上述方法模仿该类。示例代码显示了原始漏洞,尚未检查目标类的ClassLoader,来源:SecurityExplorations。 Oracle在2013年9月提供了一个修复程序。作为Java7u40的一部分,它包括一个类可见性检查。它将预期的类型与传入的ClassLoader进行比较。比较方法如下:如果两个ClassLoader相同,那么根据定义,这两种类型是完全兼容的。如果一个ClassLoader是另一个ClassLoader的父加载器,则它认为这两个类是通过常规ClassLoader层次结构加载的,因此将它们视为相等是安全的。在第二项检查中,SecurityExplorations发现在稍加修改后该漏洞可能仍然有效。首先,用于模仿类的自定义ClassLoader将目标ClassLoader设置为其父类加载器,可以通过API将其设置为参数:URLClassLoaderlookup_CL = URLClassLoader.newInstance(urlArray,member_CL),通过此机制将被自定义ClassLoader作为层次结构的一部分,来源:SecurityExplorations。然后,由于ClassLoader的默认行为是将加载类的任务委派给其父加载器,因此攻击者需要确保父ClassLoader无法加载到此类中,以便其自定义ClassLoader可以发挥作用。在Java通过网络方法加载类的过程中,已经确认了这种攻击方式:如果通过URL位置定义了该类,则父ClassLoader将尝试连接到相关服务器并获取该类的代码。此时,预建的HTTP服务器可能会返回404NOTFOUND错误,从而导致父ClassLoader无法加载此类,因此它将控制权转移给自定义ClassLoader。通过自定义HTTP服务器,强制父ClassLoader在类失败后加载代码流,来源:SecurityExplorations。当此漏洞在2016年3月再次出现时,当时可用的更新版本是8u74。该版本很容易受到攻击,Oracle在8u77中进行了更正。但是,在8u77发行说明中,该漏洞仍被描述为“ ldquo”,它将影响在桌面设备上运行的JavaSE,并且Web浏览器[并且]不会影响Java部署环境,例如典型的服务器或独立的桌面。应用程序,但事实证明它仍然会影响服务器配置和GoogleAppEngine的Java环境。更正的内容:2016年4月29日,本文错误地认为此漏洞在8u77、8u91和8u92版本中仍然存在。实际上,它已在8u77中得到纠正。在8u77发行说明中将其描述为CVE-2016-0636的修复程序。借助Hotspot子组件中未知的感染内容,这种特定描述是一种此类,不确定的漏洞,并且不包含任何提及的对CVE-2013-5838的明确引用。但是,SecurityExplorations指出CVE-2016-0636是Issue69的CVE号,而Issue69是引用原始CVE-2013-5838的一种方式。 (在本文原始英文文本的评论区域中,讨论了解决此问题的相关过程。有兴趣的读者可以访问原始文本进行查看。 Mdash,mdash,译者注)
扫描二维码关注我们
确 认