开源项目的软件供应链安全——是时候做好准备了!
对开源价值链(操作系统供应链)的攻击正变得越来越复杂,而我们,作为软件开发人员,正成为这些攻击的焦点。那么,最重要的第一步是什么,你应该关注什么?这就提出了合适的方法和工具的问题。同时,在这个安全战略中必须考虑公司的战略导向。
在最近的过去,我们还了解到攻击越来越多地针对软件开发的单个基础设施元素,例如经典的CI/CD管道。
在本次网络研讨会中,我们将讨论以下问题:
- 总的来说,有什么潜在的威胁
- 从源代码到二进制代码,软件开发中的经典攻击点是什么
- 有哪些工具,应该在哪里使用它们
- 我该如何武装自己,以应对未来网络攻击的挑战
2022世界杯阿根廷预选赛赛程资源:
视频记录
斯文Ruppert:
大家好,欢迎收看本期新视频。很高兴在这里见到你们,我们今天讨论的内容。所以今天我们想谈谈软件供应链安全。关键点是什么,不同的机制是什么?你可以在这里看到一些我想强调的来自Linux基金会的开源项目。我们想看一下漏洞,恶意代码包,最后,你可以做些什么来对付所有这些攻击。
如果你对这个感兴趣,就待在这里。顺便说一下,我叫斯文·鲁珀特。我是JFrog的开发者倡导者。如你所见,大部分时间我都待在树林里。是的,如果你是第一次观看我的视频,那么我很高兴,我也非常欢迎你。如果你想看更多关于Java或DevSecOps主题的视频,请访问我的YouTube频道,你会在那里看到很多。如果你喜欢某个视频,给我点赞,我很高兴看到你成为我的新订阅者。如果你开始订阅我的频道,你就不会错过任何其他视频了。现在是时候开始了。
好的,让我们开始谈谈供应链安全。供应链安全是一个非常宽泛的话题,软件供应链安全只是供应链安全的一部分。这是什么意思?供应链是指所有与人力有关的东西,包括人、机器、材料、第三方组件、流程,所有生产东西的东西,都在供应链中。
因此,在所有干扰它或危及它的事情中,都是针对供应链安全的事情。供应链安全正是关注这个主题,如何使一切顺利,这样你就可以工作,或者这个过程没有任何中断或中断。
软件供应链安全只是关注如何创建软件的一部分。好吧,这些年来供应链攻击有什么变化?很久以前,或多或少是一个个人或一群黑客试图闯入供应链,这或多或少是一个以金融为导向的方面,所以他们想以某种方式得到一些钱。
但在过去的几年里,尤其是现在,所以我们在2022年初,我们有一个全球政治形势不太好,现在在东方。然后,如果你直接或间接地为一家为政府工作的公司工作,或者你在供应链内部为一家被另一个政府作为目标的公司工作,让我们这样说,那么你可能不是被个人或黑客组织攻击,而是被政府攻击。这是完全不同的事情因为他们有完全不同的资源,不同的可能性。2022世界杯阿根廷预选赛赛程即使你是一家中小型公司,如果你是供应链的一部分,你现在可能受到政府而不是个人黑客的攻击。这是一个完全不同的野兽。
我们所看到的是,大公司每天都在提高他们的安全性。他们在人力、资金、基础设施等方面拥有大量资源。这意味着压力或攻击,他们越来越多地不是针对大公司,而是针对这些大公司周围的小公司。这意味着,随着时间的推移,这种压力会增加,即使你有一个小型或中型公司,假设有10或15名员工,你现在会受到对你的供应链部分的全部攻击,因为攻击中小型企业规模的公司要便宜得多,而不是攻击大公司。所以这意味着压力在逐步增加,就像大公司加强保护一样,这意味着对中小型企业的压力也会增加。
其中一个最大的问题是,应对所有这些攻击的关键因素是什么,或者你应该记住的基本事情是什么?无论你有什么样的供应链,可追溯性是抵御所有这些不同攻击的关键点之一,或者是防止其中受损元素的基本要素。可追溯性意味着所有的部分,你在做什么,在什么时间,谁参与,使用什么材料,输出是什么,输出经过哪里等等,如果你能够在整个供应链中有这种可追溯性,这是关键因素之一。但是现在我们想把这个组从一般供应链安全限制到软件供应链安全。这里我们关注的是从源代码到二进制代码。
好了,我们来谈谈软件供应链的安全问题。这是供应链安全的一个子集。它只关注软件,我有两个来自Linux基金会的开源项目,我很想在这里强调一下。一个是SLSA计划,另一个是Pyrsia计划。
让我们从SLSA开始。SLSA是一个文档项目,它意味着一群不同的个人或网络安全专家,或安全专家试图创建文档,首先,给你建议,这样你就知道你的安全处于什么水平,下一步是什么,你可以做些什么来增加你的安全性,以及对软件供应链的所有不同的常见攻击的描述。那么,在生产环境中,从源代码到二进制代码的攻击究竟是什么呢?
所以,SLSA项目的一部分就是这些级别。这些级别或多或少是为了让你知道你在哪里,你可以做什么,以及下一步要做什么来增加你的安全性。第一个级别是零级,你必须记录软件开发过程中使用的所有东西。所以它是所有内容的完整文档,这样您就知道发生了什么,涉及到什么地方,使用什么组件,等等。
所以,第一级描述的是你必须在软件构建材料中创建一个SBO,这样这个二进制文件就依赖于所有其他组件或其他依赖项,这样你就有了一个完整的依赖项列表。别担心,我们会关注这个SBO,它是什么,如何创建它,在这个视频的后面你可以在哪里得到它。这是第一级。
第二级是开始在源代码版本服务器和ICD环境以及二进制文件的存储库上使用GitHub存储库,并确保一切尽可能自动化。
第三级是引入安全审计。所以这意味着外部各方正在检查你的安全级别,你做得对和错,你应该做得更好。如果您做到了这一点,那么第四级就是描述不可变和可复制构建的定义。所以这意味着你知道什么是建筑的一部分,你复制了它,你只创造了一次边界,然后使用它们,所以它永远不会再创造一个边界。
所有这些都是对这个项目的一个非常非常简短的概述,但我在我的YouTube频道上有一个关于这个项目的视频,SLSA。在那里我将解释所有的机制,细节和所有不同的口味,你可以看到和到达那里。看看我的YouTube频道,搜索关于SLSA项目的视频。
因此,该项目SLSA的下一部分是关于针对软件供应链的最常见攻击的文档。这意味着我们现在关注的是从源代码到二进制代码,可能会发生什么,我们有一些东西。
例如,第一件事是,没有任何审查就不会进行源代码修改。如果你这么做了,下一次袭击会是什么?下一个攻击可能是您正在危及源代码组合本身。这意味着您只是在使用错误的命令或更改此部分的源代码,因此您必须提交此源代码存储库。从源代码存储库,它现在被转移到构建CI环境中。在这里,构建可以被改变,或者它可以被妥协,以一种获取原始资源的方式,但是用一些其他或额外的资源覆盖,或者你只是在妥协构建本身。
一个非常突出的例子是太阳风黑客,在CI环境中重建时,二进制文件在CI环境中被破坏了。因此,强化CI环境是一回事。现在,从CI环境中,它被推送到存储库中,在这里,您可以做的是,您可以绕过CI环境。假设我是CI环境并将受损的电池推送到存储库中,或者您可以攻击存储库本身。但有几件事。我们讨论的是不良的依赖关系,或者在构建过程中,你可以尝试提供不良的依赖关系,以便在构建过程中使用它,你可以从外部更改或提升存储库控制的边界。
长话短说,这意味着我们在这里有几个热点,主要的热点首先是三个组件,源代码存储库,CICD环境,以及获取二进制存储库。在这里,你只需要,但是你需要强化这个环境。
这是操作部分,但对于软件开发人员来说,还剩下两件事。自己的源代码和源代码法院是怎么回事,然后所有这些东西都是二进制文件。所以所有的依赖关系,我认为直接看这部分会更糟。源代码和二进制文件。
好了,我们来谈谈下一个项目,这个项目叫做Pyrsia。Pyrsia是一个项目,它是Linux基金会的开源项目,最初是由JFrog公司创建的。我们想要做的是,在这个项目中我们想要关注的是从,二进制文件将被构建到二进制文件将被交付。
它可以作为生产的依赖,但这是Pyrsia项目关注的部分,所有其他部分都是外部的,或者不包括在这个项目中。所以这意味着我们在这里关注,现在我们正在构建一个二进制文件,直到它将被交付。
Pyrsia是如何保护这个构建过程的软件供应链的?所以你想再一次建立基础设施。所以所有这些构建线程,Pyrsia正在做的是,你提供这个去中心化,它在P2P网络或点对点包管理器中。你所做的就是发送源代码所在的URL和一个通勤,然后不同的节点将获取源代码,将在本地构建它,然后共享二进制文件本身的信息。如果所有二进制文件都是相同的,那么构建基础结构就不会受到损害。
所以你可以在Pyrsia上创建不同的节点,但你无法控制你的节点是否被选中来建造某些东西。所以它实际上是随机选择的,很难以一种折衷的方式提供这些节点,所以你可以把折衷的二进制文件带到商业平台。现在我们在P2P网络中有了这个二进制文件,然后它将被传送到Pyrsia的分发层。
顺便说一下,这是对Pyrsia的一个非常简短的描述,所以如果你想了解更详细的内容,请查看我的YouTube频道。我有一个关于Pyrsia项目的视频,然后我会详细介绍每一步,这样我就能提供所有关于内部的信息。在这里,它只是一个非常简短的概述。
好吧,Pyrsia是怎么传送二进制文件的?所以这是一个点对点网络。如果你现在有这个,比如,Pyrsia网络中的原生依赖,你会问,有了Maven坐标,Pyrsia节点,它就会被选中二进制文件所在的位置,然后你可以从几个点获取它。所以如果你有更大的二进制文件,你就拥有了P2P网络的所有优势,它可以部分地从不同的节点传递,以尽可能多地利用带宽。
另一方面,我们有通往Docker Hub和Maven Central的网关,例如,这些是授权节点。因此,如果某个东西不在poser网络中,它将从这个授权节点获取,然后也存储在PTP网络中。所以如果这些节点宕掉了一次或者几分钟,你可以问一个poser网络,它还会在那里。另一方面,看看这个项目的网站,这是一个年轻的项目,是的,我可以说尝试一下。
好的,我们看到我们有不同的部分,一个是由组织或操作部分完成的,另一个是被称为二进制文件的源代码。我想强调网络防御的四个主要领域,网络安全或[听不清00:14:58],无论你想说什么,或者你想把它放在哪里。首先,[听不清00:15:03]应用程序安全测试,它不是测试机制,你要测试每个组件,直到它不运行。从第一行代码开始,你可以说这取决于你而不是你的扫描。
如果某些东西已经在运行,你有这个动态应用安全测试意味着应用正在运行你从外部看这个你有更多的黑客方法,两者的结合是IAST,交互式应用安全测试,这意味着你从外部技术增加环境你从内部看,修改技术因素和所有这些东西。最后一部分是运行时应用程序安全保护,前面已经提到过,它只适用于生产环境,它意味着在生产环境中,您正在分析正在发生的事情,并试图识别它是否是正在进行的攻击。
最后一个,我只是添加了这一部分,因为它只是为了生产。如果你专注于last,这意味着你需要一个高技能的人。所以如果你已经有了安全方面的经验,这是你以后要做的事情。Dust部分在产品线中非常晚,因为你需要一些已经在运行的东西,你不能真正扫描100%的组件,因为你只是从外部看。因此,您应该明确地关注静态应用程序安全性部分,因为通过第一行代码,您可以开始扫描所有包含的组件并确定是否存在恶意包或漏洞。
所以我们看到,如果你想从Dust开始,我们有剩余的二进制源代码,我强烈建议你首先只关注二进制代码,因为如果你比较你写了多少代码,你添加了多少依赖关系,这是多少行代码,那么对于大多数项目来说,到目前为止,最大的部分是依赖关系。所以关注那里,扫描那里的漏洞,恶意代码包,如果你从网络防御或网络安全主题或内部开始,这是容易实现的目标。
那么,下一个问题是,“漏洞信息的最佳来源是什么?”这里我要说的是,无论你使用的是哪个数据库,都要确保你是在不同的数据库之外建立一个超集因为单个数据库大多缺乏漏洞因为它们的市场太大了你永远不知道这些信息卖给了哪个供应商。
所以,这正是我们在JFrog所做的或已经在做的。因此,如果我们汇集不同的漏洞数据库,商业的,免费的,我们有一个专门的研究团队在这个漏洞数据库之上,用缓解补救信息丰富这些数据,我们也在增加关于我们自己的零日的知识。所以无论你选择什么,确保你有它的对立面,就像我们在JFrog中做的那样。
我们来谈谈恶意软件包,我们有不同的方面,我想在这里强调一下,第一个是感染方法。那么,什么是感染方法呢?所以,这种恶意的方式,提供了一种方式,让你消费它。我将从类型引用开始。那么什么是类型引用呢?类型引用意味着你有一个常见的包,非常有名的包,它们有一个名字,你抓取这个代码,然后你根据常见的拼写错误改变这个依赖的名字。如果你有一个常见的错别字,你只是在一个正规的官方存储库中提供这个包。有了这个错别字,你只是引用了一个损坏的包,在这个包里你可以做任何你想做的事情。
下一件事是化妆。因此,Masquerading专注于模仿依赖的整个环境。所以你认为你在复制代码,元数据,你在这个里面添加了小块的恶意代码,你在构建Creme包。所以,你正在建造一些看起来完全一样的东西,可能有相同的名字,但在不同的地方提供,然后是洞察力,或者你被感染了。就是这样。所以和原始包唯一的区别是可能有一行代码被混淆了,它做了一些事情,调用了一些东西,发送了一些东西。
接下来是绘图包。绘图包或多或少类似于历史视图。你有一个包可以做一些事情,一个PDF库,你可以打印这些东西。这是你需要的一切,但在这个里面你有额外的功能被混淆了,隐藏在某个地方,它只是在你使用这个运行良好的库的时候被激活。有时候有绘图包,它们是很好的库,它们给你很好的价值,但也有额外的价值。
另一种方式是依赖混淆。依赖混淆意味着,如果你有内部包和外部包,那么在你的公司里,我知道例如因为我知道有人在那里工作或者这个信息正在流出。我知道内部依赖的名字是什么,然后我可以做的是,我可以创建一个完全相同的依赖,一个更高的版本号,或者非常高的版本号,把它放在官方的存储库中。
所以我用的是完全相同的定义,但是我的CI环境首先看的可能是main central,然后抓住这个错误的依赖,名字相同,功能相同,版本号略有不同。所以自动版本增加会从外部获取这个,然后你就会看到这种依赖关系的混乱。这是我的依赖,但它是从外面抢来的。
现在感染的方法是劫持。劫持意味着您可以访问这个项目的基础设施。你以某种方式接管了所有权。这可能是一种激进的方式,你真的打包了这个页面,有这个,或者如果有一个没有维护的项目,你看到它被使用了,然后你就把这个免费的域名重新建立起来,或者你拿了一个没有人维护的开源项目,做这个。
所以劫持是,是的,它或多或少,你是项目的维护者,但有不同的意图。这些是常见的感染方法。现在的问题是什么是常见的有效载荷?
另一件事是什么是常见的有效载荷?常见的有效载荷或多或少是他们在做的。那么这些恶意包中的代码是什么呢?还有一个更大的问题是敏感数据窃取者。这意味着他们想要信用卡号,用户令牌,环境变量,密码,用户名,等等。所以他们想窃取这些数据并将其发送到某个地方。你有这个,看,如果你有这个环境,非常能够检查这个名称并在下一个请求中向攻击服务器发送一个额外的请求。这是一方面。
另一件事是你有一个类似于连接后壳的东西,它就像一个远程庇护所。有一些恶意代码在等待并连接回攻击者服务器,这样他就知道,这个恶意代码在那里,我可以连接,然后我发送命令,它会在另一端执行,结果会被发送回来。
所以这就是,无论你在这个系统中做什么来做这个。另外一件现在很流行的事情是你可以下载并执行。所以你有一个恶意代码集,它连接到一个房间,它是关于下载二进制文件并开始执行它们。这通常用于加密货币挖掘。所以用别人的精力和金钱来挖掘加密货币,然后把这个寄回来。这些是恶意代码中最常见的有效载荷,但是如何隐藏这些恶意代码,然后我们讨论混淆技术。
现在谈谈混淆技术。混淆技术可以通过公共可用的混淆器或定制的混淆器来实现。但大多数情况下,你可以搜索混淆器,然后使用它。它们所做的或多或少,它们是,它们重命名变量,它们用不同的编码编码命令,所有这些东西,所以你不打算马上读它。所以你必须重新编码,看看发生了什么。
这是一件更有趣的事情是控制流扁平化。控制流或多或少是我们有这个控制。所以它运行A B C D E F G,然后在中间你加入一些IF和ELSE的东西。然后根据代码或变量的数量,执行不同的代码。这是在代码中实现的。它不是很明显,或者说你不会马上看到它。但是如果你分析整个控制工具。你会发现在这个主逻辑周围有一些东西。
其次是同形文字。同形字符是,你有这个不同的Unicode字符看起来像普通的ASCII拉丁字符,但如果你比较字符串和所有这些东西,它们会是不同的。有了这个,你可以确保一些比较总是成功或失败。所以对你来说,它看起来像普通的ASCII符号,但它是一个不同的Unicode符号。有了这个,你可以做更多的事情这是双向控制字符,这是冷却。
所以,我们从左到右,从右到左,等等,我们也可以对机器说。我们可以在我的源代码中使用这些控制字符,这样一个人可以从左到右阅读,看到,这是一些源代码,它有一些命令,它的排序,它的结束,等等。编译器会看到完全不同的结果。这个角色会从左到右,从右到左,阅读和解释这些东西,这是完全不同的。这是一件很酷的事情就理解这个问题而言,但它并不容易被发现。
所以我们听到了很多关于漏洞、恶意软件包、技术大师和所有这些东西。但第一个问题是,在软件开发链中,安全的正确位置在哪里?出去在任何地方都很容易。因此,每一个步骤都应该涉及或应该使用安全方法进行加固。所以安全就像质量一样,它是每一步的一部分。
另一方面,它的独特之处在于,它结合了[听不清00:27:01]依赖性管理和漏洞扫描。记住,所有技术层的所有依赖关系,都有一些仪表数据。所以,就像简单和动态链接的依赖性一样,编译范围在Tesco中,在一个版本范围内[听不清00:27:22]是静态链接的,动态链接的等等。所有这些信息都可以在这些不同的依赖管理器中获得。如果您正在获取该工件的所有依赖关系,并且您拥有完整的元数据并了解这些信息,那么您可以使用该元数据来分析,例如,反应缓解信息。
你可以用它来定义跨越不同技术边界或整个技术堆栈内部的整个技术向量。因此,拥有所有技术层的所有微小模型的信息,以及覆盖这些边界的可能性是一个巨大的优势,相比之下,我只得到一种技术或我只得到一种二进制因为大多数这些信息不是二进制的一部分,然后你不能使用这些信息。所以依赖于管理和扫描漏洞是一个很好的结合。
下一个问题是,“向左转移到CI环境足够了吗?”左移到CI是好的,因为这不是解析通过的完全自动化的大门,它是实现安全边界的地方,在进入下一步之前必须通过安全边界。但是向左移动到CI点是不够的因为如果它到达了CI点,那么你已经花了很多时间,也许你可以早一点做。
所以唯一比CI环境早一点的是IDE和命令界面。所以我们两者都有,我们有命令行接口,你可以直接在命令行上工作,你可以编写脚本,你可以用它来看看有什么漏洞。我们有这个IDE插件。因此,如果您键入依赖项的第一行,那么您将立即看到依赖项树中是否存在漏洞或是否存在一些遵从性问题。
虽然这是有道理的,但首先,如果你花时间去创造一些东西,将其推向CI,然后返回,这是不可能的,你必须重写它,然后你会感到无聊,第二个解决方案的质量可能不太好,因为你现在有时间压力,你已经浪费了很多时间,你会感到无聊,因为你做了两次事情。所以尽早获得这些信息是有意义的,这样你就可以专注于核心内容,并且不会感到无聊或浪费时间。
为什么应该使用CLI命令以及如何使用它。首先,你应该使用命令,因为有了它,你可以不使用任何其他工具。如果您正在克隆像Maven项目那样的存储库,那么您可以在命令行上进入终端shell,您可以进入该项目并调用命令JFrog ordered - nvm。用ordered - nvm,它是一个命令行界面,现在有一个项目,甚至可能有一个项目。它确实提取了整个[听不清00:30:26]并给出了这里定义的所有漏洞和合规问题。所以你可以配置手表和所有的东西,但是飞机只是订购它,并获得所有可用的信息。
有了这个。你不是在浪费时间。你可以在不启动任何工作流的情况下检查它或者只是打开ID这些东西。另一方面,您可以编写脚本,以便您的所有其他工具和现有基础设施也能够使用这些功能。
另一方面,你可以做更多的分析。例如,docker成像称为按需扫描。按需扫描意味着你在你的机器上创建docker映像,你编辑东西,你抓取不同的东西,你想知道这个docker映像是否足够好。因此,在合规问题方面,或者如果你有任何漏洞,你应该摆脱。
因此,您可以提取这个docker映像,以便在磁盘上拥有整个映像,然后可以使用Jfrog行中命令来分析这个docker映像。或者,如果您有docker桌面,您可以使用docker桌面牌匾,并分析这个docker映像。您可以立即获得有关内部漏洞和遵从性问题的信息,并且您可以将这些信息发送给Artifactory,然后根据需要获得这些信息,因此它被记录下来。如果你改变船坞图像,你会看到不同扫描之间的差异。
因此,您可以与有文档记录的同事一起工作,而无需将此docker映像的任何内容推送到此工件。因此,如果您在站点上编写内容而不使用CLI资源并在那里等待,则不会出现任何出血。2022世界杯阿根廷预选赛赛程
因此,使用CLI对集成有意义,对快速进入有意义,对分析正在发生的事情有意义,并为您提供直接应对挑战的灵活性。你们在这个环境中你们在稍早的时候我谈到了SPO。
那么SPO里有什么呢?SPO是一个由材料构建的软件,意味着用于创建该二进制文件的所有依赖项的完整列表。这在最近很流行,因为美国总统拜登的网络安全行政命令明确表示,美国政府使用、拥有、运行的任何东西都必须满足这一要求,因为SPO软件是由材料构建的。
所以你必须提供所有take层的所有依赖的完整列表。我们很久以前就知道了。几天前我们称它为“构建信息”。构建信息是SPO的一个超级集合。所以你可以在创建二进制文件的时候转到这里,不仅整个依赖于这个,而且它还添加了所有你想添加的元信息,比如环境,变量,日期。时间,机器,特工名字,等等。所以所有必要的东西和你想要推动的东西在另一边都可以看起来很漂亮。
为此,你的健康状况在x光机上和x光机上,你对弱点有实际的了解。所以这意味着如果你今天通过一项法案,它是绿色的,因为今天我们不知道内部的漏洞,并将其传递给生产。也许明天更新了漏洞数据库,我们知道,“哦,我们发现了一个新的漏洞,”然后我们知道,对于这个二进制文件,我们没有漏洞,所以我们保存这个信息,而不扫描产品,另一方面是不好的。
是的,每天早上扫描一下我昨天创建的重要二进制,这是件好事。例如,如果有一个新的漏洞条目。因此,有了这个,您可以在不扫描的情况下维护生产。在另一边,你可以点击x射线点击这个动作,点击这里,然后你可以创建SBO并以不同的形式提取SBO。所以这取决于你要满足什么是主导的,然后你有一切要符合这个网络安全的行政欺诈。
这意味着,我们现在有可能创建这个SBO。我们有可能看到过去创建的二进制文件的漏洞,结果,瘦的一切。我们可以使用它来积极维护在生产中运行的东西。顺便说一下,你会发现在某些地方有很多CVSS值,如果你点击CVSS值,你会看到所有的基本指标。
我现在没有足够的时间来解释所有这些不同的度量值,但是我有一个专门的YouTube演讲,它将通过所有的CVSS度量,你会看到你有可能将CVSS度量扩展到你的环境中。为此,你需要环境指标。如何使用它以及如何使用CVS计算器在我的一个视频中有展示。
而且它是很好的建议看到和玩周围的CVSS以及因为它会给你一些建议,哪一个是更重要的为你的环境,你可以调整你想要对抗弱点的顺序。
好吧,我们现在有很多东西了。我们讨论了供应链安全,软件供应链安全,以及这两个Linux基金会项目。我们看到了漏洞和恶意包之间的区别,不同的混淆技术,等等。我向你们展示了如何提取这个[听不清00:36:04],你可以在命令行上做什么,以及为什么通过CI向左移动是不够的,应该向左移动。
所以IDE或命令行接口都是一个包,但是在我的YouTube频道上有很多更详细的视频或主题可以看,或者直接去看看。如果你有兴趣尝试一下,我们是免费的。所以你可以在那里注册并自己尝试所有这些东西,或者参加我的网络研讨会或研讨会,在那里我们会对这些主题进行实践练习。剩下的三分之一,我的一天就结束了。我发现了这个湖,今晚我要在这里扎营,好好享受。无论你什么时候看到这个视频,我都希望你今天过得愉快,注意安全,再见。
