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
利用工具:https://github.com/wyzxxz/shiro_rce_tool
三、漏洞分析
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
方法
把斷點下到rememberIdentity
後,跟進rememberIdentity
方法
繼續跟進rememberIdentity
方法後,可以看到呼叫了convertPrincipalsToBytes
方法後得到了個bytes,然後傳入了rememberSerializedIdentity
中
其實在convertPrincipalsToBytes
中進行了加密操作,我們可以跟進檢視
可以看到通過序列化拿到了個bytes,然後在362行進行了encrypt
操作,這裡就是加密進行的地方了,跟進檢視
看471行,拿到了個CipherService
類,這個類就是用來進行加密的,開啟可以看到加密模式為CBC,Padding規則是PKCS5,加密方式為AES
然後473行進行了加密操作,檢視在其引數中的getEncryptionCipherKey
方法,這個方法就是用來獲取金鑰的,此金鑰硬編碼在了類中,並進行了base64編碼
回到之前的encrypt
方法中,等加密完成後,把值return給了前面說的的bytes,然後傳進了rememberSerializedIdentity
方法
在rememberSerializedIdentity
方法中,把加密的字串進行了Base64編碼,然後設定到了cookie中
2)解密過程
在shiro中,解密過程就是和加密過程相反的了,解密過程在AbstractRememberMeManager#getRememberedPrincipals
方法中
首先呼叫getRememberedSerializedIdentity
方法,方法中獲得了cookie中的rememberMe的值然後進行base64解碼並返回給了bytes
第二步就是呼叫convertBytesToPrincipals
方法來進行解密
跟進convertBytesToPrincipals
方法
先進行了decrypt
解密,然後再進行的deserialize
反序列化。
檢視decrypt
,這裡和之前加密過程步驟差不多,用的金鑰都是同一個
檢視反序列化方法deserialize
getSerializer()
返回的是一個預設的序列化物件DefaultSerializer
跟進DefaultSerializer#deserialize
看到了熟悉的反序列化
四、漏洞修復
Apache Shiro 1.2.5版本的原始碼,修復方法就是shiro每次啟動,都會隨機生成一個新的key:https://github.com/apache/shiro/commit/4d5bb000a7f3c02d8960b32e694a565c95976848