反序列化漏洞原理详解

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

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 = Security
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值