反序列化漏洞原理详解

本文深入解析了 Apache Shiro 框架的安全问题,重点讨论了 Shiro 的反序列化漏洞。从 Shiro 的认证和授权流程出发,详细介绍了 Shiro 如何进行用户身份验证和权限分配,并探讨了 RememberMe 选项导致的反序列化漏洞根源。通过源码分析,揭示了 Shiro 在处理 rememberme 字段时,如何生成加密的序列化数据,以及攻击者如何利用此漏洞进行反序列化攻击。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Apache shiro 简介

Apache Shiro 是一个强大且易用的 Java 安全框架,执行身份验证、授权、密码和会话管理。使用 Shiro 的易于理解的 API,您可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。

本文针对 Shiro 进行了一个原理性的讲解,从源码层面来分析了 Shiro 的认证和授权的整个流程,并在认证与授权的这个流程讲解冲,穿插说明 rememberme 的作用,以及为何该字段会导致反序列化漏洞。

Apache shiro 认证

在该小节中我们将会详细讲解 Shiro 是如何认证一个用户为合法用户的 Shiro 漏洞环境测试代码修改自 Vulhub 中的 CVE-2016-4437。首先是 Shiro 的配置文件,代码如下所示

@Configuration
public class ShiroConfig {
    @Bean
    MainRealm mainRealm() {
        return new MainRealm();
    }

    @Bean
    RememberMeManager cookieRememberMeManager() {
        return (RememberMeManager)new CookieRememberMeManager();
    }

    @Bean
    SecurityManager securityManager(MainRealm mainRealm, RememberMeManager cookieRememberMeManager) {
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        manager.setRealm((Realm)mainRealm);
        manager.setRememberMeManager(cookieRememberMeManager);
        return (SecurityManager)manager;
    }

    @Bean(name = {"shiroFilter"})
    ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        bean.setSecurityManager(securityManager);
          //设置登录页面uri
        bean.setLoginUrl("/login");
          //设置登录失败页面uri
        bean.setUnauthorizedUrl("/unauth");

        Map<String, String> map = new LinkedHashMap<>();
        map.put("/doLogin", "anon");
        map.put("/doLogout", "authc");
        map.put("/user/add","perms[user:add]");
        map.put("/user/update","perms[user:update]");
        map.put("/user/delete","perms[user:delete]");
        map.put("/user/select","perms[user:select]");
        map.put("/**", "authc");

        bean.setFilterChainDefinitionMap(map);

        return bean;
    }
}

小伙伴们有兴趣想了解更多相关学习资料请点赞收藏+评论转发+关注我之后私信我,注意回复【000】即可获取更多免费资料!

 然后是 Controller 的代码

@Controller
public class UserController {
    @PostMapping({"/doLogin"})
    public String doLoginPage(@RequestParam("username") String username, @RequestParam("password") String password, @RequestParam(name = "rememberme", defaultValue = "") String rememberMe) {
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(new UsernamePasswordToken(username, password, rememberMe.equals("remember-me")));
        } catch (AuthenticationException e) {
            return "forward:/login";
        }
        return "forward:/";
    }

    @RequestMapping({"/doLogout"})
    public String doLogout() {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return "forward:/login";
    }

    @RequestMapping({"/"})
    public String helloPage() {
        return "hello";
    }

    @RequestMapping({"/unauth"})
    public String errorPage() {
        return "error";
    }

    @RequestMapping({"/login"})
    public String loginPage() {
        return "loginUser";
    }

    @RequestMapping({"/user/add"})
    public String add(){
        return "/user/add";
    };

    @RequestMapping({"/user/delete"})
    public String delete(){
        return "/user/delete";
    };

    @RequestMapping({"/user/update"})
    public String update(){
        return "/user/update";
    };

    @RequestMapping({"/user/select"})
    public String select(){
        Subject subject = SecurityUtils.getS
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值