该项目用于检查 Java 库和类路径中的利用链。利用链用于构建反序列化漏洞的利用程序。通过自动发现应用程序类路径中可能存在的利用链,渗透测试人员可以快速构建利用程序,应用程序安全工程师可以评估反序列化漏洞的影响并优先修复。
该项目曾在 Black Hat USA 2018 上展示。欲了解更多信息,请前往查看!(链接待定)
免责声明:该项目目前处于 alpha 阶段。需要添加测试和文档。欢迎通过添加测试或文档来提供帮助!
假设你的系统已安装 JDK,只需运行 ./gradlew shadowJar 即可。然后可以使用 java -jar build/libs/gadget-inspector-all.jar <args> 运行应用程序。
该应用程序接受一个 WAR 文件路径(此时 WAR 文件会被解压,其所有类和库将作为类路径)或任意数量的 JAR 文件作为参数。
请注意,分析过程可能非常消耗内存(到目前为止,Gadget Inspector 尚未针对内存使用进行任何优化)。对于小型库,你可能需要分配至少 2GB 的堆空间(即使用 -Xmx2G 标志)。对于较大的应用程序,请尽量使用尽可能多的内存。
该工具包将经历多个类路径检查阶段,以便为后续阶段构建数据集。这些数据集会写入扩展名为 .dat 的文件中,运行后可以删除(写入这些文件主要是为了在开发期间可以跳过较早阶段)。
分析运行完成后,会生成 gadget-chains.txt 文件。
以下是从 commons-collections-3.2.1.jar 运行得到的示例,使用命令如:
wget http://central.maven.org/maven2/commons-collections/commons-collections/3.2.1/commons-collections-3.2.1.jar
java -Xmx2G -jar build/libs/gadget-inspector-all.jar commons-collections-3.2.1.jar
在 gadget-chains.txt 中,存在以下利用链:
com/sun/corba/se/spi/orbutil/proxy/CompositeInvocationHandlerImpl.invoke(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object; (-1)
com/sun/corba/se/spi/orbutil/proxy/CompositeInvocationHandlerImpl.invoke(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object; (0)
org/apache/commons/collections/map/DefaultedMap.get(Ljava/lang/Object;)Ljava/lang/Object; (0)
org/apache/commons/collections/functors/InvokerTransformer.transform(Ljava/lang/Object;)Ljava/lang/Object; (0)
java/lang/reflect/Method.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; (0)
该利用链的入口点是 JDK InvocationHandler 接口的一个实现。使用与原始 commons-collections 利用链相同的技巧,该接口的任何可序列化实现都可以在利用链中到达,因此发现的链从这里开始。该方法调用了 classToInvocationHandler.get()。发现的利用链表明 classToInvocationHandler 可以被序列化为一个 DefaultedMap,因此这个调用跳转到了 DefaultedMap.get()。链中的下一步从该方法中调用了 value.transform()。这个类中的参数 value 可以被序列化为一个 InvokerTransformer。在该类的 transform 方法内部,我们看到调用了 cls.getMethodName(iMethodName, ...).invoke(...)。Gadget Inspector 确定 iMethodName 作为序列化成员是攻击者可控制的,因此攻击者可以在类上执行任意方法。
该利用链是 Frohoff 发现的完整 commons-collections 利用链的基础。在上面的例子中,Gadget Inspector 恰好通过 CompositeInvocationHandlerImpl 和 DefaultedMap 而不是 AnnotationInvocationHandler 和 LazyMap 发现了入口,但大体相同。
如果你想寻找该工具能找到的其他类型利用链的更多示例,以下库也有一些有趣的结果:
别忘了,你也可以将 Gadget Inspector 指向完整的应用程序(打包为 JAR 或 WAR)。例如,在分析 Zksample2 应用程序的 WAR 文件时,我们得到以下利用链:
net/sf/jasperreports/charts/design/JRDesignPieDataset.readObject(Ljava/io/ObjectInputStream;)V (1)
org/apache/commons/collections/FastArrayList.add(Ljava/lang/Object;)Z (0)
java/util/ArrayList.clone()Ljava/lang/Object; (0)
org/jfree/data/KeyToGroupMap.clone()Ljava/lang/Object; (0)
org/jfree/data/KeyToGroupMap.clone(Ljava/lang/Object;)Ljava/lang/Object; (0)
java/lang/reflect/Method.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; (0)
如你所见,该利用链利用了应用程序中包含的多个不同库来构建。
问: 如果 Gadget Inspector 找到了一个利用链,能根据它构建利用程序吗?
答: 不一定。该分析使用了一些简化的假设,可能会报告误报(实际上不存在的利用链)。举个简单的例子,它不会尝试求解分支条件的可满足性。因此,它将以下代码报告为利用链:
public class MySerializableClass implements Serializable {
public void readObject(ObjectInputStream ois) {
if (false) System.exit(0);
ois.defaultReadObject();
}
}
此外,Gadget Inspector 对其认为“有趣”的函数有相当宽泛的条件。例如,它将反射视为有趣(即调用 Method.invoke() 且攻击者可以控制方法时),但常常被忽略的断言意味着攻击者可以影响所调用的方法,但并没有完全控制权。例如,攻击者可能能够调用任何类中的 getError() 方法,但不能调用其他任何方法名。
问: 如果未发现利用链,是否意味着我的应用程序可以安全使用,不会被利用?
答: 不!首先,Gadget Inspector 只有一组非常狭窄的“接收器”函数被认为具有“有趣”的副作用。这当然不意味着列表中没有其他有趣或危险的行为。
此外,静态分析存在许多局限性,这意味着 Gadget Inspector 总是会有盲点。例如,以下代码 Gadget Inspector 目前会漏掉,因为它不跟踪反射调用。
public class MySerializableClass implements Serializable {
public void readObject(ObjectInputStream ois) {
System.class.getMethod("exit", int.class).invoke(null, 0);
}
}