CVE-2020-17523 shiro認證鑒權繞過復現


影響版本

  • Apache Shiro < 1.7.1

環境搭建

參考 https://github.com/jweny/shiro-cve-2020-17523

漏洞分析

代碼作者設定:

  • 訪問/login頁面會提示please login
  • 訪問/admin/**代表任意,網站會自動跳轉至/login頁面,表示用戶未登錄鑒權失敗
  • 直接訪問/admin會直接報錯404,因為沒有可以映射的url

代碼在ShiroConfig中配置了shiro過濾器,可參考下圖:

ShiroFilterFactoryBean shiroFilterFactoryBean(){
    ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
    bean.setSecurityManager(securityManager());
    bean.setLoginUrl("/login");
    bean.setSuccessUrl("/index");
    bean.setUnauthorizedUrl("/unauthorizedurl");
    Map<String, String> map = new LinkedHashMap<>();
    map.put("/doLogin/", "anon");
    map.put("/admin/*", "authc"); 
    bean.setFilterChainDefinitionMap(map);
    return  bean;
}

漏洞利用:
訪問/admin/%20會繞過shiro的鑒權認證,url會由spring處理跳轉至admin頁面:

通過比較shiro1.7.0和shiro1.7.1的源碼:https://sourcegraph.com/github.com/apache/shiro/-/compare/shiro-root-1.7.0...shiro-root-1.7.1
可以發現主要改動的代碼為core/src/main/java/org/apache/shiro/util/AntPathMatcher.java

直接在IDEA中搜索AntPatchMatcher類:

doMatch函數第一行打上斷點,在多次步進后進入到/admin/ /admin/*的匹配階段:

可以發現pathDirs中的空格已經丟失,所以這里的/admin/%20就直接變成了/admin
分析StringUtils.tokenizeToStringArray

//trimTokens=true,str=/admin/ ,delimiters="/",ignoreEmptyTokens=true
public static String[] tokenizeToStringArray(String str, String delimiters, boolean trimTokens, boolean ignoreEmptyTokens) {
        if (str == null) {
            return null;
        } else {
            StringTokenizer st = new StringTokenizer(str, delimiters); //用於分割字符串
            ArrayList tokens = new ArrayList();

            while(true) {
                String token;
                do {
                    if (!st.hasMoreTokens()) {  //判斷是否有多余的分隔符
                        return toStringArray(tokens);
                    }

                    token = st.nextToken();  //獲取當前位置到下一個分隔符之間的字符串
                    if (trimTokens) {   //是否對token進行特殊字符的刪除,包括空格、換行符、\t等,由於這里為true,所以獲取到空格時,空格被去掉了。
                        token = token.trim();
                    }
                } while(ignoreEmptyTokens && token.length() <= 0);

                tokens.add(token);
            }
        }
    }

所以這里的/admin/%20未匹配到自定義的shiro過濾器中的/admin/*,最后url直接映射到Spring的GetMapping里了,然后就直接返回了admin頁面。

漏洞修復

升級到0.17.1版本,通過查看代碼可以知道官方修復時將參數trimTokens 設置為false


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM