Java安全之Filter权限绕过 0x00 前言
在一些需要挖掘一些无条件RCE中,大部分类似于一些系统大部分地方都做了权限控制的,而这时候想要利用权限绕过就显得格外重要。在此来学习一波权限绕过的思路。
0x01 权限控制实现常见的实现方式,在不调用Spring Security、Shiro等权限控制组件的情况下,会使用Filter获取请求路径,进行校验。
编写一个servlet
package com.nice0e3; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet("/helloServlet") public class helloServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().write("hello!!!"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }定义一个Filter
package com.nice0e3.filter; import com.nice0e3.User; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import java.io.IOException; @WebFilter("/*") public class demoFilter implements Filter { public void destroy() { } public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { HttpServletRequest request = (HttpServletRequest) req; String uri = request.getRequestURI(); StringBuffer requestURL = request.getRequestURL(); System.out.println(requestURL); if(uri.startsWith("/system/login")) { //登陆接口设置⽩白名单,即登录页面 System.out.println("login_page"); resp.getWriter(). write("login_page"); chain.doFilter(request, resp); } else if(uri.endsWith(".do")||uri.endsWith(".action")) { //检测当前⽤户是否登陆 User user =(User) request.getSession().getAttribute("user"); if(user == null) { resp.getWriter(). write("unauthorized access"); //未授权访问 System.out.println("unauthorized access"); resp.getWriter(). write("go to login_page");//跳转登录 System.out.println("go to login_page"); } } } public void init(FilterConfig config) throws ServletException { } }这里使用 request.getRequestURI();获取URI为 /system/login开头 则直接放行。结尾,为.do和.action的请求去做校验,获取session有没有user的值,没有的话即返回unauthorized access,如果不为.do和.action的请求或session中存在user即放行。
访问main页面,显示未授权访问并且跳转到登录的页面
在Java中通常会使用request.getRequestURL()和request.getRequestURI()这两个方法获取请求路径,然后对请求路径做校验。
../绕过方式这里采用../的方式绕过
这里就绕过了,权限控制,直接能访问到main,而不是显示未授权访问。在绕过时候可以找一些白名单的路径,然后使用../去绕过。
payload:/system/login/../../login/main.do
绕过原理分析上图可以看到我们前面为system/login开头
符合匹配的规则,而匹配上该规则后则是直接放行,让系统认为访问路径是一个登录的路径,但在后面加入2个../进行跳转到根目录,并且拼接上login/main.do,这时候实际访问到的是。
但使用
StringBuffer requestURL = request.getRequestURL(); if(requestURL.toString().startsWith("/system/login"))