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