type
Post
status
Published
date
slug
summary
tags
CTF
推荐
category
CTF-Knowledge
category (1)
icon
password
comment

filter设计缺陷导致的权限绕过

1.1 权限控制的本质

一般来说,为了防止越权操作,通常会结合filter进⾏相关接⼝的鉴权操作。其中不不外乎就是对每⼀个接口(通俗来说就是我们的URI/URL)进行业务梳理,然后判断当前URI/URL是否具有相应的业务权限。

1.2 常见权限控制的实现

一般情况下,通常是获取到当前URI/URL,然后跟需要鉴权的接口进行⽐对,或者直接结合startsWith()或者endsWith()方法,设置对应的校验名单。
例如下⾯的过滤器实现,以/login开头的不需要校验(登陆业务每个人都可以访问),所有.do/.action结尾的接⼝均需要做登陆检查,防止未授权访问等。
但是,在Java中获取当前request中的URI/URL通常会使用request.getRequestURL()和request.getRequestURI()这两个方法,但是如果没有进⾏相关的处理的话,有可能导致权限控制绕过的风险。

1.3 绕过方式

当权限过滤器获取当前request中的URI/URL使用request.getRequestURL()和request.getRequestURI()这两个方法时,可以考虑以下三种⽅式进行权限绕过:

1.3.1 非标准化绕过

  • 相关场景:
例如/system/login开头的接口是白名单,不需要进行访问控制(登陆页面所有人都可以访问),其他接⼝都需要
  • 相关效果如下:
当未登录直接访问UserInfoSearch.do接口时,显示未授权访问:
img
img
  • 相关原理:
中间件在进⾏解析时,会对我们URI中的../进行相关处理从⽽得到相关的servlet。也就是说尝试对我们访问的URL引入../,中间件是可以正常解析并完成正常业务的,以tomcat中的examples目录中的案例servlet访问为例,尝试访问一个不存在的目录login,然后通过../回到正常目录下,正常解析:
img
img
  • 绕过分析:
使用request.getRequestURL()和request.getRequestURI()这两个方法进⾏访问接口的获取时,是不会对类似../等进⾏规范化处理的,也就是说刚刚我们访问的/system/login/../UserInfoSearch.do际获取到的URI为:
img
img
同样是前⾯的例子,那么我们可以通过在URI中写⼊/login/../,使得权限过滤器认为我们当前访问的接⼝为白名单接口,从而绕过权限控制,使得系统认为我们当前访问的接⼝是登陆login,不需要进行权限校验:
img
img
  • 绕过方法:

1.3.2 URL截断绕过

  • 相关场景:
例如/system/login开头的接⼝是⽩名单,不需要进行访问控制(登陆⻚面所有人都可以访问),其他接口都需要进行登陆检查,防止未授权访问,但是考虑到了../的非法访问问题:
  • 相关效果如下:
当未登录直接访问UserInfoSearch.do接⼝时,显示未授权访问:
img
img
尝试结合../伪造白名单,失败:
img
img
  • 相关原理:
URL中有一个保留字符分号(;),主要作为参数分隔符进行使用,有时候是请求中传递的参数太多了,所以使用分号(;)将参数对(key=value)连接起来作为一个请求参数进⾏传递。
Tomcat对URL特殊字符的处理
在URL中遇到;号会将;xxx/中的分号与斜杠之间的字符串以及分号本身都去掉
直接在URI中引入分隔符,正常来说是不会对实际接口的访问造成影响的。
  • 绕过分析:
对于request.getRequestURL()和request.getRequestURI()来说,使用&连接的参数键值对,其是获取不到的,但是参数分隔符(;)及内容是可以获取到的:
img
img
同样是前面的例子,访问.do结尾的接口需要进行登陆检查,否则认为未授权访问,那么此时可以利用分隔符,绕过endsWith()检测,使得权限过滤器认为我们访问的接口不是业务接口,从而达到绕过权限控制的效果:
img
img
  • 绕过⽅法:

1.3.3 URL编码绕过

  • 相关场景:
例如/system/UserInfoSearch.do接⼝是管理员才能访问的接口,需要进⾏⽤户检查,防止越权访问:
  • 相关效果如下:
若不是admin用户登陆,拒绝访问UserInfoSearch.do接口:
img
img
否则返回当前系统存在的用户名:
img
img
  • 相关原理:
当filter处理完相关的流程后,中间件会对请求的URL进行一次URL解码操作,然后再找到对应的Servlet进行访问。
也就是说尝试对我们访问的URL进行一次URL编码,中间件是可以正常解析并完成正常业务的,以tomcat中的examples⽬目录中的案例servlet访问为例,尝试将HelloWorldExample进行URL编码再进行访问,正常解析:
img
img
  • 绕过分析:
除了前面介绍的两种方式以外,这里存在一个问题,使用request.getRequestURL()和request.getRequestURI()这两个⽅法进⾏行行访问接口的获取时,是不会进行URL解码操作的,也就是说刚刚我们访问的
/system/%55%73%65%72%49%6e%66%6f%53%65%61%72%63%68%2e%64%6f实际获取到的URI为:
img
img
那么我们可以通过对URI进行URL编码,此时filter中得到的uri并不是正常的/system/UserInfoSearch.do,⽽是编码后的,但是filter转发请求后浏览器可以解码并正常解析,从而达到以低权限用户绕过权限控制访问管理员接口的效果:
img
img
  • 绕过⽅法:

1.3.4 Spring Web的动态Controller追加/绕过

  • 相关场景:
一般情况下,通常是获取到当前URI/URL,然后跟需要鉴权的接⼝进行比对,结合endsWith()方法,设置对应的校验名单。
例如下面的过滤器实现,所有.do、.action结尾的接口均需要做登陆检查,防⽌止未授权访问等。、
  • 相关原理:
特定情况下,Spring web在匹配url接⼝的时候会容错后⾯额外的/。
以Spring MVC为例例,如下配置的话,在实际接口访问的时候会容错后⾯额外的/:
例如以下两种访问方式效果都是一样的:
  • 绕过分析:
考虑到上⾯使用request.getRequestURL()和request.getRequestURI()这两个⽅方法进行访问接⼝的获取时存在的安全隐患,这里使用 request.getServletPath()+(request.getPathInfo() == null ? “” :
request.getPathInfo())进行路径的获取,但是如果在接口URI后追加额外的/,还是可以获取到的:
img
GeekChallenge2023-miscDASCTF-X-HDCTF-2024-公开赛
Loading...