# Apache Shiro 權限繞過漏洞CVE-2020-11989的分析
## 一、漏洞背景
Apache Shiro是一個強大且易用的Java安全框架,提供認證、授權、加密和會話管理等功能。2020年6月,Apache Shiro官方披露了一個高危權限繞過漏洞(CVE-2020-11989),該漏洞影響版本為1.5.3及以下,當Shiro與Spring框架結合使用時,攻擊者可構造特殊請求繞過權限控制。
### 1.1 漏洞基本信息
- **CVE編號**:CVE-2020-11989
- **漏洞類型**:權限繞過
- **影響版本**:Apache Shiro ≤ 1.5.3
- **CVSS評分**:9.8(Critical)
- **漏洞公開時間**:2020年6月22日
### 1.2 漏洞產生環境
當同時滿足以下條件時易受攻擊:
1. 使用Spring框架的`DispatcherServlet`(如Spring Boot)
2. 配置了Shiro的URL路徑過濾規則
3. 存在靜態資源目錄(如`/static`、`/public`)
## 二、漏洞原理分析
### 2.1 Shiro的URL匹配機制
Shiro通過`PathMatchingFilterChainResolver`進行URL路徑匹配,核心邏輯如下:
```java
public FilterChain getChain(ServletRequest request, ServletResponse response, FilterChain originalChain) {
String requestURI = getPathWithinApplication(request);
for (String pathPattern : filterChainManager.getChainNames()) {
if (pathMatches(pathPattern, requestURI)) {
return filterChainManager.proxy(originalChain, pathPattern);
}
}
return null;
}
Spring的DispatcherServlet在處理請求時會對路徑進行規范化:
1. 解碼URL編碼字符(如%2e→.)
2. 處理路徑遍歷符號(如/../)
3. 移除重復斜杠(如//→/)
當攻擊者構造如下請求時:
http://target.com/;/admin
;/admin被當作完整路徑進行匹配,若未配置該路徑規則則放行;被當作合法字符處理,最終路由到/admin控制器;在RFC 3986中屬于合法字符但處理不規范<!-- pom.xml 依賴 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
@Bean
public ShiroFilterFactoryBean shiroFilter() {
ShiroFilterFactoryBean factory = new ShiroFilterFactoryBean();
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/admin/**", "authc"); // 需要認證
filterMap.put("/static/**", "anon"); // 允許匿名訪問
factory.setFilterChainDefinitionMap(filterMap);
return factory;
}
| 請求方式 | 惡意URL | 繞過效果 |
|---|---|---|
| GET | http://target.com/;/admin |
訪問受保護的管理頁面 |
| POST | http://target.com/static/..;/admin/update |
通過靜態目錄繞過 |
curl -v "http://localhost:8080/;/admin"
* 注意觀察響應碼200(正常應為302跳轉登錄頁)
升級到Shiro 1.6.0及以上版本,主要修改:
1. 新增removeSemicolon()方法處理分號
private String removeSemicolon(String uri) {
int semicolonIndex = uri.indexOf(';');
return (semicolonIndex != -1) ? uri.substring(0, semicolonIndex) : uri;
}
getPathWithinApplication()方法調用鏈// 自定義Filter繼承AccessControlFilter
@Override
protected boolean isAccessAllowed(ServletRequest request,
ServletResponse response, Object mappedValue) {
HttpServletRequest req = (HttpServletRequest) request;
String uri = req.getRequestURI();
if (uri.contains(";")) {
return false; // 直接拒絕含分號的請求
}
return true;
}
/**通配符規則| 處理階段 | /%3badmin |
/;admin |
/static/../admin |
|---|---|---|---|
| 瀏覽器編碼 | %3badmin | ;admin | static/../admin |
| Shiro解析 | %3badmin | ;admin | static/../admin |
| Spring解析 | ;admin | ;admin | admin |
除分號外,以下字符也需注意:
- 反斜杠\(Windows路徑特性)
- Unicode編碼字符(如\u002e)
- URL雙重編碼(如%252e)
| CVE編號 | 觸發條件 | 影響范圍 |
|---|---|---|
| CVE-2020-1957 | Spring+Shiro路徑穿越 | Shiro < 1.5.2 |
| CVE-2020-11989 | 分號處理差異 | Shiro ≤ 1.5.3 |
| CVE-2021-41303 | 正則匹配缺陷 | Shiro < 1.8.0 |
# 使用nmap檢測
nmap -p 80,443 --script http-shiro-auth-bypass <target>
”`
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。