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

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

* 来源: * 作者: * 发表时间: 2020-08-07 6:10:08 * 浏览: 1
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动态加载类会为许多应用程序带来可能性。否则,某些功能可能无法实现,但是不幸的是,这也会引起很多安全问题,尤其是在类模拟方面。从理论上讲,开发人员可以创建一个自定义的ClassLoader,让它加载原始java.lang.Object的模拟实现,并在应用程序中使用此自定义对象。这可能会在两个方面引起安全问题:此自定义对象可以访问java.lang包下的包范围中可见的所有类内容,其次,该自定义对象将被JVM视为标准对象对象,因此它将其视为Java实现的可信类。为了保护Java处理这些安全性问题,必须通过三个属性来标识Java类:类名称,包和对ClassLoade的引用河如果两个不同的类具有相同的类名和包名,但由不同的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服务器可能返回404 NOTFOUND错误,并且父ClassLoader无法加载该类,因此它将控制权转移到自定义ClassLoader。通过自定义HTTP服务器,将强制在父ClassLoader无法加载类之后的代码流,来源:SecurityExplorations。当此缺陷在2016年3月重新出现时,当时可用的更新版本是8u74。该版本被证明是易受攻击的,Oracle在8u77中提供了更正。但是,在8u77发行说明中,此漏洞仍被描述为“ ldquo”,它将影响台式机设备在Web浏览器中运行的JavaSE [并且]不会影响Java部署环境,例如典型的服务器或独立部署的台式机。应用程序,但事实证明它仍然会影响服务器配置和GoogleAppEngine的Java环境。更正的内容:2016年4月29日,本文错误地认为此漏洞在8u77、8u91和8u92版本中仍然存在。实际上,它已在8u77中得到更正。 8u77的发行说明将其描述为对CVE-2016-0636的修订。特定的描述是ldquo,这是一个未知的漏洞,借助Hotspot子组件中未知的感染内容,并且不包括对CVE-2013-5838的明确引用。但是,SecurityExplorations指出CVE-2016-0636是Issue69的CVE号,而Issue69是他们自己引用早期CVE-2013-5838的方式。 (在本文原始英文文本的评论区域中,讨论了解决问题的相关过程。有兴趣的读者可以访问原始文本进行查看。 mdash,mdash,译者注)
扫描二维码关注我们
确 认