首页 > 编程语言 >java基础漏洞学习----文件操作漏洞

java基础漏洞学习----文件操作漏洞

时间:2023-10-20 23:47:49浏览次数:32  
标签:文件 java String servlet ---- 漏洞 import 上传 response

java基础漏洞学习----文件操作漏洞

前置基础知识

https://www.cnblogs.com/thebeastofwar/p/17760812.html

文件上传漏洞

文件上传的方式

1.通过文件流
index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>文件上传</title>
</head>
<body>
<form action="uploadFile1" method="post" enctype="multipart/form-data">
    <input type="file" name="file" /><br/>
    <input type="submit" value="上传" />
</form>
</body>
</html>

UploadFileServlet1.java

package com.example.servletdemo;//根据自己的项目名称更改

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

@WebServlet("/uploadFile1")
@MultipartConfig(fileSizeThreshold = 1024 * 1024 * 2, // 2MB
        maxFileSize = 1024 * 1024 * 10, // 10MB
        maxRequestSize = 1024 * 1024 * 50) // 50MB
public class UploadFileServlet1 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");

        String savePath = "C:/uploads"; // 上传文件保存的目录
        File fileSaveDir = new File(savePath);
        if (!fileSaveDir.exists()) {
            fileSaveDir.mkdirs();
        }

        for (Part part : request.getParts()) {
            String fileName = extractFileName(part);
            fileName = new String(fileName.getBytes("ISO-8859-1"), "UTF-8");
            InputStream inputStream = part.getInputStream();
            OutputStream outputStream = new FileOutputStream(savePath + File.separator + fileName);
            byte[] buffer = new byte[1024];
            int length;
            while ((length = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, length);
            }
            outputStream.close();
            inputStream.close();
        }

        response.getWriter().println("文件上传成功!");
    }

    private String extractFileName(Part part) {
        String contentDisposition = part.getHeader("content-disposition");
        String[] items = contentDisposition.split(";");
        for (String item : items) {
            if (item.trim().startsWith("filename")) {
                return item.substring(item.indexOf("=") + 2, item.length() - 1);
            }
        }
        return "";
    }
}

2.通过ServletFileUpload
改maven源
在setting里搜索maven

然后在那个目录中新建一个settings.xml

内容,然后点击override

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                          https://maven.apache.org/xsd/settings-1.0.0.xsd">
      
      <mirrors>
    	<mirror>  
      		<id>huaweimaven</id>  
      		<name>huaweimaven</name>  
      		<url>https://repo.huaweicloud.com/repository/maven/</url>  
      		<mirrorOf>central</mirrorOf>          
    	</mirror>  
      </mirrors>
</settings>

然后再pom.xml中alt+insert快捷键添加commons-io和commons-fileupload依赖

主代码

package com.example.servletdemo;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.List;

@WebServlet("/uploadFile2")
public class UploadFileServlet2 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");

        // 检查是否为文件上传请求
        boolean isMultipart = ServletFileUpload.isMultipartContent(request);
        if (!isMultipart) {
            response.getWriter().println("请选择文件");
            return;
        }

        // 创建文件上传处理工厂
        DiskFileItemFactory factory = new DiskFileItemFactory();

        // 设置内存缓冲区大小,超过大小的文件将被保存到临时文件目录
        factory.setSizeThreshold(1024 * 1024); // 1MB

        // 设置临时文件目录
        File tempDir = new File("C:/temp");
        factory.setRepository(tempDir);

        // 创建文件上传处理器
        ServletFileUpload upload = new ServletFileUpload(factory);

        // 设置请求的最大文件大小
        upload.setSizeMax(1024 * 1024 * 10); // 10MB

        try {
            // 解析文件上传请求
            List<FileItem> items = upload.parseRequest(request);

            for (FileItem item : items) {
                // 检查是否为普通表单字段
                if (item.isFormField()) {
                    // 处理普通表单字段
                    String fieldName = item.getFieldName();
                    String fieldValue = item.getString("UTF-8");
                    // TODO: 处理普通表单字段的值
                } else {
                    // 处理文件字段
                    String fieldName = item.getFieldName();
                    String fileName = item.getName();
                    // TODO: 处理文件字段的值
                    File uploadedFile = new File("C:/uploads/" + fileName);
                    item.write(uploadedFile);
                }
            }

            response.getWriter().println("文件上传成功!");
        } catch (FileUploadException e) {
            e.printStackTrace();
            response.getWriter().println("文件上传失败!");
        } catch (Exception e) {
            e.printStackTrace();
            response.getWriter().println("文件上传失败!");
        }
    }
}

3.通过MultipartFile(失败,不知为什么总报404)
在pom.xml中添加Sprintboot MVC相关依赖

        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <version>2.6.3</version>
            </dependency>
        </dependencies>

主代码

package com.example.servletdemo;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;

public class UploadFileServlet3 {

    @PostMapping("/uploadFile3")
    public String uploadFile(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            return "请选择文件";
        }

        String fileName = file.getOriginalFilename();
        String filePath = "C:/uploads/";

        try {
            File dest = new File(filePath + fileName);
            file.transferTo(dest);
            return "文件上传成功";
        } catch (IOException e) {
            e.printStackTrace();
            return "文件上传失败";
        }
    }
}

常见java的文件上传漏洞的代码

1.filename.indexof与filename.lastIndexof
shell.png.jsp
如果是filename.indexof获取的就是.png.jsp(即从第一个点获取)
如果是filename.lastIndexof获取的就是.jsp(即从最后一个点获取)
上传webshell测试代码,上传helloworld.png.jsp和shell.png.jsp
index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>文件上传</title>
</head>
<body>
<form action="uploadFile4" method="post" enctype="multipart/form-data">
    <input type="file" name="file" /><br/>
    <input type="submit" value="上传" />
</form>
</body>
</html>

主代码

package com.example.servletdemo;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.List;

@WebServlet("/uploadFile4")
public class UploadFileServlet4 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");

        // 检查是否为文件上传请求
        boolean isMultipart = ServletFileUpload.isMultipartContent(request);
        if (!isMultipart) {
            response.getWriter().println("请选择文件");
            return;
        }

        // 创建文件上传处理工厂
        DiskFileItemFactory factory = new DiskFileItemFactory();

        // 设置内存缓冲区大小,超过大小的文件将被保存到临时文件目录
        factory.setSizeThreshold(1024 * 1024); // 1MB

        // 设置临时文件目录
        File tempDir = new File("C:/temp");
        factory.setRepository(tempDir);

        // 创建文件上传处理器
        ServletFileUpload upload = new ServletFileUpload(factory);

        // 设置请求的最大文件大小
        upload.setSizeMax(1024 * 1024 * 10); // 10MB

        try {
            // 解析文件上传请求
            List<FileItem> items = upload.parseRequest(request);

            for (FileItem item : items) {
                // 检查是否为普通表单字段
                if (item.isFormField()) {
                    // 处理普通表单字段
                    String fieldName = item.getFieldName();
                    String fieldValue = item.getString("UTF-8");
                    // TODO: 处理普通表单字段的值
                } else {
                    // 处理文件字段
                    String fieldName = item.getFieldName();
                    String fileName = item.getName();
                    // 获取文件后缀
                    String fileExtension = fileName.substring(fileName.indexOf(".") + 1);//安全做法 fileName.lastIndexof(".")+1

                    /*
                    // 判断后缀是否属于指定的白名单
                    String[] whiteExtensions = {"png", "jpg", "gif"};
                    boolean isValidExtension = false;
                    for (String extension : whiteExtensions) {
                        if (fileExtension.equalsIgnoreCase(extension)) {
                            isValidExtension = true;
                            break;
                        }
                    }
                    if (!isValidExtension) {
                        response.getWriter().println("文件格式不支持(白名单)");
                        return;
                    }
                    */


                    //判断是否属于黑名单
                    String[] blackExtensions = {"jsp","jspx"};
                    for (String extension : blackExtensions) {
                        if (fileExtension.equalsIgnoreCase(extension)) {
                            response.getWriter().println("文件格式不支持(黑名单)");
                            return;
                        }
                    }


                        // TODO: 处理文件字段的值
                        File uploadedFile = new File(getServletContext().getRealPath("/") + "uploads/" + fileName);
                        item.write(uploadedFile);

                       //重定向到上传文件的位置 这样上传jsp文件就能解析了
                       String contextPath = request.getContextPath();
                       String jspPath = contextPath + "/uploads/" + fileName;
                       response.sendRedirect(jspPath);
                    }

                }
            response.getWriter().println("文件上传成功!");
        } catch (FileUploadException e) {
            e.printStackTrace();
            response.getWriter().println("文件上传失败!");
        } catch (Exception e) {
            e.printStackTrace();
            response.getWriter().println("文件上传失败!");
        }
    }
}


然后上传哥斯拉生成的jsp木马,哥斯拉连接,初始目录不是上传webshell的目录,而是tomcat的bin目录

2.前端校验
index2.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>文件上传</title>
    <script>
        function checkFileType() {
            var fileInput = document.getElementById("file");
            var file = fileInput.files[0];
            var fileType = file.type;
            var allowedTypes = ["image/png", "image/jpeg", "image/gif"];
            
            if (!allowedTypes.includes(fileType)) {
                alert("请选择图片文件(png, jpg, gif)");
                return false;
            }
            
            return true;
        }
    </script>
</head>
<body>
    <form action="uploadFile4" method="post" enctype="multipart/form-data" onsubmit="return checkFileType()">
        <input type="file" name="file" id="file" /><br/>
        <input type="submit" value="上传" />
    </form>
</body>
</html>

上传图片马然后修改文件后缀就可以了

3.MIME检测

package com.example.servletdemo;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.List;

@WebServlet("/uploadFile5")
public class UploadFileServlet5 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");

        // 检查是否为文件上传请求
        boolean isMultipart = ServletFileUpload.isMultipartContent(request);
        if (!isMultipart) {
            response.getWriter().println("请选择文件");
            return;
        }

        // 创建文件上传处理工厂
        DiskFileItemFactory factory = new DiskFileItemFactory();

        // 设置内存缓冲区大小,超过大小的文件将被保存到临时文件目录
        factory.setSizeThreshold(1024 * 1024); // 1MB

        // 设置临时文件目录
        File tempDir = new File("C:/temp");
        factory.setRepository(tempDir);

        // 创建文件上传处理器
        ServletFileUpload upload = new ServletFileUpload(factory);

        // 设置请求的最大文件大小
        upload.setSizeMax(1024 * 1024 * 10); // 10MB

        try {
            // 解析文件上传请求
            List<FileItem> items = upload.parseRequest(request);

            for (FileItem item : items) {
                // 检查是否为普通表单字段
                if (item.isFormField()) {
                    // 处理普通表单字段
                    String fieldName = item.getFieldName();
                    String fieldValue = item.getString("UTF-8");
                    // TODO: 处理普通表单字段的值
                } else {
                    // 处理文件字段
                    String fieldName = item.getFieldName();
                    String fileName = item.getName();
                    // 获取文件后缀
                    String fileExtension = fileName.substring(fileName.indexOf(".") + 1);//安全做法 fileName.lastIndexof(".")+1

                    //判断文件类型
                    String contentType = item.getContentType();
                    if (contentType.equals("image/png") || contentType.equals("image/jpeg") || contentType.equals("image/gif") || contentType.equals("application/pdf")) {

                        // TODO: 处理文件字段的值
                        File uploadedFile = new File(getServletContext().getRealPath("/") + "uploads/" + fileName);
                        item.write(uploadedFile);

                        //重定向到上传文件的位置 这样上传jsp文件就能解析了
                        String contextPath = request.getContextPath();
                        String jspPath = contextPath + "/uploads/" + fileName;
                        response.sendRedirect(jspPath);

                        response.getWriter().println("文件上传成功!");
                    }
                    else
                    {
                        response.getWriter().println("文件格式不支持(MIME)");
                    }
                }

            }

        } catch (FileUploadException e) {
            e.printStackTrace();
            response.getWriter().println("文件上传失败!");
        } catch (Exception e) {
            e.printStackTrace();
            response.getWriter().println("文件上传失败!");
        }
    }
}

Content-Type修改为image/png等白名单就可以了
4.头部检测
5.内容检测(JSP免杀)
检测常见恶意代码Runtime.getRuntime().exec

代码审计技巧

1.搜索org.apache.commons.fileupload java.ioFile
2.搜索.indexOf(
3.搜索MultipartFile,RequestMethod,MultipartHttpServletRequest,CommonsMutipartResolver等

目录遍历漏洞(任意文件读取&下载&删除)

package com.example.servletdemo;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FileContentServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String filename = request.getParameter("filename"); // 获取GET参数中的文件名
        String filePath = System.getProperty("user.dir") + "/" + filename; // 拼接当前工作目录和文件名

        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");

        PrintWriter out = response.getWriter();

        try {
            FileReader fileReader = new FileReader(filePath);
            BufferedReader bufferedReader = new BufferedReader(fileReader);

            String line;
            while ((line = bufferedReader.readLine()) != null) {
                out.println(line);
            }

            bufferedReader.close();
        } catch (IOException e) {
            e.printStackTrace();
            out.println("Error: " + e.getMessage());
        }
    }
}

然后再web.xml中添加

    <servlet>
        <servlet-name>FileContentServlet</servlet-name>
        <servlet-class>com.example.servletdemo.FileContentServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>FileContentServlet</servlet-name>
        <url-pattern>/file</url-pattern>
    </servlet-mapping>


查看源码

zip 自解压

zip解压后的文件为恶意文件

package com.example.servletdemo;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

@WebServlet("/uploadFile6")
@MultipartConfig
public class UploadFileServlet6 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");

        String uploadPath = getServletContext().getRealPath("/") + "uploads"; // 获取项目根目录并指定上传文件保存的目录

        // 创建上传文件保存的目录(如果不存在)
        File uploadDir = new File(uploadPath);
        if (!uploadDir.exists()) {
            uploadDir.mkdirs();
        }

        // 获取上传的文件
        Part filePart = request.getPart("file");
        String fileName = getFileName(filePart);

        // 保存上传的文件到指定目录
        String filePath = uploadPath + File.separator + fileName;
        try (InputStream inputStream = filePart.getInputStream();
             FileOutputStream outputStream = new FileOutputStream(filePath)) {
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
        }

        // 解压上传的zip文件
        String unzipPath = getServletContext().getRealPath("/") + "unzips"; // 获取项目根目录并指定解压目录

        // 创建解压目录(如果不存在)
        File unzipDir = new File(unzipPath);
        if (!unzipDir.exists()) {
            unzipDir.mkdirs();
        }

        unzip(filePath, unzipPath);

        // 检查解压后的文件数量 如果数量为1 则跳转到解压文件位置 这样上传shell就可以解析了
        File[] unzippedFiles = unzipDir.listFiles();
        if (unzippedFiles != null && unzippedFiles.length == 1 && unzippedFiles[0].isFile()) {
            String contextPath = request.getContextPath();
            String jspPath = contextPath + "/unzips/" + unzippedFiles[0].getName();
            response.sendRedirect(jspPath);
        } else {
            response.getWriter().println("文件上传和解压成功!");
        }
    }

    // 获取上传文件的名称
    private String getFileName(Part part) {
        String contentDisposition = part.getHeader("content-disposition");
        String[] elements = contentDisposition.split(";");
        for (String element : elements) {
            if (element.trim().startsWith("filename")) {
                return element.substring(element.indexOf('=') + 1).trim().replace("\"", "");
            }
        }
        return null;
    }

    // 解压zip文件
    private void unzip(String zipFilePath, String destDirectory) throws IOException {
        try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFilePath))) {
            byte[] buffer = new byte[4096];
            ZipEntry zipEntry = zipInputStream.getNextEntry();
            while (zipEntry != null) {
                String entryFileName = zipEntry.getName();
                String entryPath = destDirectory + File.separator + entryFileName;
                if (zipEntry.isDirectory()) {
                    File dir = new File(entryPath);
                    dir.mkdirs();
                } else {
                    try (FileOutputStream outputStream = new FileOutputStream(entryPath)) {
                        int bytesRead;
                        while ((bytesRead = zipInputStream.read(buffer)) != -1) {
                            outputStream.write(buffer, 0, bytesRead);
                        }
                    }
                }
                zipEntry = zipInputStream.getNextEntry();
            }
        }
    }
}

标签:文件,java,String,servlet,----,漏洞,import,上传,response
From: https://www.cnblogs.com/thebeastofwar/p/17767464.html

相关文章

  • 练习选讲(2023.10)
    10月10.1P2572[SCOI2010]序列操作:线段树(紫)维护每个区间的两个懒标记,\(0/1\)的数量、左端点起\(0/1\)的数量、右端点起\(0/1\)的数量、区间内最大连续\(0/1\)长度即可。点击展开代码#include<iostream>#include<cstdio>#include<algorithm>usingnamespace......
  • 《架构师之路:软件架构之美》第六七章读书笔记
    6.1软件架构有助于交付高质量的产品软件架构是关于结构和愿景的,不思考软件架构(以及“大局”)会导致团队经常遭遇一些常见问题。你的软件系统有良好定义的结构吗?团队里每个人都以一致的方式实现特性吗?代码库的质量水平一致吗?对于如何构建软件,团队有共同的愿景吗?团队里每个人都......
  • 《软件工程:方法与实践》读书笔记3
    1.瀑布模型是最早出现的软件开发模型,在软件工程中占有重要的地位,它提供了软件开发的基本框架。瀑布模型的本质是一次通过,即每个活动只执行一次,最后得到软件产品,也称为“线性顺序模型”或者“传统生命周期”。其过程是从上一项活动接收该项活动的工作对象作为输入,利用这一输入实施......
  • 「杂文」身为 OIer 的我要在第 7 周速通《汇编语言》,我为什么会做这样的梦(雾)
    目录写在前面计算斐波那契数列第\(i\)项写在最后写在前面编译器为MASM-v6.11写的一坨屎。计算斐波那契数列第\(i\)项最多支持输出30位十进制数。为第22行的cx寄存器赋值即为所求的项。.modellargeassumecs:code,ss:stackstringsegmentdb30dup(0),......
  • 计算机组成原理之地址映像
    1、直接映像2、全相联映像3、组相联映像......
  • GO 语言如何用好变长参数?
    函数重载对于函数重载相信编码过的xdm肯定不会陌生,函数重载就是在同一个作用域内定义多个具有相同名称但参数列表不同的函数此处的参数列表不同,可以是参数的类型不同,参数的个数不同那么我们一起分别来看看C语言,C++语言,GO语言如何去模拟和使用重载,体会一下C语言模拟重载......
  • 小红书疫情时代消费心理研究--小红书研究院
    https://kdocs.cn/l/cc0b1U9MpYsc报告阅读说明研究对象:过去一年内在美妆、服饰、母婴、家电/数码、家居/家装、食品饮料、奢侈品品类中有过消费或目前拥有汽车产品的小红书用户;样本覆盖国内1-6线城市,总有效样本共2036个。研究数据:本次报告基于2023年1月收集的调研数据,涉及与《20......
  • 北林OJ_243
    #include<iostream>usingnamespacestd;#defineOK1#defineERROR0#defineMaxSize100typedefintElemType;//定义栈_顺序栈structStack{ ElemType*top; ElemType*base; intstacksize;};intIsFull(Stacks);intIsEmpty(Stacks);//初始化intInitStac......
  • 智慧矿山AI算法极速解决皮带问题!
    近年来,随着智能技术的迅速发展与应用,智慧矿山逐渐成为提高生产能力和安全性的重要手段。其中,皮带运输系统作为矿山生产过程中的关键环节,其运行状态的准确判定和及时预警对矿山的安全和效率至关重要。为了实现对皮带运行状态的准确识别,智慧矿山AI算法应运而生。为什么需要皮带运行状......
  • Makefile knowledge summarization
    WildcardThewildcardinmakefileissimilarwithmacroinC/C++,itisn'tsimilarwithwildcardinlinuxshell,soitdoesn'texpendautomatically.object1=*.c//*.cobject2=$(wildcard*.cpp)//main.cppt1.cppt2.cppAutomaticallygene......