Java安全之Filter权限绕过

Java安全之Filter权限绕过0x00前言在一些需要挖掘一些无条件RCE中,大部分类似于一些系统大部分地方都做了权限控制的,而这时候想要利用权限绕过就显得格外重要。在此来学习一波权限绕过的思

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

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即放行。

Java安全之Filter权限绕过

访问main页面,显示未授权访问并且跳转到登录的页面

Java安全之Filter权限绕过

在Java中通常会使用request.getRequestURL()request.getRequestURI()这两个方法获取请求路径,然后对请求路径做校验。

../绕过方式

这里采用../的方式绕过

Java安全之Filter权限绕过

Java安全之Filter权限绕过

这里就绕过了,权限控制,直接能访问到main,而不是显示未授权访问。在绕过时候可以找一些白名单的路径,然后使用../去绕过。

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

绕过原理分析

上图可以看到我们前面为system/login开头

Java安全之Filter权限绕过

符合匹配的规则,而匹配上该规则后则是直接放行,让系统认为访问路径是一个登录的路径,但在后面加入2个../进行跳转到根目录,并且拼接上login/main.do,这时候实际访问到的是http://127.0.0.1/login/main.do

但使用

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

Java安全之Filter权限绕过

Java安全之Filter权限绕过

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("./")做过滤只要包含./字符直接报错。

Java安全之Filter权限绕过

Java安全之Filter权限绕过

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

Java安全之Filter权限绕过

Java安全之Filter权限绕过

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,越权访问。

Java安全之Filter权限绕过

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

payload: //system/UserInfoSearch.do;123

绕过分析

Java安全之Filter权限绕过

Java安全之Filter权限绕过

看到代码中只是对比了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

Java安全之Filter权限绕过

绕过分析

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

Java安全之Filter权限绕过

Java安全之Filter权限绕过

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

Java安全之Filter权限绕过

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

Java安全之Filter权限绕过

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

Java安全之Filter权限绕过

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

Java安全之Filter权限绕过

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

Java安全之Filter权限绕过

关注点

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

参考

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

0x02 结尾

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/119870.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 十二个开源UML工具

    十二个开源UML工具本文将为您介绍12个优秀的UML工具:1.StarUMLStarUML(简称SU),是一种创建UML类图,是一种生成类图和其他类型的统一建模语言(UML)图表的工具。StarUML是一个开源项目之一发展快、灵活、可扩展性强(zj)。2.NetbeansUMLPlugin目前支持:Activity图,Class图,Sequence图,State图以及Use…

    2022年7月12日
    20
  • Idea激活码永久有效Idea2017.3.7激活码教程-持续更新,一步到位

    Idea激活码永久有效Idea2017.3.7激活码教程-持续更新,一步到位Idea激活码永久有效2017.3.7激活码教程-Windows版永久激活-持续更新,Idea激活码2017.3.7成功激活

    2022年6月17日
    37
  • HSQL 学习笔记

    HSQL 学习笔记HSQL学习笔记1.    hsql 学习1.1.    学习目的本文档是针对hSQL 数据库方面的基础学习,为了使项目组成员能够达到使用hSQL 数据库的目的。1.2.    培训对象开发人员1.3.    常用词及符号说明常用词:hsql:一种免费的跨平台的数据库系统E:\hsqldb:表示是在dos 命令窗口下面1.4.    参考信息doc

    2022年9月22日
    6
  • 广义表中关于tail和head的计算

    广义表中关于tail和head的计算根据表头、表尾的定义可知:任何一个非空广义表的表头是表中第一个元素,它可以是原子,也可以是子表,而其表尾必定是子表。也就是说,广义表的head操作,取出的元素是什么,那么结果就是什么。但是tail操作取出的元素外必须加一个表——“ ()“举一个简单的列子:已知广义表LS=((a,b,c),(d,e,f)),如果需要取出这个e这个元素,那么使用tail和head如何将这个取出来。利用上面说的,tai…

    2022年5月4日
    108
  • [CentOS]离线安装gcc/gcc-c++-「建议收藏」

    [CentOS]离线安装gcc/gcc-c++-「建议收藏」环境CentOS7.5官方地址:https://gcc.gnu.org/releases.html镜像站点1:http://mirrors.aliyun.com/centos/7/os/x86_64/Packages/镜像站点2:https://vault.centos.org/7.5.1804/os/x86_64/Packages/gcc:4.8.5安装GCCgcc依赖包清单如下(镜像站下载)cpp-4.8.5-44.el7.x86_64.rpmgcc-4.8.5-44.el7.

    2022年5月9日
    618
  • UVa 10763 – Foreign Exchange

    UVa 10763 – Foreign Exchange

    2021年9月2日
    46

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号