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. Typora标题自动编号+设定快捷键技巧

    Typora标题自动编号 提示:要了解将这些CSS片段放在哪里,请参阅添加自定义CSS. 打开Typora偏好设置,打开主题文件夹,在主题文件夹中创建base.user.css文件,放置以下内容,则T ...

  2. 面试官问PHP四大主流框架的优缺点,看这篇就够了!

    本篇文章我们来讲讲PHP四大框架的优缺点都有哪些,让你们在开发中更好的去选择使用哪款PHP框架去完成项目,废话不多说,我们一起来看看吧!! ThinkPHP ThinkPHP(FCS)是一个轻量级的中 ...

  3. Julia语言程序基础

    Julia-lang 新兴的Julia语言,Julia 一开始就是为高性能而设计的. Julia 程序通过 LLVM 编译成高效的多平台机器码. Julia中文社区: https://cn.julia ...

  4. Docker下MySQL的安装

    1 概述 本文讲述了如何利用Docker去安装MySQL,以及MySQL自定义配置文件的相关设置. 2 安装Docker 首先安装Docker并开启服务: systemctl start docker ...

  5. 由电脑专卖系统引发的Java设计模式:访问者模式

    目录 定义 意图 解决问题 何时使用 优缺点 结构 电脑专卖系统 定义 访问者模式是对象的行为型模式,它的目的是封装一些施加于某些数据结构元素之上的操作,一旦这些操作需要修改的话,接收这个操作的数据结 ...

  6. JDBC_09_Statement 和 PreparedStatement

    Statement 和 PreparedStatement * Statement数据库操作对象存在SQL注入问题,而PreparedStatement预编译数据库操作对象解决了SQL注入问题. * ...

  7. 文件上传bypass安全狗

    0x00 前言 本文首发于先知社区:https://xz.aliyun.com/t/9507 我们知道WAF分为软WAF,如某狗,某盾等等:云WAF,如阿里云CDN,百度云CDN等等:硬WAF,如天融 ...

  8. thinkphp5安装php高版本出现No input file specified.解决

    <IfModule mod_rewrite.c> Options +FollowSymlinks -Multiviews RewriteEngine On RewriteCond %{RE ...

  9. 【多线程】Java线程池七个参数详解

    /** * Creates a new {@code ThreadPoolExecutor} with the given initial * parameters. * * @param coreP ...

  10. C/C++ 介绍的PE文件遍历工具

    在前面的笔记中,我总结了Pe结构的一些结构含义,并手动编写了几段PE结构遍历代码,这里我直接把之前的C语言代码进行了封装,形成了一个命令行版的PE文件查看工具,该工具只有20kb,但却可以遍历出大部分 ...