shiro-web CVE-2010-3863 路径绕过
[condition] < shiro 1.1.0
背景
如果对shiro-web的原理不清楚可以参考以下链接:shiro-web 软件分析
发送URL前,浏览器本身会对
../``./
这类路径进行处理,将其还原成实际路径,然后才会发送请求。
【url栏】http://ip:port/test/../admin.html ---> 【请求包】 http://ip:port/admin.html
但是,可以拦截请求包,对URL进行篡改
漏洞环境
https://github.com/dota-st/vulnEnv
文件结构:
主要配置文件:
realm.ini:
ShiroConfig:
package com.vuln.shirodemo.Shiro;
import java.util.LinkedHashMap;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Created by dotast on 2022/10/14 15:13
*/
@Configuration
public class ShiroConfig {
@Bean
public IniRealm getIniRealm(){
return new IniRealm("classpath:realm.ini");
}
@Bean
public DefaultWebSecurityManager getDefaultWebSecurityManager(Realm realm){
return new DefaultWebSecurityManager(realm);
}
/*
* anon:无需认证就可以访问
* authc:必须认证才能访问
* user:必须拥有记住我功能才能访问
* perms:拥有某个资源的权限才能访问
* role:拥有某个角色的权限才能访问
* */
@Bean
ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager) {
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setSecurityManager(defaultWebSecurityManager);
bean.setLoginUrl("/login.html");
LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
map.put("/admin.html", "authc, roles[admin]");
map.put("/user.html", "authc, roles[user]");
map.put("/**", "anon");
bean.setFilterChainDefinitionMap(map);
return bean;
}
}
漏洞分析
payload:
GET /./admin.html HTTP/1.1
Host: localhost:8088
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:130.0) Gecko/20100101 Firefox/130.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Priority: u=0, i
FlowChart:shiro-web整体流程
红色部分为漏洞点
详情:shiro-web 软件分析
代码分析
PathMatchingFilterChainResolver.getChain(...):
局部变量
可以看出没有做任何过滤,直接获取url
配置文件里设置的FilterChain的名字序列
最终匹配到/**
:
该链只有anon:AnonymousFilter一个过滤器
Anonymous的过滤逻辑:允许任何人通过
漏洞修复
如果是我,我会如何修复?
当然是像浏览器那样,将带有../
的路径规范化后再进行比较,比较逻辑不变
实际修复
shiro-1.1.0:
request中url没有变
但是requstURI 被规范化了
所以一定是getPathWithApplication(request)内部逻辑发生改变了
最后不断跟进找到:
//org.apache.shiro.web.util.WebUtils::
//shiro-1.0.1-incubating
public static String getRequestUri(HttpServletRequest request) {
String uri = (String) request.getAttribute(INCLUDE_REQUEST_URI_ATTRIBUTE);
if (uri == null) {
uri = request.getRequestURI();
}
return decodeAndCleanUriString(request, uri);
}
//shiro-1.1.0
public static String getRequestUri(HttpServletRequest request) {
String uri = (String)request.getAttribute("javax.servlet.include.request_uri");
if (uri == null) {
uri = request.getRequestURI();
}
return normalize(decodeAndCleanUriString(request, uri));
}
添加了一个normalize
函数
private static String normalize(String path, boolean replaceBackSlash) {
if (path == null) {
return null;
} else {
String normalized = path;
//'\' ASCII 是 92
if (replaceBackSlash && normalized.indexOf(92) >= 0) {
normalized = normalized.replace('\\', '/');
}
if (normalized.equals("/.")) {
return "/";
} else {
if (!normalized.startsWith("/")) {
normalized = "/" + normalized;
}
while(true) {
int index = normalized.indexOf("//");
if (index < 0) {
while(true) {
index = normalized.indexOf("/./");
if (index < 0) {
while(true) {
index = normalized.indexOf("/../");
if (index < 0) {
return normalized;
}
if (index == 0) {
return null;
}
// ‘/’ ASCII :47
int index2 = normalized.lastIndexOf(47, index - 1);
//循环去除 ‘/../’
normalized = normalized.substring(0, index2) + normalized.substring(index + 3);
}
}
//循环去除 ‘/./’
normalized = normalized.substring(0, index) + normalized.substring(index + 2);
}
}
//循环去‘//’
normalized = normalized.substring(0, index) + normalized.substring(index + 1);
}
}
}
}
Reference
JavaSec/12.Shiro/CVE-2010-3863权限绕过/index.md at main · Y4tacker/JavaSec (github.com)
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
文章目录