Java代码审计&鉴权漏洞&Interceptor&Filter&Shiro&JWT

目录

0x00 前言

0x01 鉴权方式&审计思路 

1、目前主流的鉴权方式

2、鉴权漏洞审计思路

0x02 Interceptor鉴权审计 - NewbeeMall电商系统

1、项目介绍 - NewbeeMall

2、Interceptor 补充介绍

3、NewbeeMall - Interceptor鉴权 - 代码审计

0x03 Filter鉴权审计 - 华夏ERP进销存系统

1、项目介绍 - 华夏ERP

2、华夏ERP - Filter - 代码审计

0x04 Shiro鉴权审计 - Tumo博客系统

1、项目介绍 - Tumo博客系统

2、Tumo - Shiro - 代码审计

0x05 JWT鉴权审计 - FastCMS

1、项目介绍 - FastCMS

2、JWT鉴权漏洞审计思路

3、FastCMS - JWT - 代码审计


0x00 前言

希望和各位大佬一起学习,如果文章内容有错请多多指正,谢谢!  

个人博客链接:CH4SER的个人BLOG – Welcome To Ch4ser's Blog

0x01 鉴权方式&审计思路 

1、目前主流的鉴权方式

        Interceptor是一种拦截器,也称之为拦截器链(Interceptor Chain),主要用于拦截请求、响应或处理过程中的某些事件,比如权限认证、日志记录、性能测试等。在 Java 中,Interceptor可以用来扩展框架,增加或修改某个方法的行为,或者对应用流程做些前置处理、后置处理、环绕处理等。

        Filter被称为过滤器,过滤器实际上就是对Web资源进行拦截,做一些处理后再交给下一个过滤器或Servlet处理,通常都是用来拦截request进行处理的,也可以对返回的 response进行拦截处理。开发人员利用filter技术,可以实现对所有Web资源的管理,例如实现权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。

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

        JWT(JSON Web Token),将用户信息加密到token里,服务器不保存任何用户信息,只保存密钥信息,通过使用特定加密算法验证token,通过token验证用户身份。基于token的身份验证可以替代传统的cookie+session身份验证方法。这使得JWT成为高度分布式网站的热门选择,在这些网站中,用户需要与多个后端服务器无缝交互。

2、鉴权漏洞审计思路

         不同于常规审计思路,鉴权漏洞几乎没有业务关键词供搜索,其特征较弱。所以,针对鉴权漏洞的代码审计,思路为直接找鉴权技术特征目录进行代码追溯。

  • 找有没有 Interceptor ,拦截器里有没有鉴权
  • 找有没有 Filter ,过滤器里有没有鉴权
  • 找有没有 Shiro ,看版本及里面的逻辑配置
  • 找有没有 JWT ,看后面写的四个方向确定
  • 若以上都没有,可能是自写的鉴权代码

0x02 Interceptor鉴权审计 - NewbeeMall电商系统

1、项目介绍 - NewbeeMall

        Newbee-mall 项目是一套电商系统,包括 newbee-mall 商城系统及 newbee-mall-admin 商城后台管理系统,基于 Spring Boot 2.X 及相关技术栈开发。

        前台商城系统包含首页门户、商品分类、新品上线、首页轮播、商品推荐、商品搜索、商品展示、购物车、订单结算、订单流程、个人订单管理、会员中心、帮助中心等模块。

        后台管理系统包含数据面板、轮播图管理、商品管理、订单管理、会员管理、分类管理、设置等模块。

下载:https://github.com/newbee-ltd/newbee-mall

2、Interceptor 补充介绍

参考:Spring Boot拦截器(Interceptor)详解

Interceptor必须重写以下三个方法:preHandle、postHandle、afterCompletion

  • preHandle 方法:在请求处理之前被调用。当它返回 false 时,表示拦截请求,不继续执行后续处理器;当它返回为 true 时,表示放行请求,继续执行后续处理器
  • postHandle 方法:在 Controller 方法调用之后执行
  • afterCompletion 方法:在整个请求结束之后,也就是在 DispatcherServlet 渲染了对应的视图之后执行
public class LogInterceptor extends HandlerInterceptorAdapter {    

@Override    
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {      
     long startTime = System.currentTimeMillis();       
     System.out.println("\n-------- LogInterception.preHandle --- ");        
     System.out.println("Request URL: " + request.getRequestURL());        
     System.out.println("Start Time: " + System.currentTimeMillis());        
     request.setAttribute("startTime", startTime);       
      return true;    
}    

@Override   
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { 
      System.out.println("\n-------- LogInterception.postHandle --- ");        
      System.out.println("Request URL: " + request.getRequestURL());    
}    

@Override   
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {        
   System.out.println("\n-------- LogInterception.afterCompletion --- ");        
   long startTime = (Long) request.getAttribute("startTime");        
   long endTime = System.currentTimeMillis();        
   System.out.println("Request URL: " + request.getRequestURL());        
   System.out.println("End Time: " + endTime);        
   System.out.println("Time Taken: " + (endTime - startTime));   
    }
}

       

        假如有三个不同的Interceptor,他们的配置如下,则其默认执行顺序为其注册顺序。当然,也可以使用 InterceptorRegistry#order(int) 方法指定执行顺序,值越小优先级越高。

@Configurationpublic 
class WebConfig implements WebMvcConfigurer {    
@Override    
public void addInterceptors(InterceptorRegistry registry) {        
	registry.addInterceptor(new LogInterceptor());      
	registry.addInterceptor(new OldLoginInterceptor()).addPathPatterns("/admin/oldLogin"); 
	registry.addInterceptor(new	AdminInterceptor()).addPathPatterns("/admin/*").excludePathPatterns("/admin/oldLogin");   
	 }
}

3、NewbeeMall - Interceptor鉴权 - 代码审计

3.1、 确定鉴权方式

       翻阅 pom.xml 和 External Libraries,未观察到 Shiro、JWT 关键字,排除使用 Shiro、JWT 进行鉴权的可能。继续翻阅项目文件,观察到 interceptor 文件夹下有三个文件:AdminLoginInterceptor、NewBeeMallCartNumberInterceptor、NewBeeMallLoginInterceptor。继续搜索注册关键字 "registry.addInterceptor" 定位到 Interceptor 的配置文件 NeeBeeMallWebMvcConfigurer,最终确定该项目使用 Interceptor 进行鉴权。

3.2、AdminLoginInterceptor >> preHandle >> uri.startsWith

        分析 AdminLoginInterceptor 的 preHandle 方法,得知若请求的 URI 以 "/admin" 开头且 Session 中的 loginUser 属性为 null,则进行拦截。

3.3、漏洞利用

        由于 Session 无法伪造,那么可以从 URI 入手,试想若构造一个不以 /admin 开头的 URI,那不就可以放行了吗?于是构造 URI 为 /;/admin//admin(不影响解析)成功绕过 Interceptor 进入后台。

0x03 Filter鉴权审计 - 华夏ERP进销存系统

1、项目介绍 - 华夏ERP

华夏 ERP 是目前唯一完整开源的进销存系统,具备进销存 + 财务的功能(只有后台)

核心框架为 SpringBoot 2.0.0,持久层框架为 Mybatis 1.3.2,日志管理为 Log4j 2.10.0

项目环境为:Mysql5.7+、JDK1.8、Maven3.2.3

下载:https://github.com/jishenghua/jshERP

2、华夏ERP - Filter - 代码审计

2.1、确定鉴权方式

        翻阅 pom.xml 和 External Libraries,未观察到 Shiro、JWT 关键字,排除使用 Shiro、JWT 进行鉴权的可能。继续翻阅项目文件,观察到 filter 文件夹下有文件:LogCostFilter,其 urlPatterns 为匹配所有,分析 doFilter 方法确实含有于鉴权相关的代码逻辑,所以确定项目使用 Filter 进行鉴权。

2.2、LogCostFilter >> urlPatterns >> doFilter >> requestUrl,ignoredList,allowUrl

分析 doFilter 方法,得出其放行和拦截的逻辑如下:

  • 检查用户是否已登录,如果已登录则放行
  • 放行登录页和注册页
  • 检查是否为忽略列表中的URL,如果是则放行
  • 检查是否为允许列表中的URL,如果是则放行
  • 否则,重定向到登录页

分析 init 方法,得知以下信息:

  • ignoredList << ignoredUrl = ".css#.js#.jpg#.png#.gif#.ico"
  • allowUrls << filterPath = "/user/login#/user/registerUser"

2.3、漏洞利用 

      根据上面得到的信息,从 URI 入手,构造 URI 为:

/login.html/../account/getAccount
/register.html/../account/getAccount
/ch4ser.css/../account/getAccount
/ch4ser.jpg/../account/getAccount
/user/login/../../account/getAccount
/user/registerUser/../../account/getAccount
........

        BurpSuite抓包修改URI,成功在未登录情况下进入后台。

0x04 Shiro鉴权审计 - Tumo博客系统

1、项目介绍 - Tumo博客系统

Tumo Blog 是一个简洁美观的博客系统,基于SpringBoot2.X + Vue.js。

下载:https://github.com/TyCoding/tumo

2、Tumo - Shiro - 代码审计

2.1、确定鉴权方式

        翻阅 pom.xml 和 External Libraries,观察到 Shiro 关键字,确定项目使用 Shiro 进行鉴权。

2.2、查看Shiro配置信息

        查看 tumo.properties,发现有关 Shiro 的配置,其中 anon_url 为可匿名访问的路径(一般代表不需要鉴权)。不同于 Shiro 本身的漏洞,这里的鉴权漏洞是由于开发、运维不当的 Shiro 配置所造成的。

2.3、漏洞利用 

        根据Shiro配置信息,寻找利用点,比如 /comment/** 是不需要鉴权的。全局搜索 "/comment" 相关的 Controller 文件,定位到 CommentController。

        测试删除评论,路由为 /comment/{id},提交方式为 DELETE。

        删除前,数据库存储的评论如下:

        BurpSuite抓包修改提交方式为 DELETE,成功删除评论,如下:

0x05 JWT鉴权审计 - FastCMS

1、项目介绍 - FastCMS

FastCMS 基于 SpringBoot 进行插件式开发,具有极强的扩展性,内置一套完整的 CMS 建站系统,同时也支持博客,论坛,商城等功能。

下载:https://gitee.com/xjd2020/fastcms

2、JWT鉴权漏洞审计思路

一般来说,空加密和未校验签名很少见,除非是新手开发、运维,比较常见的是默认密钥未修改和密钥存在被爆破的可能。

  • 生成时使用空加密(逻辑代码问题)
  • 服务端未校验签名(逻辑代码问题)
  • 密钥默认未被修改(搭建后未修改)
  • 密钥爆破可能性大(密钥过于简单)

3、FastCMS - JWT - 代码审计

3.1、确定鉴权方式

        翻阅 pom.xml 和 External Libraries,观察到 JWT 相关 Dependency 信息。

        除此之外,BurpSuite 抓包也能看到很明显的 JWT 流量特征(eyJ)

3.2、审计流程

 分析 JwtAuthTokenFilter,它主要做了以下工作:

1、在请求到达控制器之前检查JWT令牌,并将令牌中的认证信息设置到Spring Security

2、过滤器根据请求URI的前缀判断是否需要进行身份验证。

3、如果需要验证且JWT令牌有效,它将继续执行过滤器链;否则,它将返回相应的错误响应。

JWT 的验证到底有没有问题,关键就在于 tokenManager 的各个方法是否存在问题,于是跟踪到了 DelegatingTokenManager,检查其各个方法的代码,发现不存在空加密或未校验签名的问题。

转而查看 application.yml,发现密钥 secret-key 为官方默认的,也就是说搭建后未修改过。

3.3、漏洞利用 

利用默认密钥,生成管理员账户的 JWT(注意修改过期时间 exp)

BurpSuite 抓包修改 JWT 值,成功进入管理员后台

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值