问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
Apache Shiro身份验证绕过漏洞(CVE-2021-41303)分析
漏洞分析
此漏洞爆发应急于中秋前,因为网上到现在也没看到有师傅分析这个漏洞,所以在中秋后对此漏洞进行了自我理解式的具体分析~
0x00漏洞描述 ======== Apache Shiro是阿帕奇(Apache)基金会的一套用于执行认证、授权、加密和会话管理的Java安全框架。 ![](https://shs3.b.qianxin.com/attack_forum/2021/12/attach-e56491520eabbe410af6e4405ba964c7344491e8.jpg) 近日,Apache Shiro被披露出身份验证绕过漏洞,攻击者使用特制的 HTTP 请求可进行身份验证绕过。 0x01影响版本 ======== Apache Shiro < 1.8.0 0x02环境搭建 ======== 基本环境采用:<https://github.com/lenve/javaboy-code-samples/tree/master/shiro/shiro-basic> ,拉入idea前修改shiro版本为1.7.1 配置路径拦截器,服务启动时该配置会被当做规则一样写入filterChains中。测试环境暂时最好以以下顺序和路径进行配置,`原因是在shiro的鉴权配置中,使用的LinkedHashMap是一个有序的HashMap,而我认为shiro的认证鉴权会根据配置的先后顺序去依次拦截` [![](https://shs3.b.qianxin.com/attack_forum/2021/10/attach-05f948e60b1d3cf1a919c6f52ad0e89fa3b3c792.png)](https://shs3.b.qianxin.com/attack_forum/2021/10/attach-05f948e60b1d3cf1a919c6f52ad0e89fa3b3c792.png) 配置访问路由 [![](https://shs3.b.qianxin.com/attack_forum/2021/10/attach-42bb6343ae83b50a2e5c6ce6ff6660f86b0650ce.png)](https://shs3.b.qianxin.com/attack_forum/2021/10/attach-42bb6343ae83b50a2e5c6ce6ff6660f86b0650ce.png) debug启动服务之后,访问 <http://localhost:8080/admin/vv/page/> 0x03漏洞分析 ======== 首先在`PathMatchingFilterChainResolver`类中断点`getChain`方法 `fiterChains`是配置过的拦截器,当中有对访问路径做匹配拦截的规则,而`request`当中的`coyoteRequest`就是现在url所访问的路径 [![](https://shs3.b.qianxin.com/attack_forum/2021/10/attach-94424156a1dc6243daa7e1e3e6c5dcf68c65ec68.png)](https://shs3.b.qianxin.com/attack_forum/2021/10/attach-94424156a1dc6243daa7e1e3e6c5dcf68c65ec68.png) 经过 `getPathWithinApplication` 和 `WebUtils.getPathWithinApplication` 方法得到 `requestURL`即`/admin/vv/page/` `removeTrailingSlash` 对路径末尾做做反斜杠的删除得到 [![](https://shs3.b.qianxin.com/attack_forum/2021/10/attach-78b1d0918da64bee6328a7a5af9901eb810d623c.png)](https://shs3.b.qianxin.com/attack_forum/2021/10/attach-78b1d0918da64bee6328a7a5af9901eb810d623c.png) 由于拦截器的顺序,URL会经过pathMatches先匹配`/admin/*/page`拦截规则 ```java String pathPattern; do { if (!var7.hasNext()) { return null; } pathPattern = (String)var7.next(); if (this.pathMatches(pathPattern, requestURI)) { if (log.isTraceEnabled()) { log.trace("Matched path pattern [{}] for requestURI [{}]. Utilizing corresponding filter chain...", pathPattern, Encode.forHtml(requestURI)); } ...... protected boolean pathMatches(String pattern, String path) { PatternMatcher pathMatcher = this.getPathMatcher(); return pathMatcher.matches(pattern, path); } ``` matches --> match --> 然后来到`AntPathMatcher`类中的`doMatch`方法,先通过`StringUtils.tokenizeToStringArray`方法将路径以“/”对其拆分成数组 [![](https://shs3.b.qianxin.com/attack_forum/2021/10/attach-178de63d85ed2740f4bb4ec0f06f8645a7b5d559.png)](https://shs3.b.qianxin.com/attack_forum/2021/10/attach-178de63d85ed2740f4bb4ec0f06f8645a7b5d559.png) 在这里对数组中的每个字符做\*和强对比的循环 [![](https://shs3.b.qianxin.com/attack_forum/2021/10/attach-935c63f171cde6d525eb5003e369de58254e9af1.png)](https://shs3.b.qianxin.com/attack_forum/2021/10/attach-935c63f171cde6d525eb5003e369de58254e9af1.png) 正因为URI后多加一个/,就能让`requestURI`和`pathPattern`匹配不上,直接进入else,并且能在else中的if使其`pathPattern`和`requestURINoTrailingSlash`成功匹配上。所以根据第一个拦截器的匹配不成功则又来到`doMatch`匹配第二个拦截器。 [![](https://shs3.b.qianxin.com/attack_forum/2021/10/attach-0bd3bb4696c8df6858d13fe96eabb00150a42bbb.png)](https://shs3.b.qianxin.com/attack_forum/2021/10/attach-0bd3bb4696c8df6858d13fe96eabb00150a42bbb.png) ```java protected boolean pathsMatch(String path, ServletRequest request) { String requestURI = this.getPathWithinApplication(request); log.trace("Attempting to match pattern '{}' with current requestURI '{}'...", path, Encode.forHtml(requestURI)); boolean match = this.pathsMatch(path, requestURI); if (!match) { if (requestURI != null && !"/".equals(requestURI) && requestURI.endsWith("/")) { requestURI = requestURI.substring(0, requestURI.length() - 1); } if (path != null && !"/".equals(path) && path.endsWith("/")) { path = path.substring(0, path.length() - 1); } log.trace("Attempting to match pattern '{}' with current requestURI '{}'...", path, Encode.forHtml(requestURI)); match = this.pathsMatch(path, requestURI); } return match; } protected boolean pathsMatch(String pattern, String path) { boolean matches = this.pathMatcher.matches(pattern, path); log.trace("Pattern [{}] matches path [{}] => [{}]", new Object[]{pattern, path, matches}); return matches; } protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception { if (this.appliedPaths != null && !this.appliedPaths.isEmpty()) { Iterator var3 = this.appliedPaths.keySet().iterator(); String path; do { if (!var3.hasNext()) { return true; } path = (String)var3.next(); } while(!this.pathsMatch(path, request)); log.trace("Current requestURI matches pattern '{}'. Determining filter chain execution...", path); Object config = this.appliedPaths.get(path); return this.isFilterChainContinued(request, response, path, config); } else { if (log.isTraceEnabled()) { log.trace("appliedPaths property is null or empty. This Filter will passthrough immediately."); } return true; } } ``` 以上代码对`/admin/vv/page/`做了末尾“/”的删除后得到`/admin/vv/page`又重新进入拦截器进行路径匹配 [![](https://shs3.b.qianxin.com/attack_forum/2021/10/attach-4def3b8e380b5ef5e4e98686f723865135d59786.png)](https://shs3.b.qianxin.com/attack_forum/2021/10/attach-4def3b8e380b5ef5e4e98686f723865135d59786.png) [![](https://shs3.b.qianxin.com/attack_forum/2021/10/attach-3743433803581a7919b712ddc9d5c84f828742c7.png)](https://shs3.b.qianxin.com/attack_forum/2021/10/attach-3743433803581a7919b712ddc9d5c84f828742c7.png) 与拦截器匹配成功则返回`matches`为true [![](https://shs3.b.qianxin.com/attack_forum/2021/10/attach-6b53a5c6e90c73e45d3667e4f8fefc8109f6e4a0.png)](https://shs3.b.qianxin.com/attack_forum/2021/10/attach-6b53a5c6e90c73e45d3667e4f8fefc8109f6e4a0.png) 由于mtahces为true则代表拦截器匹配成功,故最后来到在`AdviceFilter`类中`doFilterInternal`方法,并且输出指定路由的页面信息 [![](https://shs3.b.qianxin.com/attack_forum/2021/10/attach-13c0fd96e02edbeb1991aba0abf880bfe00ae21a.png)](https://shs3.b.qianxin.com/attack_forum/2021/10/attach-13c0fd96e02edbeb1991aba0abf880bfe00ae21a.png) [![](https://shs3.b.qianxin.com/attack_forum/2021/10/attach-1bedf8f9fa145809f2579d4a18887388567bbbb9.png)](https://shs3.b.qianxin.com/attack_forum/2021/10/attach-1bedf8f9fa145809f2579d4a18887388567bbbb9.png) 而访问 <http://localhost:8080/admin/vv/page> 是无法成功匹配至拦截器路径,因此以上的绕过则是利用“/”达到访问权限的绕过 [![](https://shs3.b.qianxin.com/attack_forum/2021/10/attach-13b972dea9573dc698dc58d2a91729747563126c.png)](https://shs3.b.qianxin.com/attack_forum/2021/10/attach-13b972dea9573dc698dc58d2a91729747563126c.png) 以下为漏洞利用时函数调用栈的全部内容 ```java doMatch:139, AntPathMatcher (org.apache.shiro.util) match:97, AntPathMatcher (org.apache.shiro.util) matches:93, AntPathMatcher (org.apache.shiro.util) pathsMatch:159, PathMatchingFilter (org.apache.shiro.web.filter) pathsMatch:127, PathMatchingFilter (org.apache.shiro.web.filter) preHandle:195, PathMatchingFilter (org.apache.shiro.web.filter) doFilterInternal:131, AdviceFilter (org.apache.shiro.web.servlet) doFilter:125, OncePerRequestFilter (org.apache.shiro.web.servlet) doFilter:66, ProxiedFilterChain (org.apache.shiro.web.servlet) executeChain:108, AdviceFilter (org.apache.shiro.web.servlet) doFilterInternal:137, AdviceFilter (org.apache.shiro.web.servlet) doFilter:125, OncePerRequestFilter (org.apache.shiro.web.servlet) doFilter:66, ProxiedFilterChain (org.apache.shiro.web.servlet) executeChain:450, AbstractShiroFilter (org.apache.shiro.web.servlet) call:365, AbstractShiroFilter$1 (org.apache.shiro.web.servlet) doCall:90, SubjectCallable (org.apache.shiro.subject.support) call:83, SubjectCallable (org.apache.shiro.subject.support) execute:387, DelegatingSubject (org.apache.shiro.subject.support) doFilterInternal:362, AbstractShiroFilter (org.apache.shiro.web.servlet) doFilter:125, OncePerRequestFilter (org.apache.shiro.web.servlet) internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core) doFilter:166, ApplicationFilterChain (org.apache.catalina.core) doFilterInternal:99, RequestContextFilter (org.springframework.web.filter) doFilter:107, OncePerRequestFilter (org.springframework.web.filter) internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core) doFilter:166, ApplicationFilterChain (org.apache.catalina.core) doFilterInternal:92, FormContentFilter (org.springframework.web.filter) doFilter:107, OncePerRequestFilter (org.springframework.web.filter) internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core) doFilter:166, ApplicationFilterChain (org.apache.catalina.core) doFilterInternal:93, HiddenHttpMethodFilter (org.springframework.web.filter) doFilter:107, OncePerRequestFilter (org.springframework.web.filter) internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core) doFilter:166, ApplicationFilterChain (org.apache.catalina.core) doFilterInternal:200, CharacterEncodingFilter (org.springframework.web.filter) doFilter:107, OncePerRequestFilter (org.springframework.web.filter) internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core) doFilter:166, ApplicationFilterChain (org.apache.catalina.core) invoke:200, StandardWrapperValve (org.apache.catalina.core) invoke:96, StandardContextValve (org.apache.catalina.core) invoke:490, AuthenticatorBase (org.apache.catalina.authenticator) invoke:139, StandardHostValve (org.apache.catalina.core) invoke:92, ErrorReportValve (org.apache.catalina.valves) invoke:74, StandardEngineValve (org.apache.catalina.core) service:343, CoyoteAdapter (org.apache.catalina.connector) service:408, Http11Processor (org.apache.coyote.http11) process:66, AbstractProcessorLight (org.apache.coyote) process:836, AbstractProtocol$ConnectionHandler (org.apache.coyote) doRun:1747, NioEndpoint$SocketProcessor (org.apache.tomcat.util.net) run:49, SocketProcessorBase (org.apache.tomcat.util.net) runWorker:1142, ThreadPoolExecutor (java.util.concurrent) run:617, ThreadPoolExecutor$Worker (java.util.concurrent) run:61, TaskThread$WrappingRunnable (org.apache.tomcat.util.threads) run:748, Thread (java.lang) ``` 0x04修复建议 ======== 请检查所使用的软件版本是否受在受影响范围内,并从官方渠道升级到安全版本或更新版本。Apache Shiro官方网站:<https://shiro.apache.org/index.html>
发表于 2021-10-27 17:55:39
阅读 ( 7832 )
分类:
漏洞分析
2 推荐
收藏
0 条评论
请先
登录
后评论
w1nk1
12 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!