request.getRequestURL();该方法获取URL是携带等信息的。其实这里比较废话,因为验证首部的字符路径的话,使用 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
绕过分析