Java加载动态链接库方式

💡 原文中文,约8700字,阅读约需21分钟。
📝

内容提要

本文介绍Java加载动态链接库的方法,可替代传统webshell。通过System.load或Runtime.load直接加载,但易被安全软件检测。文章提出模拟ClassLoader或NativeLibrary的load方法,利用反射或Unsafe绕过限制,实现免杀。实战中,上传动态链接库至服务器并加载,可执行如弹计算器等操作,未来有望实现无文件加载,提升内网渗透能力。

🔎

延伸解读

为何要模拟底层加载

直接调用System.load或Runtime.load虽然简单,但安全软件容易监控这些高危API。文章指出,模拟ClassLoader或NativeLibrary的加载方法,可以减少Java层面的调用痕迹,降低被查杀的风险。同时,越底层的调用越难被检测,兼容性也更好。

两种模拟加载的技术路线

模拟加载主要有两条路线:一是通过反射调用ClassLoader的私有静态方法loadLibrary或loadLibrary0;二是直接实例化NativeLibrary类并调用其load方法。对于NativeLibrary,除了反射构造外,还可利用Unsafe.allocateInstance绕过构造器限制,从而更隐蔽地加载动态链接库。

实战中的优势与局限

相比传统webshell,动态链接库加载方式可结合签名实现免杀,且能直接加载frp等代理工具,便于内网渗透。但当前技术仍处初级阶段,加载路径写死,功能有限,且依赖上传漏洞或RCE先上传dll/so文件。未来有望实现无文件加载,提升实用性。

Q&A

Java中加载动态链接库有哪些方法?

Java中加载动态链接库的方法包括:使用System.load()、Runtime.getRuntime().load()、com.sun.glass.utils.NativeLibLoader.loadLibrary(),以及通过反射或Unsafe模拟ClassLoader或NativeLibrary的load方法。

为什么需要模拟ClassLoader或NativeLibrary来加载动态链接库?

因为直接使用System.load或Runtime.load容易被安全软件(如webshell查杀工具、RASP、终端防护软件)检测到。模拟底层方法可以减少Java层面的调用,降低被检测的风险,同时提高兼容性和成功率。

如何使用反射模拟ClassLoader的loadLibrary方法加载动态链接库?

通过反射获取java.lang.ClassLoader类的私有静态方法loadLibrary,设置可访问后调用,传入参数为Class对象、文件路径和布尔值true。示例代码:Class clazz = Class.forName("java.lang.ClassLoader"); Method method = clazz.getDeclaredMethod("loadLibrary", Class.class, String.class, boolean.class); method.setAccessible(true); method.invoke(null, clazz, "D:\\temp\\calc_x64.dll", true);

如何使用Unsafe类实例化NativeLibrary并加载动态链接库?

首先通过反射获取sun.misc.Unsafe的实例,然后使用unsafe.allocateInstance(Class)方法绕过构造器实例化NativeLibrary类,最后通过反射调用其load方法。示例代码:Class aClass = Class.forName("sun.misc.Unsafe"); Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(); declaredConstructor.setAccessible(true); Unsafe unsafe = (Unsafe)declaredConstructor.newInstance(); Object obj = unsafe.allocateInstance(a); Method method = obj.getClass().getDeclaredMethod("load", String.class, boolean.class); method.setAccessible(true); method.invoke(obj, file, false);

Java加载动态链接库相比传统webshell有什么优势?

Java加载动态链接库可以实现免杀效果,因为动态链接库可以签名,降低被终端检测的风险。此外,可以将frp、socks代理等工具作为动态链接库上传并加载,实现一键内网穿透,操作上比传统webshell更方便。

在实战中如何利用动态链接库加载实现免杀?

在实战中,可以通过文件上传或RCE等方式上传一个JSP木马,该木马接收动态链接库的Base64编码内容,将其写入系统临时目录,然后通过反射或Unsafe加载该动态链接库。动态链接库可以预先设置好命令,实现如弹计算器、内网穿透等操作。

com.sun.glass.utils.NativeLibLoader.loadLibrary方法有什么局限性?

该方法并非在所有JDK环境中都可用,因为javafx模块并非总是存在。此外,在Windows上只能穿越到JDK所在盘符的根目录,且文件名不能带后缀,否则会被自动添加.dll后缀。

🏷️

标签

➡️

继续阅读