java代码审计2之servlet学习(1)

文章目录

  • 1、基本知识
      • 1.1、Servlet
      • 1.2、番外之jsp后门清理注意
  • 2、路由相关
      • 2.1、注解
      • 2.2、web.xml
      • 2.3、tomcat默认的server
  • 3、servlet生命周期
      • 3.1、简述过程
      • 3.2、测试init、service、destroy
      • 3.3、初始化之注解
      • 3.4、初始化之web.xml
  • 4、servlet请求与响应
      • 4.1、get传参
      • 4.2、POST传参

1、基本知识

1.1、Servlet

1、Servlet 是什么?

Servlet(Server Applet)是Java Servlet的简称,称为⼩服务程序或服务连接器,
	
⽤Java编写的服务器端程序,具有独⽴于平台和协议的特性, 
	
是运⾏在 Web 服务器或应⽤服务器上的程序。

2、Servlet 的作⽤

它是作为来⾃ Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应⽤程序之间的中间层。

主要功能在于收集来⾃⽹⻚表单的⽤户输⼊,交互式地浏览和⽣成数据,还可以⽣成动态Web内容。

3、个人的理解

前端提交数据		--》		server		--》具体的代码逻辑

1.2、番外之jsp后门清理注意

新建一个jsp文件,执行代码后,访问这个jsp文件

这里直接复制index.jsp

java代码审计2之servlet学习(1)_第1张图片

运行程序,会在“Using CATALINA_BASE”文件下生成两个对应的文件(java/class)

具体路径为,

%Using CATALINA_BASE%\work\Catalina\localhost\ROOT\org\apache\jsp

java代码审计2之servlet学习(1)_第2张图片

假设这个test.jsp是后门的话,攻击者访问下这个test.jsp文件,就会生成(java/class)

java代码审计2之servlet学习(1)_第3张图片

最开始以为需要以下三步才会清理干净,

	删除test.jsp后,同时删除上边两个生成的对应文件,最后重启容器

经过测试发现,只需要删除test.jsp之后,重启tomcat容器即可
	
	生成的(java/class)会被自动清理

2、路由相关

2.1、注解

Servlet3.0⾥引⼊了注解;注解@WebServlet⽤来定义Web应⽤程序中的⼀个Servlet。  

@WebServlet⽤来注册Servlet;name是Servlet的名字;value是通过请求的url地址

以下代码的意思是,通过访问/hello-servlet访问HelloServlet

java代码审计2之servlet学习(1)_第4张图片

这个value的值可以任意,比如,下边通过

"/hello", "/aaa.php"来访问这个文件,

java代码审计2之servlet学习(1)_第5张图片

2.2、web.xml

除了上边的注解方式,还可以通过配置web.xml来设置路由

具体的配置在src/main/webapp/WEB-INF/web.xml
   
    <servlet>
        <servlet-name>helloServlet</servlet-name>
        <servlet-class>com.example.demo.HelloServlet</servlet-class>
    </servlet>
      
    <servlet-mapping>
        <servlet-name>helloServlet</servlet-name>
        <url-pattern>/hi</url-pattern>
    </servlet-mapping>


      server-name是设计一个联系的纽带
      server-class是具体指向哪个class文件
    	url-pattern是直接对应的路由
      

java代码审计2之servlet学习(1)_第6张图片

当注解有web.xml的文件冲突时,以web.xml为准;注解会直接失效

即当注解也加了路由,web.xml也加了路由的情况,路由路径还不一样

java代码审计2之servlet学习(1)_第7张图片

2.3、tomcat默认的server

这里一个问题是以下这个文件既没有找到注解,也没有web.xml配置,但是可以直接访问

src/main/webapp/index.jsp

java代码审计2之servlet学习(1)_第8张图片

直接的记录是,webapp目录下的文件可以直接访问,但是不明白为什么,

其根本原因是,tomcat默认自带的server解析的,

apache-tomcat-9.0.68\conf\web.xml

这个文件内有一些server与servlet-mapping的映射

3、servlet生命周期

3.1、简述过程

三个步骤即:初始化------>处理请求------>销毁 
创建Servlet对象后
  
  		---------->初始化(调⽤ init () ⽅法)
  	
  		--------->处理/响应客户端的请求(调⽤ service() ⽅法)
  		
  		--------->销毁(调⽤ destroy() ⽅法,

  最后由 JVM 的垃圾回收器进⾏垃圾回 收)  

init方法,

只会在第⼀次创建 Servlet 时被调⽤,在后续每次⽤户请求时不再调⽤

init可以初始化一些变量,比如mysql的链接信息等

service() ⽅法

每次服务器接收到⼀个 Servlet 请求时,都会调用该方法

destroy() ⽅法

在⻓时间没有被调⽤或者是服务器关闭时,会调⽤destroy()⽅法来销毁Servlet对象


destroy() ⽅法只会被调⽤⼀次,在 Servlet ⽣命周期结束时被调⽤。


destroy() ⽅法可以让Servlet 关闭数据库连接、停⽌后台线程、

把 Cookie 列表或点击计数器写⼊到磁盘,并执⾏其他类似的清理活动。 

在调⽤ destroy() ⽅法之后,servlet 对象被标记为垃圾回收。  

3.2、测试init、service、destroy

新建一个java文件,名称任意,

java代码审计2之servlet学习(1)_第9张图片

将新建的类继承Servlet类接口,

将鼠标放到放到“class”或者“test”上,将下边的方法都实现,

java代码审计2之servlet学习(1)_第10张图片

现在将上边描述的三个方法都增加一下输出,

java代码审计2之servlet学习(1)_第11张图片
增加注解,
java代码审计2之servlet学习(1)_第12张图片

启动项目,

此时没有访问test,所以下边没有任何输出,

java代码审计2之servlet学习(1)_第13张图片

访问test路由,

init方法和service方法被执行,

java代码审计2之servlet学习(1)_第14张图片

多次访问/刷新test路由,init方法不在执行,server则访访问一次,执行一次

java代码审计2之servlet学习(1)_第15张图片

当我们手动终止项目的时候,

destroy方法被执行,

java代码审计2之servlet学习(1)_第16张图片

3.3、初始化之注解

      	@WebServlet(value = "/test",initParams={@WebInitParam(name="username",value="xbb"),@WebInitParam(name="age",value="20")})

		String username = servletConfig.getInitParameter("username");
        int age = Integer.parseInt(servletConfig.getInitParameter("age"));
        System.out.println("username: "+username+"age: "+age);

java代码审计2之servlet学习(1)_第17张图片

3.4、初始化之web.xml

上边是通过注解来初始化,下边通过web.xml
    <servlet>
        <servlet-name>test</servlet-name>
        <servlet-class>com.example.demo.test</servlet-class>
        <init-param>
            <param-name>username</param-name>
            <param-value>xbb</param-value>
        </init-param>
        <init-param>
            <param-name>age</param-name>
            <param-value>18</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>test</servlet-name>
        <url-pattern>/test11</url-pattern>
    </servlet-mapping>

java代码审计2之servlet学习(1)_第18张图片

值得一提的是,假设通过注解的方法也同时存在时,

这两个路由会同时生效,

在上边测试,没有初始化参数的时候,当web.xml与注解同时出现的话,注解会失效,

但是当都存在初始化参数的时候,两个都生效

java代码审计2之servlet学习(1)_第19张图片
但是假设当注解和web.xml声明的路由相同时,会直接报错,
java代码审计2之servlet学习(1)_第20张图片

4、servlet请求与响应

先看下最初的,在init内定义了一个变量,

doget进行输出,

java代码审计2之servlet学习(1)_第21张图片

4.1、get传参

index.jsp

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
    <title>JSP - Hello World</title>
</head>
<body>
<h1><%= "Hello World!" %>
</h1>
<br/>
<a href="aaa.php?username=xbb&age=20">get传输参数</a><br>

<%--<form action="/aaa.php" method="post">--%>
<%--    账号:<input name="username" type="text"><br>--%>
<%--    年龄:<input name="age" type="text"><br>--%>
<%--    兴趣:--%>
<%--    <input type="checkbox" name="hobby" value="song">唱--%>
<%--    <input type="checkbox" name="hobby" value="jump">跳--%>
<%--    <input type="checkbox" name="hobby" value="rap">rap--%>
<%--    <input type="submit" value="提交">--%>
<%--</form>--%>

</body>
</html>

HelloServlet

package com.example.demo;

import java.io.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;

@WebServlet(name = "helloServlet", value ={"/hello", "/aaa.php"})// "/hello-servlet",)
public class HelloServlet extends HttpServlet {
    private String message;

    public void init() {
        message = "Hello World!";
    }





  	//重点
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setCharacterEncoding("utf-8"); //如果有中乱码可以设置接收编码utf-8

        String username = request.getParameter("username");
        int age = Integer.parseInt(request.getParameter("age"));
        System.out.println(String.format("前端传输过来的参数 username = %s age = %s",username,age));


        response.setContentType("text/html");
        // Hello
        PrintWriter out = response.getWriter();
        out.println("");
        out.println("

传输完成

"
); out.println(""); } public void destroy() { } }

测试访问,
java代码审计2之servlet学习(1)_第22张图片
点击后,
java代码审计2之servlet学习(1)_第23张图片

4.2、POST传参

index.jsp

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
    <title>JSP - Hello World</title>
</head>
<body>
<h1><%= "Hello World!" %>
</h1>
<br/>
<%--<a href="aaa.php?username=xbb&age=20">get传输参数</a><br>--%>

<form action="/aaa.php" method="post">
    账号:<input name="username" type="text"><br>
    年龄:<input name="age" type="text"><br>
    兴趣:
    <input type="checkbox" name="hobby" value="song"><input type="checkbox" name="hobby" value="jump"><input type="checkbox" name="hobby" value="rap">rap
    <input type="submit" value="提交">
</form>

</body>
</html>

HelloServlet

package com.example.demo;

import java.io.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;

@WebServlet(name = "helloServlet", value ={"/hello", "/aaa.php"})// "/hello-servlet",)
public class HelloServlet extends HttpServlet {
    private String message;

    public void init() {
        message = "Hello World!";
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setCharacterEncoding("utf-8"); //如果有中乱码可以设置接收编码utf-8

        String username = request.getParameter("username");
        int age = Integer.parseInt(request.getParameter("age"));
        System.out.println(String.format("前端传输过来的参数 username = %s age = %s",username,age));

        response.setContentType("text/html");
        // Hello
        PrintWriter out = response.getWriter();
        out.println("");
        out.println("

传输完成

"
); out.println(""); } //关注点 public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { response.setCharacterEncoding("utf-8"); //如果有中乱码可以设置接收编码utf-8 String username = request.getParameter("username"); int age = Integer.parseInt(request.getParameter("age")); System.out.println(String.format("前端传输过来的参数 username = %s age = %s",username,age)); //接受参数集合 String[] hobbys = request.getParameterValues("hobby"); for (String s : hobbys) { System.out.println(s); } response.setContentType("text/html"); // Hello PrintWriter out = response.getWriter(); out.println(""); out.println("

post请求完成

"
); out.println(""); } public void destroy() { } }

访问首页,
java代码审计2之servlet学习(1)_第24张图片
提交信息,
java代码审计2之servlet学习(1)_第25张图片

你可能感兴趣的:(代码审计,java,servlet,学习)