认证绕过依赖项
在每一个模块的cas-client.properties
文件中,都有如下字段的参数配置
# 不拦截的地址,支持正则表达式,按照组件需求配置
cas.ignore.pattern=/login,*.html,*.eot,*.woff,*.ttf,*.svg,*.gif,*.css,*.js,*.json,/casLogin,*.ico,*.icon,*.png,*.map,/api/meta/qrcode,/api/session,/api/session/captcha,/api/locales,/api/meta,/api/menus,......
其他模块的相关配置如下
搜索关键字: cas.ignore.pattern
认证的时候是通过正则匹配的方式,来判断当前请求的路径是否需要认证
每一个模块下都有一个这样的认证函数。
绕过过程调试
这里的认证绕过,主要是通过url
的处理的绕过,所以关键在对url
的处理上。
org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter#handle
org.springframework.web.servlet.resource.ResourceHttpRequestHandler#handleRequest
过程如下:
假设我们想访问portal
模块下的/front/common/getToken
接口,正常情况下未授权访问后,会跳转到登录页面。
跟踪一下从入口到报错,这整个过程对URL的处理。
我们的请求进入到应用后,会进入到认证过滤器,直接在SSO的认证过滤器处下断点
请求的链接成功断在了断点处
这个url
不是忽略的,直接进入下边的else
逻辑块。 这块逻辑直接拼接Cas认证
路径,跳转到Cas
了。
上边的跟踪并没有多大意义,没有跟到对URL
路径的具体处理逻辑,下边尝试构造绕过的URL,再次进行跟踪。
利用..;/
绕过认证
改进url
如下:https://xx.xx.xxx.x/portal/ui/login/..;/..;/front/common/getToken
,利用/ui/login
被忽略的特性,进行认证绕过。
直接在isRequestUrlExcluded()
函数中下断点,这里事通过getRequestUrl()
来获取URL路径,很大概率存在漏洞。
成功返回True
,也就是说成功的绕过了认证,接下来就进入了下一个过滤器。
该模块一共18个过滤器,当前是第11个过滤器,
在最后一个过滤器的时候,会调用处理程序,对URL路径进行处理。
org.springframework.web.servlet.resource.ResourceHttpRequestHandler#getResource
通过该函数进行请求的资源获取。如果没找到就返回404,如果找到了,就进一步处理。
进入getResource
后默认通过如下映射处理器获取路径。
如果返回空,再用如下两个映射处理器获取路径
其中org.springframework.web.util.UrlPathHelper.PATH
处理器已经把url
路径中的;
给去掉了。
在org.springframework.web.util.UrlPathHelper#resolveAndCacheLookupPath
中
其他的处理器
之后就是从如下几个目录中找到对应的资源,这里很显然没找到。
这里拼接了一个这样的路径,很显然找不到东西
那么,这时候就因该思考,前边某个地方应该进入接口路径的处理逻辑,而不是进入文件路径的处理逻辑。
经过再次整理,在org.springframework.web.servlet.DispatcherServlet#doDispatch
中找到获取映射处理器的函数调用
通过getMappingsByDirectPath()
在映射接口列表中获取对应的接口映射处理器
当然,这是在正确获取了url路径的情况下。我们构造的绕过认证的路径,很显然不是正常路径。
正常情况下获取到的路径
绕过认证构造的路径
如果是接口的认证绕过,就需要消除这个影响。
利用;.css
绕过认证
现在需要满足一个条件,用来绕过认证的字符,在认证绕过之后,需要利用应用自身机制把多余的字符删除掉。那么就需要认证的字符串放到url后边,利用/*.css
的规则就比较合适了。
经过一番查找,很遗憾,该模块没有后缀忽略的规则。。。
可绕过总结
应用程序用匹配规则是正则匹配,这个匹配特别严格,是全字符匹配。
本地写了个脚本,看一下具体执行情况。大志分这么几种情况,方案一采用的是前边验证,方案二采用的后缀验证。
根据上边脚本运行的情况,再匹配忽略规则,就很容易知道哪些可以用来绕过前边检查,哪些可以用来绕过后缀检查了。