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,这时候实际访问到的是http://127.0.0.1/login/main.do

但使用

 StringBuffer requestURL = request.getRequestURL();
if(requestURL.toString().startsWith("/system/login"))

request.getRequestURL();该方法获取URL是携带http://127.xxx等信息的。其实这里比较废话,因为验证首部的字符路径的话,使用 request.getRequestURI();来获取请求路径部分来校验。

URL截断绕过

基于前面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(); if(uri.contains("./")){
resp.getWriter().write("error");
return;
}
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");
}
} chain.doFilter(request,resp);
} public void init(FilterConfig config) throws ServletException { }
}

添加多了一个uri.contains("./")做过滤只要包含./字符直接报错。

这时候会报错,可见上图。可进行绕过

payload:/login/main.do;123

绕过分析

URL中有一个保留字符分号;,主要为参数进行分割使用,有时候是请求中传递的参数太多了,所以使用分号;将参数对(key=value)连接起来作为一个请求参数进⾏传递。

再来看到代码,代码中识别.do.action的后缀的字符,而加入;加上随便内容后,代码中就识别不到了。则会走到最下面的chain.doFilter(request,resp);,而在后面添加分号不会对地址的访问有任何影响。

绕过

创建一个后台接口,只允许admin用户登录访问

package com.nice0e3.Servlet;

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("/system/UserInfoSearch.do")
public class UserInfoServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().write("admin_login!!!");
} protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}

而权限控制这步肯定是在Filter里面实现

     String uri = request.getRequestURI();

        if(uri.equals("/system/UserInfoSearch.do")){
User user =(User) request.getSession().getAttribute("user");
String role = user.getRole();
if(role.equals("admin")) {
//当前⽤用户为admin,允许访问该接⼝
chain.doFilter(request, resp);
}
else {
resp.getWriter().write("Unauthorized");
return;
}
}

这时候去对/system/UserInfoSearch.do做了校验,获取URI地址后匹配如果是这个/system/UserInfoSearch.do,则验证用户身份,加入不为admin,则显示Unauthorized,越权访问。

可直接访问到admin用户才可访问的页面下。

payload: //system/UserInfoSearch.do;123

绕过分析

看到代码中只是对比了URI是否为/system/UserInfoSearch.do,而多加一个/并不影响正常解析,而又能让该规则匹配不到。

URL编码绕过

还是用上面的代码演示,绕过手法则是换成url编码绕过的方式。

payload:/system/%55%73%65%72%49%6e%66%6f%53%65%61%72%63%68%2e%64%6f

绕过分析

当Filter处理完相关的流程后,中间件会对请求的URL进行一次URL解码操作,然后请求解码后的Servlet,而在request.getRequestURL()和request.getRequestURI()中并不会自动进行解码,所以这时候直接接收过来进行规则匹配,则识别不出来。这时候导致了绕过。

Spring MVC中追加/绕过

在SpringMVC中假设以如下方法配置:

<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

特定情况下Spring匹配web路径的时候会容错后面的/

如,/admin/main.do/

修复

使用该代码接受URI

String uri1 = request.getServletPath() + (request.getPathInfo() != null ? request.getPathInfo() : "");

下面来尝试前面的几种绕过方式。

分号阶段绕过 payload: /login/main.do;123

/绕过payload: //system/UserInfoSearch.do;123

URL编码绕过payload:/system/%55%73%65%72%49%6e%66%6f%53%65%61%72%63%68%2e%64%6f

../绕过payload:/system/login/../../login/main.do

均不可用,使用上面的方式接受URI后,接受过去的时候发送特殊字符一律被剔除了。打断点可见。

关注点

前面提到过request.getRequestURL()request.getRequestURI(),这些危险字符并不会自动剔除掉。可重点关注该方法。

参考

https://blog.csdn.net/qq_38154820/article/details/106799046

0x02 结尾

不只是Filter里面可以做权限绕过,在使用到一些Shiro框架的时候,也会有一些权限绕过的方式。

Java安全之Filter权限绕过的更多相关文章

  1. Java 中的 Filter 过滤器详解

    Filter简介 Filter也称之为过滤器,它是Servlet技术中最实用的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件 ...

  2. Java中的Filter过滤器

    Filter简介 Filter也称之为过滤器,它是Servlet技术中最实用的技术,Web开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件 ...

  3. java之过滤器Filter

    Java三大器之过滤器(Filter)的工作原理和代码演示   一.Filter简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术之一,WEB开发人员通过Filter技术,对w ...

  4. java web中filter分析

    摘自博客园,博主孤傲苍狼 一.Filter简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp ...

  5. Android电话拨打权限绕过漏洞(CVE-2013-6272)分析

    原文:http://blogs.360.cn/360mobile/2014/07/08/cve-2013-6272/ 1. CVE-2013-6272漏洞背景 CVE-2013-6272是一个安卓平台 ...

  6. java web之Filter详解

    java web之Filter详解 2012-10-20 0 个评论 作者:chenshufei2 收藏 我要投稿 .概念: Filter也称之为过滤器,它是Servlet技术中比较激动人心的技术,W ...

  7. Java中的访问控制权限

    简介 Java中为什么要设计访问权限控制机制呢?主要作用有两点: (1)为了使用户不要触碰那些他们不该触碰的部分,这些部分对于类内部的操作时必要的,但是它并不属于客户端程序员所需接口的一部分. (2) ...

  8. Java成员的访问权限控制

    Java中的访问权限控制包含两个部分: 类的访问权限控制 类成员的访问权限控制 对类来说,访问权限控制修饰符可以是public或者无修饰符(默认的包访问权限): 对于类成员来说,访问权限控制修饰符可以 ...

  9. 浅析Java中的访问权限控制

    浅析Java中的访问权限控制 今天我们来一起了解一下Java语言中的访问权限控制.在讨论访问权限控制之前,先来讨论一下为何需要访问权限控制.考虑两个场景: 场景1:工程师A编写了一个类ClassA,但 ...

随机推荐

  1. 2、MyBatis教程之第一个MyBatis程序

    3.MyBatis第一个程序 1.搭建实验数据库 CREATE DATABASE `mybatis`; USE `mybatis`; DROP TABLE IF EXISTS `user`; CREA ...

  2. Git命令太多记不住?有了这个神器,从此告别输入命令行

    一 .SourceTree简介 SourceTree 是 Windows 和Mac OS X 下免费的 Git 和 Hg 客户端,拥有可视化界面,容易上手操作.同时它也是Mercurial和Subve ...

  3. Starting Tomcat v9.0 Server at localhost' has encountered a problem

    •问题描述 在通过 Eclipse 打开 Tomcat 时报错: •解决方案 找到 Tomcat 的安装位置,打开 tomcat\bin 目录,找到 shutdown.bat,手动关闭 tomcat: ...

  4. PAT (Advanced Level) Practice 1031 Hello World for U (20 分) 凌宸1642

    PAT (Advanced Level) Practice 1031 Hello World for U (20 分) 凌宸1642 题目描述: Given any string of N (≥5) ...

  5. PAT (Basic Level) Practice (中文) 1050 螺旋矩阵 (25 分) 凌宸1642

    PAT (Basic Level) Practice (中文) 1050 螺旋矩阵 (25 分) 目录 PAT (Basic Level) Practice (中文) 1050 螺旋矩阵 (25 分) ...

  6. MySQL巩固学习记录(一)

    mysql下载安装 一.采用图形化界面安装 (初期只安装server服务端就可以了,别的不多赘述) 二.采用压缩版安装 1.将文件解压缩到自己想要的路径 2. 添加环境变量,即mysql的bin目录 ...

  7. .NET 6 Preview 3 发布

    前言 2021/4/8 .NET 6 Preview 3 发布,这个版本的改进大多来自于底层,一起来看看都有什么新特性和改进吧. 库改进 新增值类型作为字典值时更快的处理方法 .NET 6 Previ ...

  8. [Fundamental of Power Electronics]-PART I-2.稳态变换器原理分析-2.3 Boost 变换器实例

    2.3 Boost 变换器实例 图2.13(a)所示的Boost变换器器是另一个众所周知的开关模式变换器,其能够产生幅值大于直流输入电压的直流输出电压.图2.13(b)给出了使用MOSFET和二极管的 ...

  9. HarmonyOS三方件开发指南(17)-BottomNavigationBar

    目录: 1.引言 2.功能介绍 3.BottomNavigationBar使用指南 4.BottomNavigationBar开发指南 5.<HarmonyOS三方件开发指南>文章合集 引 ...

  10. 关于ArrayList 中子方法 -- contains 疑惑解决

    写之前先看下 ArrayList 子函数 contains 的Api 怎么介绍: boolean contains(Object o)           如果此列表中包含指定的元素,则返回 true ...