当前位置: 首页 > article >正文

第33天:安全开发-JavaEE应用SQL预编译Filter过滤器Listener监听器访问控制

时间轴:

33天学习内容:

703b780e9b8f43219d3363a343e27f4d.png

内存马介绍:(转存于浅析JavaWeb内存马基础原理与查杀思路-CSDN博客)

c72d1c57c2cd4115ac0391c0275dcbc0.png

现在所流行的内存马也是有使用了filter和listener

SQL预编译:

133d23706ebb488a82a44f554704ffad.png

危险写法:

sql预编译使用代码:(运行时使用第二个执行符号)

32fef348bf6b44afa54742d1fe732683.png

public class NewsServlet {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {

        //接受用户输入的 变量字符串s接受
        Scanner scanner=new Scanner(System.in);
        System.out.print("please input id:");
        String s=scanner.nextLine();
        System.out.println(s);


        Class.forName("com.mysql.jdbc.Driver");
        String url ="jdbc:mysql://localhost:3306/demo1";
        Connection connection = DriverManager.getConnection(url,"root","root");
        System.out.println(connection);

        //不安全的写法
        String sql="select * from news where id="+s;
        System.out.println(sql);
        Statement statement= connection.createStatement();
        ResultSet resultSet = statement.executeQuery(sql);

7471f237a9bd4abdbc076996e0ffe9fd.png

造成结果SQL注入:

7169075b5c0f4df793dbbefdfeef44b9.png

注入语句为:

1 union select 1,2,3,version(),user(),database()

安全写法:

安全写法代码如下(数据库内容遍历省略)

127078cff9e54d188e65abf281a2bb41.png

        //预编译写法
        String safesql="select * from news where id=?";
        PreparedStatement preparedStatement=connection.prepareStatement(safesql);
        preparedStatement.setString(1,s);
        ResultSet resultSet=preparedStatement.executeQuery();
        System.out.println(safesql);
代码解析如下:

// 定义了一个安全的SQL查询字符串,其中包含一个参数占位符(?),用于后续绑定具体的值  
String safesql="select * from news where id=?";  
  
// 使用connection对象(通常是一个已经建立好的数据库连接)来创建一个PreparedStatement对象  
// PreparedStatement对象允许你设置SQL语句中的参数,并且这些参数在发送到数据库之前会被自动地转义,从而防止SQL注入攻击  
PreparedStatement preparedStatement=connection.prepareStatement(safesql);  
  
// 通过setString方法设置SQL语句中第一个参数(?)的值为变量s的值  
// 这里假设s是一个已经定义好的String类型的变量,它包含了要查询的新闻ID  
preparedStatement.setString(1,s);  
  
// 执行PreparedStatement对象中的SQL查询,并返回一个ResultSet对象  
// ResultSet对象包含了查询结果的所有行,你可以通过遍历ResultSet来访问每一行的数据  
ResultSet resultSet=preparedStatement.executeQuery();  
  
// 打印原始的SQL模板字符串,但请注意,这里打印的safesql并不包含已经绑定的参数值  
// 它仅仅是定义时的字符串:"select * from news where id=?"  
System.out.println(safesql);  
  
// 如果需要处理查询结果,应该在这里添加遍历ResultSet的代码  
// 例如:  
// while(resultSet.next()) {  
//     // 处理每一行数据  
//     String title = resultSet.getString("title"); // 假设news表有一个名为title的列  
//     System.out.println(title);  
// }  
  
// 注意:在实际应用中,还需要添加异常处理代码来捕获和处理可能发生的SQLException  
// 以及在代码的最后关闭ResultSet、PreparedStatement和Connection对象,以释放数据库资源

结果如下:

769fa8a37a194959ba3bd4a7de08f622.png注入语句为: 1 union select 1,2,3,version(),user(),database()

1 a,1 and 11=11 都有数据正常回显。

22这种没有回显,sleep()是延时回应,输入后没有影响。

预编译绕过:

需要特定的条件,和warf一样

Fliter过滤器:

原理:

d76e0168c6404154a6d789dd5636ed2c.png

内存马就是写在代码中,没有写在文件里。内存马在listener和filter,而不是在后门Servlet里面。

e007ddb9ce1741d190cac6fdacc15650.png

测试步骤:

1.创建过滤器(可以删掉.mvn,.gitgnore,mvnw,mvnw.cmd使代码更简洁)

2.创建TestServlet,在其可以使用alt + insert进行测试重写(选择重写方法)等

参考文章:史上最全的IDEA快捷键总结_idea 变量全选-CSDN博客

3.路由使用时需要配置web.xml(配置方法上期说过)或在代码前加入@WebServlet("/test")

4.运行尝试:(使用/test?code=<script>alert(1)</script>)

//以下为TestServlet
//@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.flush();
        out.close();
    }
}



//以下为web.xml
    <servlet>
        <servlet-name>TestServlet</servlet-name>
        <servlet-class>com.example.filterdemo01.TestServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>TestServlet</servlet-name>
        <url-pattern>/test</url-pattern>
    </servlet-mapping>

859adb8bd5404b2aa7f28272b8d4cab8.png

使用:

1.可以新建软件包进行分类(右键新建软件包)(很多东西会帮你重构,从而运行不会失败)。

bf8746ae62de4b97925926bd8772d700.png

2.extends和implements的区别(extends是继承类,implements是继承接口,也就是上下级的关系)

public class Xssfilter implements Filter {
}


以及


public class Xssfilter extends HttpServlet implements Filter {
}

3.创建Xssfilter,放在filter下。

代码步骤:

a09e187b3b464ed59680db5c662e63dd.png

package com.example.filterdemo01.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

@WebFilter("/test")
public class Xssfilter implements Filter {
    @Override
    //中间件开启后就自动运行
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("xss正在过滤");
    }

    @Override
    //doFilter 访问路由触发的方法
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("xss开启过滤");
    }

    @Override
    //中间件关闭后就自动运行
    public void destroy() {
        System.out.println("xss销毁过滤");
    }
}

当有servlet时web.xml就不需要配置了。

b58871e4305249e0a6dc920c7309de96.png

    <filter>
        <filter-name>Xssfilter</filter-name>
        <filter-class>com.example.filterdemo01.filter.Xssfilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>Xssfilter</filter-name>
        <url-pattern>/test</url-pattern>
    </filter-mapping>

运行结果:

没有访问/test就有了语句“xss开启过滤",原因是先通过filter,再到servlet。

访问/test,xss正在过滤。

XSS过滤:

代码:

package com.example.filterdemo01.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 就进行拦截
        // 接受参数值 如果没有攻击payload 就进行放行
        HttpServletRequest request= (HttpServletRequest) servletRequest;
        String code = request.getParameter("code");
        if(!code.contains("<script>")){ //没有攻击payload
            //放行
            filterChain.doFilter(servletRequest,servletResponse);
        }else{
            System.out.println("存在XSS攻击");
            //继续拦截
        }

    }
}

效果:

当运行不了的时候改一下tomcat的端口,改为8888:

AdminFIilter和AdminServlet:

代码:(在filter下创建AdminFIilter)

package com.example.filterdemo01.filter;


import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

@WebFilter("/admin")
public class AdminFileter 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 {

        System.out.println("admin身份检测进行");
        //检测Cookie过滤
        HttpServletRequest request= (HttpServletRequest) servletRequest;
        Cookie[] cookies=request.getCookies();
        //对Cookie进行遍历获取
        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("非管理员访问");
            }
        }

    }
}

 代码:(在servlet下创建Admin)

package com.example.filterdemo01.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("/admin")
public class AdminServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("欢迎进入管理员页面");
    }
}

运行效果:

当只访问http://localhost:8888/FilterDemo01/admin​​​​​​

当修改了cookie再次访问时:

后门内存码植入:

1.使用哥斯拉生成1.jsp:

2.注意:别将其放入WEB-INF中:

3.连接测试:

分析:

点击addFilterShell

点击getALLFilter:

总结:

内存马是写在Filter中:

 后门没有写到Servlet中,常规方法扫描只会扫Servlet,而忘记扫描Filter。

Listener监听器:

参考: JavaWeb监听器_javaweb 监听器-CSDN博客

-监听 ServletContext、HttpSession、ServletRequest 等域对象创建和销毁事件

-监听域对象的属性发生修改的事件
-监听在事件发生前、发生后做一些必要的处理
1、创建监听器
2、监听器内置方法
3、监听器触发流程
@WebListener
<listener>
......
</listener>
4.监听器安全场景:
代码审计中分析执行逻辑触发操作,后门内存马植入等。
​
1.创建:
ListenerDemo01:
2.删除:
3.创建软件包(listener):
可以先复制一下HelloServlet的路径,这样方便创建软件包。
4.在Servlet中写入:

CSession:(生成)

package com.example.listendemo1.Servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;

@WebServlet("/cs")
public class CSession extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Servlet里面创建Session");
        //创建Session
        req.getSession();
    }
}

DSession:(销毁)

package com.example.listendemo1.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("/ds")
public class DSession extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Servlet里面销毁Session");
        //销毁Session
        req.getSession().invalidate();
    }
}

ListeneSession:

package com.example.listendemo1.listener;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

@WebListener
public class ListenSession implements HttpSessionListener {

    @Override
    public void sessionCreated(HttpSessionEvent se) {
        //监听检测有Session创建就会执行这里
        System.out.println("监听器监听到了session创建");
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        //监听检测有Session销毁就会执行这里
        System.out.println("监听器监听到了session销毁");
    }
}

效果图:/cs创建,/ds销毁

本文章由李豆豆喵和番薯小羊卷~共同完成。


http://www.kler.cn/a/445241.html

相关文章:

  • 配置flutter 解决andriod studio报错 no device selected
  • 揭秘语言模型后训练:指令微调、偏好调优与强化学习的深度解析
  • AdminJS - 现代化的 Node.js 管理面板框架详解
  • 【系统架构设计师】真题论文: 论数据分片技术及其应用(包括解题思路和素材)
  • 在THREEJS中加载3dtile模型
  • Mysql索引类型总结
  • 【华为OD-E卷-开心消消乐 100分(python、java、c++、js、c)】
  • 【软件开发】做出技术决策
  • 2024.2 ACM Explainability for Large Language Models: A Survey
  • 基于springboot的银行账目账户管理系统
  • maven项目运行时NoSuchMethodError问题排查记录(依赖冲突解决)
  • 使用yolo v5 识别月球极小撞击坑
  • 卫星综合电子软件系统
  • docling:PDF解析
  • DALL-M:基于大语言模型的上下文感知临床数据增强方法 ,补充
  • Ansible基本用法
  • 14:00面试,14:10就出来了,问的问题过于变态了。。。
  • Visio——导出的PDF文件缺乏嵌入字体的解决办法 / 设置导出的PDF文件添加嵌入字体的方法
  • 【HTML+CSS】深入理解HTML中的<div>标签:布局与样式的基石
  • verge下最节省gas的智能合约写法