深入探究Shiro反序列化漏洞

什么是shiro反序列化漏洞

Shiro是Apache的一个强大且易用的Java安全框架,用于执行身份验证、授权、密码和会话管理。使用 Shiro 易于理解的 API,可以快速轻松地对应用程序进行保护

Shiro-550反序列化漏洞(CVE-2016-4437) 漏洞简介 shiro-550主要是由shiro的rememberMe内容反序列化导致的命令执行漏洞,造成的原因是默认加密密钥是硬编码在shiro源码中,任何有权访问源代码的人都可以知道默认加密密钥。 于是攻击者可以创建一个恶意对象,对其进行序列化、编码,然后将其作为cookie的rememberMe字段内容发送,Shiro 将对其解码和反序列化,导致服务器运行一些恶意代码。

环境搭建

我们先去github下载shiro 1.2.4的工程代码,下载链接如下

shiro 1.2.4

然后解压到一个文件夹,并打开shiro-shiro-root-1.2.4/pom.xml文件,并把jstl依赖版本改为1.2

1711202988730.png

然后使用IDEA打开Maven项目,位置选择我们刚才解压的文件夹,最后点击确认

1711203015927.png

然后IDAE会自动下载依赖项,需要等待一段时间,如果感觉下的很慢,或者下载失败的话,可以将Maven的下载源更改为国内的

1711203036535.png

下载完成后我们编辑下运行配置,设置为Tomcat本地服务器运行,然后JRE选择我们Java8版本的

1711203068871.png

然后点击部署,工件选择samples-web:war

1711203087252.png

最后点击运行即可,出现下面界面即代表配置成功

1711203104257.png

漏洞判断

访问url/samples_web_war/login.jsp,并登陆抓包
1711203120903.png

抓包完成后,我们回到网页退出下登陆,然后在repeater界面重放下,可以看到remenberme 字段,代表可能存在shiro反序列化漏洞
1711203153748.png
当发现cookie中带有rememberMe字段时,就会触发getRememberedPrincipals方法

该方法路径为 org\apache\shiro\mgt\AbstractRememberMeManager.java 390行 getRememberedPrincipals

rememberMe解密流程

1711203194323.png

1711203218898.png

在shiro进行反序列化前会经过三层解密,如上图所示

1.getRememberedSerializedIdentity(subjectContext) //base64解密
2.convertBytesToPrincipals(bytes, subjectContext) //密钥aes解密&反序列化解密
    2.1 decrypt(bytes) 密钥解密
    2.2 deserialize(bytes)反序列化解密

接下来便对这三层解密进行分析

代码分析

第一层解密

在我们Cookie中传入代码如下rememberMe字段后会先调用getRememberedPrincipals方法对其处理,其中参数subjectContext便是我们传入的rememberMe字段

我们看下该方法的代码

public PrincipalCollection getRememberedPrincipals(SubjectContext subjectContext) {
   
    PrincipalCollection principals = null;
    try {
   
        byte[] bytes = getRememberedSerializedIdentity(subjectContext);
        //SHIRO-138 - only call convertBytesToPrincipals if bytes exist:
        if (bytes != null && bytes.length > 0) {
   
            principals = convertBytesToPrincipals(bytes, subjectContext);
        }
    } catch (RuntimeException re) {
   
        principals = onRememberedPrincipalFailure(re, subjectContext);
    }

    return principals;
}

代码中的subjectContext属性便为rememberMe字段的值,我们发现对其调用了getRememberedSerializedIdentity方法,跟进查看该方法代码如下

    protected byte[] getRememberedSerializedIdentity(SubjectContext subjectContext) {
   

        if (!WebUtils.isHttp(subjectContext)) {
   
            if (log.isDebugEnabled()) {
   
                String msg = "SubjectContext argument is not an HTTP-aware instance.  This is required to obtain a " +
                        "servlet request and response in order to retrieve the rememberMe cookie. Returning " +
                        "immediately and ignoring rememberMe operation.";
                log.debug(msg);
            }
            return null;
        }

        WebSubjectContext wsc = (WebSubjectContext) subjectContext;
        if 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Elitewa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值