ApacheShiro默认密钥致命令执⾏漏洞(CVE-2016-4437)⽬录
1 漏洞描述
Apache Shiro 是ASF旗下的⼀款开源软件,它提供了⼀个强⼤⽽灵活的安全框架,提供⾝份验证、授权、密码学和会话管理。在Apache Shiro部分旧版本中,加密的⽤户信息序列化后存储在名为remember-me的Cookie中,攻击者可以使⽤Shiro的默认密钥伪造⽤户Cookie,触发Java反序列化漏洞,进⽽在⽬标机器上执⾏任意命令。
2 漏洞特征
远程代码执⾏
3 修复建议
(1)、升级shiro⾄最新版本1.7.0并⽣成新的密钥替换。
(2)、使⽤官⽅秘钥⽣成⽅法:org.pto.AbstractSymmetricCipherService#generateNewKey()
备注:若在配置⾥配置了默认密钥,则⽴即修改,并妥善保管该密钥。
(3)升级shiro到1.2.5及以上,如果shiro的rememberMe功能的AES密钥⼀旦泄露,就会导致反序列化漏洞。
跟了shiro 1.3.2的代码,看到官⽅的操作如下:
删除代码⾥的默认密钥
默认配置⾥注释了默认密钥
如果不配置密钥,每次会重新随机⼀个密钥
可以看到并没有对反序列化做安全限制,只是在逻辑上对该漏洞进⾏了处理。
如果在配置⾥⾃⼰单独配置AES的密钥,并且密钥⼀旦泄露,那么漏洞依然存在。
4 解决办法
4.1 升级shiro到最新版本
4.2 ⾃定义⽣成AESkey(Apache Shiro使⽤官⽅⾃带的⽣成AES密钥)
dules.security;
pto.KeyGenerator;
pto.SecretKey;
import org.dec.Base64;
/**
*
* @Title ShiroCustomAESKeyUtil.java
* @Description ⾃定义⽣成shiro AESkey(解决:Apache Shiro 默认密钥致命令执⾏漏洞(CVE-2016-4437))
* 采⽤Apache Shiro官⽅⾃带的⽣成AES密钥
* @Author wy
* @Date 2020年11⽉17⽇上午10:06:45
*/
public class ShiroCustomAESKeyUtil {
/**
* ⽣成密钥
*
* @return
* @throws Exception
*/
public static String getKey() throws Exception {
KeyGenerator keygen = Instance("AES");
SecretKey deskey = ateKey();
String key = Encoded());
return key;
}
public static void main(String[] args) throws Exception {
System.out.println(getKey());
}
}
1).shiro采⽤xml⽅式配置(spring+springMVC+xx)
<!-- 定义Shiro安全管理配置 -->
<bean id="securityManager" class="org.apache.DefaultWebSecurityManager">
<!-- 指定Shiro验证⽤户登录的类为⾃定义的Realm(若有多个Realm,可⽤[realms]属性代替) -->
<property name="realm" ref="systemAuthorizingRealm" />
<property name="sessionManager" ref="sessionManager" />
<property name="cacheManager" ref="shiroCacheManager" />
<!--注⼊rememberMe cookie管理器-->
<property name="rememberMeManager" ref="rememberMeManager"/>
</bean>
<!-- rememberMe管理器 -->
<bean id="rememberMeManager" class="org.apache.CookieRememberMeManager">
<!--注⼊⾃定义cookie(主要是设置寿命, 默认的⼀年太长) -->
<property name="cookie" ref="rememberMeCookie" />
<!-- 避免Apache Shiro 默认密钥致命令执⾏漏洞(CVE-2016-4437) -->
<!-- 密钥 WVYw571OG4BehqT7I6J3mA== 调⽤Key()⽣成 -->
<property name="cipherKey" value="#{T(org.dec.Base64).decode('WVYw571OG4BehqT7I6J3mA==')}"/> </bean>
<!--⼿动指定cookie -->
<bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<constructor-arg value="rememberMe" />
<property name="httpOnly" value="true" />
<property name="maxAge" value="604800" /><!-- 7天 -->
</bean>
2).springBoot项⽬
在shiro配置类中添加以下代码
/**
* 安全管理器
*/
@Bean
public SecurityManager securityManager(UserRealm userRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 设置realm.
securityManager.setRealm(userRealm);
// 记住我
securityManager.setRememberMeManager(rememberMeManager());
// 注⼊缓存管理器;
securityManager.setCacheManager(getEhCacheManager());
// session管理器
securityManager.setSessionManager(sessionManager());
return securityManager;
}
/**
shiro安全框架* 记住我
*/
public CookieRememberMeManager rememberMeManager() {
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager(); cookieRememberMeManager.setCookie(rememberMeCookie());
cookieRememberMeManager.setCipherKey(Base64.decode(cipherKey));
return cookieRememberMeManager;
}
/**
* cookie 属性设置
*/
public SimpleCookie rememberMeCookie() {
SimpleCookie cookie = new SimpleCookie("rememberMe");
cookie.setDomain(domain);
cookie.setPath(path);
cookie.setHttpOnly(httpOnly);
cookie.setMaxAge(maxAge * 24 * 60 * 60);
return cookie;
}
5 参考⽹址
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论