从蓝队流量角度分析Shiro-550反序列化漏洞

2024-09-16 12 0

Apache Shiro 简介

Apache Shiro是一个强大且易用的Java安全框架,执行身份验证、授权、密码和会话管理。Shiro的优势在于轻量级,使用简单、上手更快、学习成本低。

Shiro反序列化原理:Apache Shiro框架提供了 RememberMe 功能,用户登陆成功后会生成经过加密并编码的cookie,在服务端接收cookie值后,Base64解码–>AES解密–>反序列化。因此攻击者只要找到AES加密的密钥,就可以构造一个恶意对象,对其进行序列化–>AES加密–>Base64编码,然后将其作为cookie的rememberMe字段发送,Shiro将rememberMe进行解密并且反序列化,最终造成反序列化漏洞。

在 Apache Shiro<=1.2.4 版本中 AES 加密时采用的 key 是硬编码在代码中的,这就为伪造 cookie 提供了机会。只要 rememberMe 的 AES 加密密钥泄露,无论 shiro 是什么版本都会导致反序列化漏洞

Shiro-550(CVE-2016-4437)

特征:返回包中包含rememberMe=deleteMe字段。

影响版本:shiro<1.2.24

环境搭建

git clone https://github.com/apache/shiro.git
cd shiro
git checkout shiro-root-1.2.4

注意导入代码部署的文件夹是samples/web,不是web

从蓝队流量角度分析Shiro-550反序列化漏洞插图

打开shiro-shiro-root-1.2.4/pom.xml文件,并把jstl依赖版本改为1.2

从蓝队流量角度分析Shiro-550反序列化漏洞插图1

使用IDEA打开项目,选择shiro-shiro-root-1.2.4文件夹,最后点击OK

从蓝队流量角度分析Shiro-550反序列化漏洞插图2

IDAE会自动下载依赖项,下载完成后编辑运行配置,设置为Tomcat本地服务器运行,然后JRE选择Java8版本

从蓝队流量角度分析Shiro-550反序列化漏洞插图3

然后点击部署,工件选择samples-web:war或 samples-web:war exploded

从蓝队流量角度分析Shiro-550反序列化漏洞插图4

最后点击运行即可,出现下面界面即代表配置成功

从蓝队流量角度分析Shiro-550反序列化漏洞插图5

漏洞分析

加密流程分析

首先,分析Apache官方通告(https://issues.apache.org/jira/projects/SHIRO/issues/SHIRO-550?filter=allissues)提到CookieRememberMeManager,以此为入口点进行分析。

从蓝队流量角度分析Shiro-550反序列化漏洞插图6

CookieRememberMeManager继承AbstractRememberMeManager

从蓝队流量角度分析Shiro-550反序列化漏洞插图7

AbstractRememberMeManager实现了RememberMeManager接口中的多个方法,主要是密钥、加解密、序列化/反序列化相关功能。另外包括登录成功、失败的处理,查看调用发现在DefaultSecurityManager中

从蓝队流量角度分析Shiro-550反序列化漏洞插图8

DefaultSecurityManager是登录处,只要登陆都会经过这里的Login方法,从这里开始分析。在这里下个断点,然后authenticate方法验证凭证的正确性,如果不正确就不走下面的onSuccessfulLogin方法:

从蓝队流量角度分析Shiro-550反序列化漏洞插图9

F7步入后,F8步过forgetIdentity,if判断中的isRememberMe方法判断是否勾选RememberMe,如果没有就不走rememberIdentity,rememberIdentity是加密的关键方法:

从蓝队流量角度分析Shiro-550反序列化漏洞插图10

F7进入rememberIdentity方法,调用getIdentityToRemember(),作用就是获取用户名赋值给 principals。然后继续F7进入rememberIdentity方法:

从蓝队流量角度分析Shiro-550反序列化漏洞插图11

从蓝队流量角度分析Shiro-550反序列化漏洞插图12

从蓝队流量角度分析Shiro-550反序列化漏洞插图13

进到convertPrincipalsToBytes方法,会序列化principals对象,也就是登陆名称root字符串。

从蓝队流量角度分析Shiro-550反序列化漏洞插图14

往下走,就到了加密的函数位置,会上步骤中序列化principals对象进行加密处理。getCipherService()获取加密方式AES/CBC/PKCS5Padding

从蓝队流量角度分析Shiro-550反序列化漏洞插图15

从蓝队流量角度分析Shiro-550反序列化漏洞插图16

在下一行代码的if判断中通过getEncryptionCipherKey进行获取密钥进行加密,那么重点分析下这段代码逻辑:首先进入getEncryptionCipherKey(其实所有功能都在AbstractRememberMeManager文件中)

发现getEncryptionCipherKey函数中直接返回了一个encryptionCipherKey属性值,也就是密钥。

从蓝队流量角度分析Shiro-550反序列化漏洞插图17

encryptionCipherKey属性是AbstractRememberMeManager中定义的一个私有属性

从蓝队流量角度分析Shiro-550反序列化漏洞插图18

那么需要找到赋值的位置,在setEncryptionCipherKey方法中

从蓝队流量角度分析Shiro-550反序列化漏洞插图19

继续找调用setEncryptionCipherKey的位置,发现在setCipherKey方法中

从蓝队流量角度分析Shiro-550反序列化漏洞插图20

继续找调用setCipherKey的位置,发现在构造方法中

从蓝队流量角度分析Shiro-550反序列化漏洞插图21

构造方法的setCipherKey传参了一个属性值DEFAULT_CIPHER_KEY_BYTES,该值即加密密钥,直接默认固定写死在代码中。

从蓝队流量角度分析Shiro-550反序列化漏洞插图22

最终可以顺推一下密钥生成获取的流程。

从蓝队流量角度分析Shiro-550反序列化漏洞插图23在回到getDecryptionCipherKey获取密钥的位置,进入encrypt函数传参密钥和原始明文进行加密

从蓝队流量角度分析Shiro-550反序列化漏洞插图24

encrypt函数中首先随机生成16位的IV。

从蓝队流量角度分析Shiro-550反序列化漏洞插图25

从蓝队流量角度分析Shiro-550反序列化漏洞插图26

获取到IV后回到encrypt函数中执行encrypt函数执行加密处理

从蓝队流量角度分析Shiro-550反序列化漏洞插图27

加密原始明文数据,并将IV拼接到加密后的数据前16位

从蓝队流量角度分析Shiro-550反序列化漏洞插图28

到此加密流程已经结束,回到rememberIdentity方法中,会进入rememberSerializedIdentity方法,F7步入会跳到AbstractRememberMeManager的子类CookieRememberMeManager中,其实现了rememberSerializedIdentity方法。此方法会将上步骤中的IV和加密数据进行BASE64编码后存入Cookie字段的rememberMe中。

从蓝队流量角度分析Shiro-550反序列化漏洞插图29

整体加密流程并不复杂:

1、序列化principals对象,对象中保存了登录用户名(root)

2、加密算法AES/CBC/PKCS5Padding,iv是16位随机生成的值

3、将1)中序列化后principals对象的值跟DEFAULT_CIPHER_KEY_BYTES进行AES加密,将2)中随机生成的iv拼接到加密后的字符串最前面

4、Base64编码生成Base64字符串,写入Cookie中rememberMe的值

解密流程分析

解密时就不一定涉及到登录了,那么就需要从请求发起时进行跟进。可从哪个位置开始下断点呢?

Javaweb是根据web.xml文件配置路由,通过该路由指定过滤器等,在web.xml里面看到以下配置:

从蓝队流量角度分析Shiro-550反序列化漏洞插图30

说明访问根目录就要走ShiroFilter过滤器,那么跟进过滤器进行分析:

ShiroFilter继承于AbstractShiroFilter类,AbstractShiroFilter又继承于OncePerRequestFilter类

从蓝队流量角度分析Shiro-550反序列化漏洞插图31

从蓝队流量角度分析Shiro-550反序列化漏洞插图32

OncePerRequestFilter类就是开始的地方,无论是GET还是POST都会从这里开始,但是呢中间会有很多各种调用,会比较繁琐,部分无关的会直接跳过,到关键函数位置再细致分析:

从蓝队流量角度分析Shiro-550反序列化漏洞插图33

为了分析简单,可以直接构造Get方法的Cookie头部rememberMe发包。

从蓝队流量角度分析Shiro-550反序列化漏洞插图34

F7进入doFilterInternal方法,在createSubject位置继续F7进入

从蓝队流量角度分析Shiro-550反序列化漏洞插图35

F7进入buildWebSubject方法

从蓝队流量角度分析Shiro-550反序列化漏洞插图36

F7进入buildSubject方法

从蓝队流量角度分析Shiro-550反序列化漏洞插图37

F7进入createSubject方法

从蓝队流量角度分析Shiro-550反序列化漏洞插图38

可以看到关键的resolvePrincipals方法了,

从蓝队流量角度分析Shiro-550反序列化漏洞插图39

F7进入resolvePrincipals方法,就会跳到DefaultSecurityManager.java文件中,也就是之前分析shiro登录加密最开始下断点的文件。

从蓝队流量角度分析Shiro-550反序列化漏洞插图40

F7跟进getRememberedIdentity方法进去,继续往下跟getRememberedPrincipals方法

从蓝队流量角度分析Shiro-550反序列化漏洞插图41

可以看到两个方法getRememberedSerializedIdentityconvertBytesToPrincipals,后面本不用太过于分析了,跟加密流程大体相当。

从蓝队流量角度分析Shiro-550反序列化漏洞插图42

  • getRememberedSerializedIdentity:获取cookie的RememberMe的值并进行Base64解码
  • convertBytesToPrincipals:获取到的密文进行解密并进行反序列化

convertBytesToPrincipals方法中获取前16位作为iv进行解密:

从蓝队流量角度分析Shiro-550反序列化漏洞插图43

从蓝队流量角度分析Shiro-550反序列化漏洞插图44

防守侧分析

推荐一款由ABC_123大佬开发的蓝队分析研判工具箱。

1、正常登录的原始明文内容形式如下:

从蓝队流量角度分析Shiro-550反序列化漏洞插图45

2、攻击流量解密后的内容

从蓝队流量角度分析Shiro-550反序列化漏洞插图46

可以很明显发现恶意攻击的流量,rememberMe字段的值会很长,而且解密后存在很多可疑的反序列化类。

那么在日常分析过程中,在分析大量shiro流量时,可以先根据rememberMe字段的长度进行排序,优先分析长度最长的流量;然后对rememberMe字段进一步解密,分析原始内容,确定shiro攻击的真实性。

参考链接:

https://xxe.icu/shiro_deserialization_vulnerability.html#%E6%BC%8F%E6%B4%9E%E5%88%A9%E7%94%A8

https://www.cnblogs.com/1vxyz/p/17572415.html


4A评测 - 免责申明

本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。

不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。

本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。

如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!

程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。

侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)

相关文章

如何使用CODASM编码Payload并降低熵值
SessionExec:一款针对会话安全的安全命令测试工具
Arkime:一款大规模数据包捕获和索引数据库系统
万字长文浅谈三高系统建设方法论和实践
你遇到过哪些奇葩面试题目;如何考察渗透测试与安全管理能力| FB甲方群话题讨论
Amoco:一款针对二进制源码的安全分析工具

发布评论