java之文件上传代码审计

news2024/12/24 3:19:48

1 文件上传漏洞审计

1.1 漏洞原理介绍

大部分文件上传漏洞的产生是因为Web应用程序未对文件的格式和进行严格过滤,导致用户可上传jsp、php等webshell代码文件,从而被利用。例如在 BBS发布图片 , 在个人网站发布ZIP压缩包, 在办公平台发布DOC文件等 , 只要 Web应用程序允许上传文件, 就有可能存在文件上传漏洞。

1.2 审计策略

  • 文件上传可以搜索以下关键词: upload,write,fileName ,filePath

  • 在查看时,主要判断是否有检查后缀和文件的大小

  • 同时要查看配置文件是否有设置白名单或者黑名单(不推荐黑名单,可能被绕过)

1.3 修复方案

  • 通过后端增加对上传文件后缀格式的验证,验证的手段有两种,分别是白名单校验和黑名单校验

  • 推荐使用白名单校验,绕过的危险小,黑名单无法维护全面,极容导致绕过校验成功上传脚本文件

  • 只允许文件上传到固定目录且设置程序对该目录下只有读写权限,不得具有执行权限

  • 推荐存储文件的服务器和应用服务器相互独立

  • 上传成功的文件不得真实的存储路径回显给前端,但是对于我想下载禁止直接使用完整的路径【为了防止直接暴露真实路径到前端】,应该通过key,到服务端或数据库中找到真实的路径下载即可

  • 必要的时候需要重命名文件名,最合理的一定是后端生成的文件的目录

1.4 审计案例

1.4.1 无任何过滤

服务端脚本语言未对上传的文件进行任何限制和过滤,导致恶意用户上传任意文件。

    <form action="/file/upload01" method="post" enctype="multipart/form-data">
        <input type="file" name="uploadfile" >
        <input type="submit">
    </form>

上传文件的后端处理,基于Spring Boot

package com.ms08067.fileupload.controller;
​
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
​
import java.io.File;
import java.io.IOException;
​
@Controller
@RequestMapping("/file")
public class FileUploadController {
    /**
     * 未对上传文件进行任何安全处理
     * @param file
     * @return
     */
    @PostMapping("/upload01")
    public String uploadFile01(@RequestParam("uploadfile") MultipartFile file) {
        //获取文件名
        String filename = file.getOriginalFilename();
        //文件保存路径
//        String path = "/";
        File outfile = new File("D:\\20230222"+filename);
        try {
            file.transferTo(outfile);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "success";
    }
    }

上述代码未对上传的文件进行任何检测,可以上传任意类型的文件,包括exe文件和木马等。

运行页面如下:

成功上传后

1.4.2 客户端检测

JS对文件后缀名检测绕过

通过前端js检测文件名是否合法没有任何意义,因为任意用户都可以对前端js进行任意修改或者通过burp suite抓包修改上传的文件名。

以下代码限制上传文件的后缀名必须为.jpg和.png

<form action="/file/upload02" method="post"  οnsubmit="return judge()" enctype="multipart/form-data">
    <input type="file" name="uploadfile" id="checkfile" >
    <input type="submit" value="提交">
    <p id="msg"></p>
</form>
<script type="text/javascript">
​
    function judge(){
        var file=document.getElementById("checkfile").value;
        if (file==null||file==""){
            alert("请选择要上传的文件");
            // location.reload(true);
            return false;
        }
        var isnext=false;
        var filetypes=[".jpg",".png"];
        var fileend=file.substring(file.lastIndexOf("."));
        for (var i=0;i<filetypes.length;i++){
            if (filetypes[i]==fileend){
                isnext=true;
                break;
            }
        }
        if (!isnext){
            document.getElementById("msg").innerHTML="文件类型不允许";
​
            // location.reload(true);
            return false;
​
        }else {
            return true;
        }
​
    }
</script>

后端没有进行任何限制,将文件存储在src\main\resources\static\upload下

 import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
​
import java.io.File;
import java.io.IOException;
 /**
     * 前端通过JS进行文件名称限制
     * @param file
     * @return
     */
    @PostMapping("/upload02")
    public String uploadFile02(@RequestParam("uploadfile") MultipartFile file) {
        String filename = file.getOriginalFilename();
        String path = "D:\\20230222";
        File fileDir = new File(path);
        File outfile = new File(fileDir.getAbsolutePath()+File.separator + filename);
        try {
            file.transferTo(outfile);
        }catch (IOException e){
            e.printStackTrace();
        }
​
        return "success";
    }

绕过js检测方法一:修改前端代码,删除js检测部分或者禁用js

绕过js检测方法二:使用代理Burp Suite上传文件;上传符合要求的文件类型,抓包修改文件类型。例

如要上传1.jsp,先将文件名改为1.jpg,上传,抓包,再修改为1.jsp即可。


成功上传

1.4.3 服务端检测绕过

1.4.3.1 服务器端后缀名检测绕过

主要通过黑白名单进行过滤,如果不符合过滤规则,则不允许上传

一般有个专门的 blacklist 文件,里面会包含常见的危险脚本文件后缀名。

1.4.3.2 大小写绕过

以下后端代码,检测上传的文件的后缀名是否符合要求,不允许上

传".jsp",".php",".exe",".dll","vxd","html"结尾的文件,可通过将文件后缀大写进行绕过

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
​
import java.io.File;
import java.io.IOException;
//基于黑名单大小写绕过的文件上传
    @PostMapping("/upload03")
    public String uploadFile03(@RequestParam("uploadfile")MultipartFile file, Model model){
        boolean flag=true;
        String filename = file.getOriginalFilename();
        System.out.println(filename);
       String suffix=filename.substring(filename.lastIndexOf("."));
        String[] blacklist={".jsp",".php",".exe",".dll","vxd","html"};//后缀名黑名单
        for (String s : blacklist) {
            if (suffix.equals(s)){
                flag=false;
                break;
            }
        }
        if (flag){
            String path="D:\\20230222";
            File fileDir = new File(path);
            File outfile = new File(fileDir.getAbsolutePath()+File.separator + filename);
            try {
                file.transferTo(outfile);
                return "success";
            }catch (IOException e){
                e.printStackTrace();
            }
​
        }
        else {
            model.addAttribute("msg","非法文件类型");
        }
        return "index";
    }

通过大小写上传

上述黑名单仅过滤了少数后缀名,可以上传其他后缀类型的恶意文件。

可利用Burp suite截断HTTP请求,利用Intruder模块进行枚举后缀名,寻找黑名单中没有过滤的后缀名。接收HTTP请求,send to intruder,选中变量,在Payloads中加载相应的字典。

1.4.3.3 双写绕过

以下代码判断文件后缀名是否存在黑名单中的字符,若存在则将对应的字符串替换为空

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
​
import java.io.File;
import java.io.IOException;
//基于双写绕过的文件上传(如果后缀名为非法的字符,将替换成空)修复大小写绕过
    @PostMapping("/upload04")
    public String uploadFile04(@RequestParam("uploadfile")MultipartFile file){
        String filename = file.getOriginalFilename();
        System.out.println(filename);
        String preFilename=filename.substring(0,filename.lastIndexOf("."));
        String suffix=filename.substring(filename.lastIndexOf(".")).toLowerCase();
        String[] blacklist={"jsp","php","exe","dll","vxd","html"};//后缀名黑名单
        for (String s : blacklist) {
            if (suffix.indexOf(s)!=-1){
                suffix=suffix.replace(s,"");//后缀存在黑名单字符串,则将字符串替换为空
            }
        }
        String path="D:\\20230222";
        File fileDir = new File(path);
        File outfile = new File(fileDir.getAbsolutePath()+File.separator + preFilename+suffix);
        try {
            file.transferTo(outfile);
            return "success";
        }catch (IOException e){
            e.printStackTrace();
        }
        return "index";
    }

可通过双写后缀名进行绕过,例如上传4.jjspsp文件,过滤掉jsp后,文件名正好是我们想要上传的

1.4.3.4 双后缀名绕过

以下代码,后端判断后缀名使用的是filename.indexOf("."),而不是filename.lastIndexOf(".")

可通过双后缀名绕过检测,例如欲上传1.jsp,可将文件名改为1.jsp.jsp,这样后端获得的后缀名

为.jsp.jsp,可通过检测。

   //文件后缀名双写绕过-未修复大小写绕过
    @PostMapping("/upload05")
    public String uploadFile05(@RequestParam("uploadfile")MultipartFile file,Model model){
        boolean flag=true;
        String filename = file.getOriginalFilename();
        System.out.println(filename);
        String suffix=filename.substring(filename.indexOf("."));
        String[] blacklist={".jsp",".php",".exe",".dll",".vxd",".html"};//后缀名黑名单
        for (String s : blacklist) {
            if (suffix.equals(s)){
                flag=false;
                break;
​
            }
        }
        if (flag){
            String path="D:\\20230222";
            File fileDir = new File(path);
            File outfile = new File(fileDir.getAbsolutePath()+File.separator + filename);
            try {
                file.transferTo(outfile);
                return "success";
            }catch (IOException e){
                e.printStackTrace();
            }
​
        }else {
            model.addAttribute("msg","非法文件类型");
​
        }
        return "index";
​
    }

上传不符合windows文件命名规则的文件名

上述代码可以通过抓包,修改文件名为如下形式:

  • 点绕过1.jsp.

  • 空格绕过1.jsp(空格)

  • 1.jsp:1.jpg

  • 1.jsp::$DATA

1.4.4 白名单检测

在jdk低版本(1.7及以下)中可以使用%00截断。图片木马

1.4.4.1 MIME类型检测绕过

以下代码限制上传文件的MIME类型需为"image/jpeg","image/png"或"image/gif",可通过抓包,

修改Content-Type为合法类型绕过MIME类型检测

 @PostMapping("/upload07")
    public String uploadFile07(@RequestParam("uploadfile")MultipartFile file,Model model){
        boolean flag=false;
        String filename = file.getOriginalFilename();
        String contentType = file.getContentType();
        System.out.println(filename);
        String preFilename=filename.substring(0,filename.lastIndexOf("."));
        String suffix=filename.substring(filename.lastIndexOf(".")).toLowerCase();
        //基于文件头类型进行白名单校验
        String[] whiteList={"image/jpeg","image/png","image/gif"};
        for (String s : whiteList) {
            if (contentType.equals(s)){
                flag=true;
            }
        }
        if (flag){
            String path="D:\\20230222";
            File fileDir = new File(path);
            File outfile = new File(fileDir.getAbsolutePath()+File.separator + filename);
            try {
                file.transferTo(outfile);
                return "success";
            }catch (IOException e){
                e.printStackTrace();
            }
​
        }else {
            model.addAttribute("msg","非法文件类型");
        }
        return "index";
    }

例如上传1.jsp文件,可修改Content-Type值为 image/jpeg

1.4.4.2 文件头检测绕过

根据文件的前面几个字节,即常说的魔术数字进行判断,不同文件类型的开头几个字节不同。

常见文件头:

以下代码,通过检测文件头部分判断上传的文件是否为图片,可利用如下两种方法绕过

package com.ms08067.fileupload.controller;
​
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
​
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
​
@Controller
@RequestMapping("/file1")
public class FileUploadController1 {
    public final static Map<String,String> FileType=new HashMap<String,String>();
    static {
        getAllFileType();//初始化文件类型信息
    }
    @PostMapping("/upload")
    public static String upload(@RequestParam("uploadfile") MultipartFile file, Model model){
        String filename = file.getOriginalFilename();
        boolean flag=false;
        byte[] b=new byte[50];
        try {
            InputStream inputStream = file.getInputStream();
            inputStream.read(b);
            System.out.println(b.toString());
            StringBuilder stringBuilder=new StringBuilder();
            if (b==null ||b.length<0){
                flag=false;
            }
            for (int i = 0; i < b.length; i++) {
                int v=b[i]&0xff;
                String hv=Integer.toHexString(v);//十六进制
                stringBuilder.append(hv);
            }
            System.out.println("stringBuilder"+stringBuilder.toString());
            String fileTypeHex = String.valueOf(stringBuilder.toString());
            Iterator<Map.Entry<String, String>> iterator = FileType.entrySet().iterator();
            while (iterator.hasNext()){//判断文件前几个字节是否为FileType中三种类型之一
                Map.Entry<String, String> next = iterator.next();
                System.out.println(fileTypeHex.toUpperCase(Locale.ROOT));
                if (fileTypeHex.toUpperCase(Locale.ROOT).startsWith(next.getValue())){
                    flag=true;
                }
​
            }
​
            inputStream.close();
        }catch (FileNotFoundException e){
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
​
        }
​
        if (flag){
            String path="D:\\20230222";
            File fileDir = new File(path);
            File outfile = new File(fileDir.getAbsolutePath()+File.separator + filename);
            try {
                file.transferTo(outfile);
                return "success";
            }catch (IOException e){
                e.printStackTrace();
            }
​
        }else {
            model.addAttribute("msg","非法文件类型");
​
        }
        return "index";
​
    }
    private static void getAllFileType(){
        FileType.put("jpeg","FFD8FF");
        FileType.put("png","89504E47");
        FileType.put("gif","47494638");
        FileType.put("jpg","GIF89a");
    }
    }
1.4.4.3 添加合法文件头绕过

通过抓包,添加合法文件头,例如GIF89a(jpg格式文件头)


上传两个注意事项:

(1)编码前空格、编码上边空一行

1.4.4.4 制作图片木马绕过

copy 2.jpg/b+1.jsp 3.jpg,或者使用记事本等软件打开图片,在末尾添加jsp木马数据,将攻击脚本隐藏到图片中。

单纯的图片马并不能直接和蚁剑连接,因为该文件依然是以image格式进行解析,需要结合文件包含漏洞

1.4.4.5 ImageIO判断上传图片文件

通过ImageReader解码file并返回一个BufferedImage对象,如果找不到合适的ImageReader则会返回null,我们可以认为这不是图片文件。

如果能够正常的获取到一张图片的宽高属性,那么该文件一定是图片,因为非图片文件获取不到它的宽高属性的。

但若是在可以正常打开的图片里面加入非法代码或者病毒,那就非常危险了

@Controller
public class UploadImg {
//ImageIO判断上传的文件是否为图片
@PostMapping("/upload")
public static String uploadImg(@RequestParam("uploadfile")MultipartFile file , Model model){
boolean flag=false;
String filename = file.getOriginalFilename();
String suffix = filename.substring(filename.lastIndexOf("."));
String path="src\\main\\resources\\static\\upload";
File fileDir = new File(path);
File outfile = new File(fileDir.getAbsolutePath()+File.separator + filename);
String[] whiteList={".jpg",".png"};
for (String s : whiteList) {
if (suffix.toLowerCase(Locale.ROOT).equals(s)){
flag=true;
break;
}
}
File tmpFile=null;
if (flag){
tmpFile = new File(System.getProperty("java.io.tmpdir"), filename);
​
try{
file.transferTo(tmpFile);
BufferedImage read = ImageIO.read(tmpFile);
read.getWidth();
read.getHeight();
}catch (Exception e){
e.printStackTrace();
flag=false;
}finally {
if (flag){
try {
FileCopyUtils.copy(new FileInputStream(tmpFile),
Files.newOutputStream(Paths.get(path,filename), StandardOpenOption.CREATE_NEW));
 tmpFile.delete();
return "success";
}catch (FileNotFoundException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
}else {
model.addAttribute("msg","请上传图片文件!");
}
}
}else {
model.addAttribute("msg","文件后缀名不符合要求");
}
return "index";
}
}

1.5 文件上传漏洞总结

文件上传漏洞的原因:

  • 未对文件做任何过滤,可上传任意文件类型,如木马、可执行文件等;

  • 在js端检验文件后缀,可通过删除js或禁用js或抓包修改文件后缀等方法绕过;

  • 后端后缀过滤使用黑名单,过滤不全,可通过使用未过滤的后缀名、大小写变换、双写后缀名、双后缀名、文件名结尾加”.“或空格、%00截断等方式绕过;

  • 后端判断文件类型,只判断Content-type,可通过抓包修改Content-type字段的值进行绕过;

  • 后端检查文件内容仅检查文件头内容,可通过抓包添加合法文件头,或使用其他工具添加合法文件头进行绕过。

1.6 文件上传漏洞修复

  • 服务器端的检查最好使用白名单过滤的方法,黑名单极不可靠

  • 使用随机数**改写文件名和文件路径**。文件上传如果要执行代码,需要用户能够访问到这个文件。应用了随机数改写了文件名和路径,可防止大小写绕过、双后缀、多后缀等手段,将极大地增加攻击的成本;

  • 文件上传目录设置为不可执行,只要web容器无法解析该目录下面的文件,即使攻击者上传了脚本文件,服务器本身也不会受到影响。

  • 使用安全设备防御,恶意文件千变万化,隐藏手法也不断推陈出新,对普通的系统管理员来说可以通过部署安全设备来帮助防御。

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

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

相关文章

H3C综合实验

实验拓扑 实验要求 1、按照图示配置IP地址 2、sw1和sw2之间的直连链路配置链路聚合 3、 公司内部业务网段为VLAN10和VLAN20; VLAN 10是市场部&#xff0c;vlan20是技术部&#xff0c;要求对VLAN进行命名以便识别&#xff1b;PC1属于vlan10&#xff0c;PC2属于vlan20&#xf…

JavaScript事件传播_冒泡和捕获

事件传播分为冒泡&#xff08;Bubbling&#xff09;和捕获&#xff08;Capturing&#xff09;两种模式。 冒泡 ● 冒泡是指当一个元素上的事件被触发时&#xff0c;该事件会从最内层的元素开始向外层元素逐层传播&#xff0c;直到传播到最外层的祖先元素。 ● 举例来说&#…

vivado WIRE

WIRE是用于在Xilinx部件上路由连接或网络的设备对象。一根电线 是单个瓦片内部的一条互连金属。PIP、系紧装置和 SITE_PINs。 提示&#xff1a;WIRE对象不应与设计的Verilog文件中的WIRE实体混淆。那些 电线在设计中与网络有关&#xff0c;而不是与定义的设备的路由资源有关 WI…

Modbus协议转Profibus协议网关模块连PLC与激光发射器通讯

一、概述 在PLC控制系统中&#xff0c;从站设备通常以Modbus协议&#xff0c;ModbusTCP协议&#xff0c;Profinet协议&#xff0c;Profibus协议&#xff0c;Profibus DP协议&#xff0c;EtherCAT协议&#xff0c;EtherNET协议等。本文将重点探讨PLC连接Modbus协议转Profibus协…

芯片验证分享系列总结及PPT分享

大家好&#xff0c;我是谷公子。花了将近两个月时间&#xff0c;《芯片验证分享》这一系列视频分享已经更新完了&#xff0c;内容涵盖了名词解释、芯片验证原则、激励开发、代码审查以及芯片调试。这一系列视频主要侧重于芯片验证理论的分享&#xff0c;希望可以帮助大家构建芯…

PHP蜜语翻译器在线文字转码解码源码

源码介绍 PHP蜜语翻译器在线文字转码解码源码 文字加密通话、一键转换、蜜语密码 无需数据库,可以将文字、字母、数字、代码、表情、标点符号等内容转换成新的文字形式&#xff0c;通过简单的文字以不同的排列顺序来表达不同的内容&#xff01;支持在线加密解密 有多种加密展示…

亚马逊卖家注册业务类型怎么选?VC账号能申请?

在亚马逊卖家注册时&#xff0c;业务类型的选择是非常重要的&#xff0c;因为它将直接影响您的销售策略、费用结构以及您在平台上的权限。目前&#xff0c;亚马逊主要的卖家业务类型包括专业卖家和个人卖家&#xff0c;而VC&#xff08;Vendor Central&#xff09;账号和VE&…

AI创作音乐引发的深思

在最近一个月中&#xff0c;音乐大模型的迅速崛起让素人生产音乐的门槛降到了最低。这一变革引发了关于AI能否彻底颠覆音乐行业的广泛讨论。在初期的兴奋过后&#xff0c;人们开始更加理性地审视AI在音乐领域的应用&#xff0c;从版权归属、原创性、创作质量、道德层面以及法律…

飞睿智能UWB定位手环芯片模块,高速无线传输超宽带uwb定位技术,创新手环科技潮流

在数字化时代的浪潮中&#xff0c;我们每天都在享受着科技带来的便捷和惊喜。其中&#xff0c;定位技术作为现代科技的重要分支&#xff0c;已经深入我们生活的每一个角落。从智能手机导航到共享单车&#xff0c;从无人驾驶到物流追踪&#xff0c;定位技术都在默默发挥着它的作…

2024广东省职业技能大赛云计算赛项实战——Ansible部署Zabbix

Ansible部署Zabbix 前言 今年的比赛考了一道Ansible部署Zabbix的题目&#xff0c;要求就是用两台centos7.5的云主机&#xff0c;一台叫ansible&#xff0c;一台叫node&#xff0c;使用对应的软件包&#xff0c;通过ansible节点控制node节点安装zabbix服务。这道题还是算比较简…

缓存雪崩(主从复制、哨兵模式(脑裂)、分片集群)

缓存雪崩&#xff1a; 在同一时段大量的缓存key同时失效或者Redis服务宕机&#xff0c;导致大量请求到达数据库&#xff0c;带来巨大压力。 方法一&#xff1a; 给不同key的TTL添加随机值&#xff0c;以此避免同一时间大量key失效。&#xff08;用于解决同一时间大量key过期&…

环境配置04:Pytorch下载安装

说明&#xff1a; 显存大于4G的建议使用GPU版本的pytorch&#xff0c;低于4G建议使用CPU版本pytorch&#xff0c;直接使用命令安装对应版本即可 GPU版本的pytorch的使用需要显卡支持&#xff0c;需要先安装CUDA&#xff0c;即需要完成以下安装 1.查看已安装CUDA版本 GPU对应…

Zabbix 监控 Kubernetes 集群

Zabbix 监控 Kubernetes 集群 Zabbix作为一个成熟且功能强大的监控系统&#xff0c;被许多企业广泛采用。它能够对各种IT基础设施进行全面的监控&#xff0c;包括服务器、网络设备、应用程序等。而将Zabbix与Kubernetes结合&#xff0c;可以实现对Kubernetes集群的全面监控&am…

qt 简单实验 画一个等边三角形

1.概要 2.代码 2.1 widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPainter>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr)…

3.3 Ubuntu24使用kubeadm部署高可用K8S集群

Ubuntu24使用kubeadm部署高可用K8S集群 使用kubeadm部署一个k8s集群&#xff0c;3个master1个worker节点。 1. 环境信息 操作系统&#xff1a;ubuntu24.04内存: 2GBCPU: 2网络: 能够互访&#xff0c;能够访问互联网 hostnameip备注k8s-master1192.168.0.51master1k8s-maste…

可视化数据科学平台在信贷领域应用系列七:自动机器学习(下篇)

在当今金融科技迅速发展的时代&#xff0c;自动机器学习&#xff08;AutoML&#xff09;逐步成为了信贷风控领域的重要工具。随着大数据和人工智能技术的进步以及信贷风险环境的快速变化&#xff0c;传统人工建模模式的时效性已经难以应对复杂多变的挑战。自动机器学习框架将数…

【linux】操作系统使用wget下载网络文件,内核tcpv4部分运行日志

打印日志代码及运行日志(多余日志被删除了些)&#xff1a; 登录 - Gitee.comhttps://gitee.com/r77683962/linux-6.9.0/commit/55a53caa06c1472398fac30113c9731cb9e3b482 测试步骤和手段&#xff1a; 1、清空 kern.log&#xff1b; 2、使用wget 下载linux-6.9.tar.gz&…

芯片方案SIC88336血氧仪方案

血氧仪利用红外线光源照射患者手指末梢&#xff0c;在经过血液的时候&#xff0c;光线会被血液中的氧合血红蛋白和脱氧血红蛋白吸收。传感器感知到吸收的光强度变化&#xff0c;并将其转化为电信号发送给主机。主机通过处理这些信号&#xff0c;计算出血氧饱和度值&#xff0c;…

数字贸易变革:新模式、新机遇、新发展

树莓集团通过积极探索数字贸易的新模式和新机遇&#xff0c;不断推动数字贸易的发展和创新。未来&#xff0c;树莓集团将继续秉承开放、合作、共赢的理念&#xff0c;与全球优秀的企业和合作伙伴共同探索新的发展路径&#xff0c;为实现数字贸易的升级贡献一份力量。 一、数字贸…