Shiro 550反序列化漏洞分析


Shiro 550反序列化漏洞分析

一、漏洞簡介

影響版本:Apache Shiro < 1.2.4

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

Apache Shiro框架提供了記住密碼的功能(RememberMe),用戶登錄成功后會生成經過加密並編碼的cookie。在服務端對rememberMe的cookie值,先base64解碼然后AES解密再反序列化,就導致了反序列化RCE漏洞。
那么,Payload產生的過程:

命令=>序列化=>AES加密=>base64編碼=>RememberMe Cookie值

在整個漏洞利用過程中,比較重要的是AES加密的密鑰,如果沒有修改默認的密鑰那么就很容易就知道密鑰了,Payload構造起來也是十分的簡單。

二、環境搭建

下載后用idea配置tomcat啟動:https://github.com/Medicean/VulApps/tree/master/s/shiro/1

image-20210928220044865

利用工具:https://github.com/wyzxxz/shiro_rce_tool

image-20210930144244696

三、漏洞分析

shiro會提供rememberme功能,可以通過cookie記錄登錄用戶,從而記錄登錄用戶的身份認證信息,即下次無需登錄即可訪問。而其中對rememberme的cookie做了加密處理,漏洞主要原因是加密的AES密鑰是硬編碼在文件中的,那么對於AES加密算法我們已知密鑰,並且IV為cookie進行base64解碼后的前16個字節,因此我們可以構造任意的可控序列化payload。

  • 通過在cookie的rememberMe字段中插入惡意payload,

  • 觸發shiro框架的rememberMe的反序列化功能,導致任意代碼執行。

  • shiro 1.2.24中,提供了硬編碼的AES密鑰:kPH+bIxk5D2deZiIxcaaaA==

1)加密過程

處理rememberme的類為org.apache.shiro.web.mgt.CookieRememberMeManager,它繼承AbstractRememberMeManager類,當登錄成功並且勾選了rememberme選項,那么此時將進入onSuccessfulLogin方法

image-20210930145350773

把斷點下到rememberIdentity后,跟進rememberIdentity方法

image-20210930150030956

繼續跟進rememberIdentity方法后,可以看到調用了convertPrincipalsToBytes方法后得到了個bytes,然后傳入了rememberSerializedIdentity

image-20210930150117056

其實在convertPrincipalsToBytes中進行了加密操作,我們可以跟進查看

image-20210930150327306

可以看到通過序列化拿到了個bytes,然后在362行進行了encrypt操作,這里就是加密進行的地方了,跟進查看

image-20210930150940274

看471行,拿到了個CipherService類,這個類就是用來進行加密的,打開可以看到加密模式為CBC,Padding規則是PKCS5,加密方式為AES

image-20210930151207547

然后473行進行了加密操作,查看在其參數中的getEncryptionCipherKey方法,這個方法就是用來獲取密鑰的,此密鑰硬編碼在了類中,並進行了base64編碼

image-20210930152334108

回到之前的encrypt方法中,等加密完成后,把值return給了前面說的的bytes,然后傳進了rememberSerializedIdentity方法

image-20210930152813892

rememberSerializedIdentity方法中,把加密的字符串進行了Base64編碼,然后設置到了cookie中

image-20210930152858104

2)解密過程

在shiro中,解密過程就是和加密過程相反的了,解密過程在AbstractRememberMeManager#getRememberedPrincipals方法中

image-20210930154228507

首先調用getRememberedSerializedIdentity方法,方法中獲得了cookie中的rememberMe的值然后進行base64解碼並返回給了bytes

image-20210930154613502

第二步就是調用convertBytesToPrincipals方法來進行解密

image-20210930154747209

跟進convertBytesToPrincipals方法

image-20210930154814180

先進行了decrypt解密,然后再進行的deserialize反序列化。

查看decrypt,這里和之前加密過程步驟差不多,用的密鑰都是同一個

image-20210930155113371

查看反序列化方法deserialize

image-20210930155502621

getSerializer()返回的是一個默認的序列化對象DefaultSerializer

image-20210930155550111

跟進DefaultSerializer#deserialize看到了熟悉的反序列化

image-20210930155831320

四、漏洞修復

Apache Shiro 1.2.5版本的源碼,修復方法就是shiro每次啟動,都會隨機生成一個新的key:https://github.com/apache/shiro/commit/4d5bb000a7f3c02d8960b32e694a565c95976848

img


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM