zabbix监控是谷歌研发的吗?

Fuchsia 是一个通用的开源操作系统。谷歌在 2016 年左右开始了这个操作系统的开发。2020 年 12 月,这个项目对来自公众的贡献者开放。2021 年 5 月,谷歌正式发布了在 Nest Hub 设备上运行的 Fuchsia。该操作系统支持 arm64 和 x86-64。Fuchsia 正在积极开发中,看起来很有活力,所以我决定在它身上做一些安全实验。

让我们来看看 Fuchsia 设计的基本理念。这个操作系统被开发用于与各种设备相关联的生态系统:物联网、智能手机、PC。这就是为什么 Fuchsia 的开发者特别关注安全性和可更新性。因此,Fuchsia 操作系统采用了非同一般的安全架构。

首先,Fuchsia 没有用户的概念。相反,它是基于能力的。内核资源作为需要相应能力的对象公开给应用程序。其主要思想是,如果一个应用程序没有显式授予的能力,它就不能与一个对象进行交互。此外,在 Fuchsia 上运行的软件应该获得最少的能力来执行其工作。因此,我认为,Fuchsia 中的本地权限升级(Local privilege escalation,LPE)的概念将不同于 GNU/Linux 系统中的概念,在 GNU/Linux 系统中,攻击者以非特权用户的身份执行代码,并利用一些漏洞来获得 root 权限。

第二个有趣的方面:Fuchsia 是基于微内核的。这极大地应县了该操作系统的安全性。大量的功能都从 Zircon 微内核转移到了用户空间。这使得内核的攻击面更小。在 Fuchsia 文档中,可以看到 Zircon 仅实现了少数服务,与单片式操作系统内核不同。不过,Zircon 并不追求最小化:它拥有超过 170 个系统调用,远远多于典型的微内核。

我不得不提到的下一个安全解决方案是沙箱。在 Fuchsia 中,应用和系统服务是被称作组件的独立的软件单元。这些组件在隔离的沙箱中运行。它们之间的所有进程间通信(inter-process communication,IPC)都必须明确声明。Fuchsia 甚至没有全局文件系统。相反,每个组件都有自己的本地命名空间来运行。这种设计方案增加了用户空间的隔离性和 Fuchsia 应用的安全性。我认为这也使得 Zircon 内核对攻击者很有诱惑力,因为 Zircon 为所有 Fuchsia 组件提供了系统调用。

最后,Fuchsia 在软件发布和升级方面有着非同一般的计划。Fuchsia 的组件是由 URL 识别的,可以按需解决、下载和执行。这个设计方案的主要目标是使 Fuchsia 中的软件包永远是最新的,就像网页一样。

这些安全特性使 Fuchsia OS 成为我感兴趣的新研究目标。

Fuchsia 文档提供了一个很好的教程,描述如何开始使用这个操作系统。该教程给出了一个脚本的链接,该脚本可以检查你的 GNU/Linux 系统是否符合从源代码构建 Fuchsia 的要求:

它说不支持非 Debian 发行版。然而,我还没有经历过针对 Fedora 34 的问题。该教程还提供了下载 Fuchsia 源代码和设置环境变量的说明。

构建完 Fuchsia 系统后,你可以在 FEMU(Fuchsia 模拟器)中启动它。FEMU 基于安卓模拟器(AEMU),它是 QEMU 的一个分支。

让我们为 Fuchsia 创建一个“hello world”的应用程序。正如我前面提到的,Fuchsia 的应用程序和程序被称为组件。这个命令为一个新的组件创建一个模板。

我希望这个组件将“hello”打印到 Fuchsia 日志:

这些命令用一个新的组件来构建 Fuchsia:

当带有新组件的 Fuchsia 构建完成后,我们就可以测试它了:

在主机系统的第二个终端使用命令 fx serve 来启动 Fuchsia 软件包发布服务器。

在主机系统的第三个终端使用命令 fx log 来显示 Fuchsia 的日志。

在主机系统的第四个终端上使用 ffx 工具启动新的组件。

现在我们来关注一下 Zircon 内核的开发工作流程。C++ 的 Zircon 源代码是 Fuchsia 源代码的一部分。它位于 zircon/kernel 子目录下,在 Fuchsia 操作系统建立时进行编译。Zircon 的开发和调试需要使用 fx qemu -N 命令在 QEMU 中运行它。然而,当我尝试时,我得到了一个错误:

我发现这个故障发生在具有非英语控制台语言的机器上。这个错误已经存在了很长时间了。我不知道为什么这个补丁还没有被合并。有了这个补丁,Fuchsia OS 可以在 QEMU/KVM 虚拟机上成功启动。

参数 -s 1 指定了这个虚拟机的虚拟 CPU 的数量。拥有一个虚拟 CPU 可以使调试体验更好。

如果你在调试过程中需要单步执行,--no-kvm 参数很有用。否则 KVM 的中断会破坏工作流程,Fuchsia 会在每个 stepi 或 nexti GDB 命令后进入中断处理程序。然而,在没有 KVM 虚拟化支持的情况下运行 Fuchsia VM 会慢很多。

允许执行 Zircon GDB 脚本,该脚本提供以下内容:

GDB 的 KASLR 重定位,这是正确设置断点所需要的。

Zircon 对象的漂亮打印机(目前还没有)。

增强了 Zircon 内核故障的解除器。

然而,在我的机器上,Zircon 的 GDB 脚本在每次启动时都完全挂起,我不得不对这个脚本进行调试。我发现它调用了带有 -readnow 参数的 add-symbol-file GDB 命令,这需要立即读取整个符号文件。由于某些原因,GDB 无法在合理的时间内从 110MB 的 Zircon 二进制文件中读出符号。在我的机器上去掉这个选项就解决了这个问题,并允许正常的 Zircon

正如你所看到的,如果定时器的最后期限值以 31337 结束,那么无论 refcount 值如何,TimerDispatcher 对象都被释放了。我想从用户空间组件打这个内核 bug,看看 KASAN 错误报告。这就是我添加到我的 a13x-pwns-fuchsia 组件中的代码。

这里调用了 zx_timer_create() 系统调用。它初始化了一个新定时器对象的定时器句柄。然后这个程序将定时器的最后期限设置为以 31337 结尾的魔法值。在这个程序等待 zx_nanosleep() 的时候,Zircon 删除了被启动的定时器。下面的 zx_timer_cancel() 系统调用对于被删除的定时器会引发使用后的免费。

因此,执行这个用户空间组件会使 Zircon 内核崩溃,并产生一个可爱的 KASAN 报告。很好,KASAN 管用!引述相关部分:

Zircon 还将崩溃的回溯打印成一些模糊的内核地址链。为了使它能被人类阅读,我不得不用一个特殊的 Fuchsia 工具来处理它:

当我让 Fuchsia OS 与 KASAN 一起工作时,我感到自信并为安全研究做好了准备。

在研究了 Fuchsia 内核开发工作流程的基础知识后,我决定开始安全研究。对于 Fuchsia 内核安全的实验,我需要一个 Zircon bug 来开发一个 PoC 漏洞。实现这一目标的最简单方法是模糊处理。

有一个伟大的覆盖率引导的内核模糊器,叫做 syzkaller。我很喜欢这个项目和它的团队,我喜欢用它来对 Linux 内核进行模糊处理。syzkaller 的文档说它支持对 Fuchsia 的模糊处理,所以我首先尝试了一下。

然而,由于 Fuchsia 上不寻常的软件交付,我遇到了麻烦,这是我前面描述过的。一个用于模糊测试的 Fuchsia 镜像必须包含 syz-executor 这个组件。syz-executor 是 syzkaller 项目的一部分,负责在虚拟机上执行模糊测试的输入。但我没能用这个组件构建一个 Fuchsia 镜像。

看起来构建系统并没有正确处理 syzkaller_dir 参数。我试图删除这个断言并调试 Fuchsia 的构建系统,但我失败了。

的系统调用、头文件位置等有很多变化。

简而言之,也许 Fuchsia 与 syzkaller 的集成在 2020 年曾经工作过,但目前它已经损坏。我查看了 Fuchsia 的版本控制系统,找到了致力于这个功能的 Fuchsia 开发者。我给他们写了一封邮件,描述了这个 bug 的所有技术细节,但没有得到回复。

在 Fuchsia 构建系统上花费更多的时间,让我感到压力很大。

我反思了我的进一步研究的策略。如果不进行模糊处理,要成功发现操作系统内核中的漏洞需要:

对其代码库的良好了解;

对其攻击面的深刻认识。

获得 Fuchsia 的这些经验需要我花费大量的时间。我想在我的第一个 Fuchsia 研究上花费大量时间吗?也许不是,因为:

把大量的资源投入到对系统的第一次熟悉中是不合理的;

事实证明,Fuchsia 并不像我预期的那样可以用于生产;所以我决定推迟在 Zircon 中搜索零日漏洞,并尝试为我用于测试 KASAN 的合成漏洞开发一个 PoC 漏洞。最终,这是一个很好的决定,因为它给我带来了快速的结果,并允许我沿途发现其他 Zircon 漏洞。

所以我专注于利用 TimerDispatcher 的免费使用。我的开发策略很简单:用受控数据覆盖释放的 TimerDispatcher 对象,使 Zircon 的定时器代码工作异常,或者说,将这段代码变成一个奇怪的机器。

首先,为了覆盖 TimerDispatcher,我需要发现一个堆喷射(Heap Spraying)的利用原语,该原语是:

可以被攻击者从无特权的用户空间组件中使用;

让 Zircon 分配几个新的内核对象,使其中一个对象大概率地被放在被释放对象的位置上;

让 Zircon 把攻击者的数据从用户空间复制到这个新的内核对象中。

我从我的 Linux 内核经验中知道,堆喷射通常是利用进程间通信(IPC)构建的。根据第 1 段,基本的 IPC 系统调用通常对无特权的程序可用。根据第 3 段,它们将用户空间的数据复制到内核空间,以便将其传输给接收者。最后,根据第 2 段,一些 IPC 系统调用设置了传输的数据大小,这就给出了对内核分配器行为的控制,允许攻击者覆盖目标释放的对象。

数据分配所需的内核内存。

通过调试器,我确定释放的 TimerDispatcher 对象的大小是 248 字节。我假设,为了成功地进行堆喷射,我需要创建相同数据大小的 Zircon FIFO。这个想法立即奏效:在 GDB 中,我看到 Zircon 用 FifoDispatcher 的数据覆盖了释放的 TimerDispatcher! 这就是我的 PoC 漏洞中的堆喷射的代码:

这里 zx_fifo_create() 系统调用被执行了 10 次。每一次都会创建一对包含 31 个元素的 FIFO。每个元素的大小为 8 字节。所以这段代码创建了 20 个 FifoDispatcher 对象,有 248 字节的数据缓冲区。

好的,我可以更改 TimerDispatcher 对象的内容。但是,要在其中写入什么内容才能发动攻击呢?

作为一个 Linux 内核的开发者,我已经习惯了用 C 结构来描述内核对象。一个 Linux 内核对象的方法被实现为一个存储在相应 C 结构中的函数指针。这种内存布局是明确而简单的。

但是,Zircon 中 C++ 对象的内存布局在我看来要复杂得多,也晦涩难懂。我试图研究 TimerDispatcher 对象的解剖结构,并在 GDB 中使用 print -pretty on -vtbl on 命令进行展示。输出结果是一大堆乱七八糟的东西,而且我没能把它和这个对象的十六进制转储关联起来。然后我试了一下 TimerDispatcher 的 pahole 工具。它显示了类成员的偏移量,但对理解类方法的实现方式没有帮助。类的继承性使整个情况更加复杂。

没有问题。我发现这个 refcount 被存储在从 TimerDispatcher 对象开始的 8 字节偏移处。为了绕过这个检查,我在堆喷射出的有效负载中设置了相应的字节:

控制流劫持需要了解内核符号地址,这取决于 KASLR 的偏移。KASLR 是指内核地址空间布局随机化。Zircon 源代码中多次提到 KASLR。一个例子来自 zircon/kernel/params.gni:

对于 Fuchsia,我决定实现一个类似于我对 Linux 内核的 KASLR 绕过的技巧。我对 CVE- 的 PoC 攻击使用了 Linux 内核日志来读取内核指针,以启动攻击。Fuchsia 内核日志也包含安全敏感的信息。所以我尝试从我的非特权用户空间组件读取 Zircon 日志。我添加了 use: [ { protocol:

首先,这段代码创建了一个 Fuchsia 通道,将用于 Fuchsia 日志协议。然后,它为 ReadOnlyLog 调用 fdio_service_connect(),并将通道传输附加到它上面。这些函数来自 fdio 库,它为各种 Fuchsia 资源提供了一个统一的接口:文件、套接字、服务和其他。执行这段代码会返回错误:

那是正确的行为。我的组件是无特权的,而且在父类中没有匹配的 fuchsia.boot.ReadOnlyLog 的 offer 声明。因为这个 Fuchsia 组件不具备所需的能力,所以不被授予访问权。没有办法。

所以我放弃了从内核日志中泄露信息的想法。我开始浏览 Fuchsia 的源代码,等待另一种启示。突然间,我发现了另一种使用 zx_debuglog_create() 系统调用来访问 Fuchsia 内核日志的方法:

这段代码成功了!我设法在没有所需功能和ZX_RSRC_KIND_ROOT 资源的情况下读取了 Zircon 内核日志。但为什么呢?我很惊讶,发现 Zircon 代码负责处理这个系统调用。以下是我的发现:

有一个不当的能力检查,导致内核信息泄露。顺便说一下,这个问题追踪器要求提供纯文本的信息,但默认情况下,它将报告渲染成 Markdown(这很奇怪,点击 Markdown 按钮可以禁用这种行为)。

Fuchsia 的维护者批准了这个问题,并申请了 CVE-。

由于阅读 Fuchsia 的内核日志不再是一个问题,我从其中提取了一些内核指针来绕过 Zircon KASLR。我第二次感到惊奇,又笑了起来。

尽管有 KASLR,但每次 Fuchsia 启动时的内核指针都是一样的!请看相同的日志输出的例子。Boot #1:

内核指针是一样的。Zircon KASLR 不起作用。我在 Fuchsia 的 bug 追踪器中提交了一个安全问题(禁用 Markdown 模式才能正确看到)。Fuchsia 的维护者回答说这个问题他们已经知道了。

Fuchsia OS 的实验性比我想象的要强。

在我意识到 Fuchsia 的内核函数有固定地址之后,我开始研究 Zircon C++ 对象的 vtables。我想,构造一个假的 vtable 可以实现控制流劫持。

正如我所提到的,指向相应 vtable 的指针被存储在对象的开头。这是 GDB 为 TimerDispatcher 对象显示的内容:

这个高级别的 C++ 噩梦变成了下面的简单汇编:

Prevention),它阻止从内核空间访问用户空间的数据。

在我的 Linux 内核防御图中,你可以看到 SMAP 在 Linux 内核中控制流劫持攻击的各种缓解措施中。我看到有多种方法可以通过在内核空间放置假 vtable 来绕过 SMAP 保护。

另一个想法是使用某个内核地址的内核日志信息泄露,该地址指向攻击者控制的数据。

但为了简化我对 Fuchsia 的第一次安全实验,我决定在启动 QEMU 的脚本中禁用 SMAP 和 SMEP,并在用户空间创建我的漏洞中的假 vtable。

这看起来很棘手,但不要害怕,你会喜欢它的!

这就是在执行漏洞时发生在地址上的魔法。真实的例子:

在实现了 Zircon 内核空间的任意代码执行后,我开始考虑用它来攻击什么。我的第一个想法是伪造一个假的 ZX_RSRC_KIND_ROOT 超能力资源,我之前在 zx_debuglog_create() 中看到过。但我没能利用 ZX_RSRC_KIND_ROOT 设计出特权升级,因为在 Fuchsia 的源代码中,这个资源用得不多。

由于知道 Zircon 是一个微内核,我意识到特权升级需要攻击通过微内核进行的进程间通信(IPC)。换句话说,我需要在 Zircon 中使用任意代码执行来劫持 Fuchsia 用户空间组件之间的 IPC,例如,在我的非特权开发组件和一些特权实体(如组件管理器)之间。

我又回到了研究 Fuchsia 用户空间的过程中,这很混乱,也很无聊……但我突然有了一个想法:

在 Zircon 中植入一个 rootkit 怎么样?这看起来有趣多了,于是我转而研究 Zircon 系统调用的工作原理。

下面是这段代码在调试器中的样子:

啊哈,它显示系统调用表在 0xffffff003c49f8。让我们看看内容:

是的,最后一个系统调用的函数指针 0xffffffff00307d10 就在系统调用表的末端。这些知识对于我的 rootkit 实验来说已经足够了。

作为第一个实验,我在 pwn() 函数中用 0x41 重写了整个系统调用表。正如我提到的,这个函数的执行是 Zircon 中控制流劫持的结果。为了覆盖只读的系统调用表,我使用了老派的经典方法,即改变 CR0寄存器中的 WP 位:

很好。然后我开始考虑如何劫持 Zircon 的系统调用。类似于 Linux 内核 rootkits 的做法是不可能的:通常的 Linux rootkit 是一个内核模块,在内核空间提供钩子作为特定模块的功能。但在我的案例中,我试图将用户空间的 rootkit 植入微内核中。把 rootkit 的钩子作为用户空间的函数在利用进程的上下文中实现是行不通的。

所以我决定把 Zircon 的一些内核代码变成我的 rootkit 钩子。我的第一个覆盖对象是 assert_fail_msg() 函数,它在漏洞开发过程中让我很头疼。这个函数足够大,所以我有很多空间来放置我的钩子有效负载。

我用 C 语言编写了 zx_process_create() 系统调用的 rootkit 钩子,但不喜欢编译器生成的钩子汇编。所以我用 asm 重新实现了它。让我们看一下代码,我喜欢这部分:

这个钩子保存了(推到栈)所有的寄存器,这些寄存器可能会被后续的函数调用所破坏。

这个函数的第一个参数是通过 rdi 寄存器提供的。它存储了我想打印到内核日志的字符串的地址。这方面的更多细节将在后面介绍。STR 和 XSTR 宏的技巧被用于字符串化;你可以在 GCC 文档中读到它。

零 al 表示没有向量参数被传递给这个参数数量可变的函数。

在调用内核 printf() 后,被钩住的寄存器被恢复。

现在是最有趣的部分:植入 rootkit。pwn() 函数将钩子的代码从利用二进制文件复制到 assert_fail_msg() 地址处的 Zircon 内核代码中。

这个函数的第一个字节被覆盖为 0xc3,也就是 ret 指令。我这样做是为了跳过 Zircon 在断言上的崩溃;现在断言处理会立即返回。

最后,pwn() 漏洞函数返回 42。正如我所提到的,Zircon 使用我的假 vtable 并执行这个函数,而不是 TimerDispatcher.get_type() 方法。这个内核对象的原始 get_type() 方法返回 16,以通过类型检查并继续处理。而在这里,我返回 42,表示该检查失败,并完成了 zx_timer_cancel() 系统调用,该调用击中了内存释放后使用。

我为 zx_process_exit() 系统调用在 assert_fail() 内核函数的位置上实现了一个类似的 rootkit 钩。所以 rootkit 在进程创建和退出时将信息打印到内核日志中。请看该漏洞演示:

这就是我遇到 Fuchsia OS 及其 Zircon 微内核的原因。这项工作对我来说是一次全新的体验。自从我在温哥华举行的 2018 年 Linux 安全峰会上听说了这个有趣的操作系统,我想在这个操作系统上尝试我的内核黑客技术已经很久了。所以我很高兴这项研究。

在这篇文章中,我对 Fuchsia OS、其安全架构和内核开发工作流程进行了概述。我从攻击者的角度评估了它,并分享了我对 Zircon 微内核的漏洞开发实验结果。对于本研究中发现的 Fuchsia 安全问题,我遵循了负责任的披露程序。

这是关于 Fuchsia OS 安全的首批公开研究之一。我相信这篇文章对操作系统安全社区很有帮助,因为它突出了微内核漏洞利用和防御的实际问题。我希望我的工作也能激发你做内核黑客的热情。谢谢你的阅读!

Alexander Popov,2013 年成为 Linux 内核开发人员,关注内核安全。技术博主,专注漏洞发现、利用技术和防御技术。

1、路径:配置——主机——选择‘WEB监测',点击右上角‘创建WEB场景'


2、填写场景名称、应用集、更新间隔、尝试次数以及客户端,这些都可以自定义

3、点击‘步骤'——点击‘添加',配置第一步‘打开页面',配置如下图所示,步骤名称自定义,URL填写打开zabbix时的网址链接,一般是http://IP/zabbix。

勾选‘跟随跳转'(不勾选会报301错误),超时时间默认15s,要求的状态码填200(多个状态码用西文逗号隔开即可,如:200,404,500),然后点击右下角‘添加'添加步骤。


再次点击‘添加',成功添加新的Web场景

点击‘监测'——‘最新数据',选择我们的测试机,稍等一分钟后可以看到有数据,说明配置无误。这里我们可以看到步骤‘打开页面',返回的信息,其中从键值看有‘ web.test.in'(平均下载速度),‘ web.test.fail'(失败的步骤数量),‘ web.test.error'(返回报错时的文本信息),‘

4、接来下配置步骤二,模拟登陆‘登录页面'

众所周知,登陆zabbix需要用到账号密码,这里我们需要用到谷歌浏览器(其他浏览器也可以,个人习惯用谷歌)来帮忙分析下登陆页面需要用到的信息。

打开zabbix登陆页面(http://IP/zabbix),按下‘F12',点击‘Network',红色小圆圈表示开启网络日志分析,页面资源这里我选择All,不同的web需要具体分析合适的资源。

输入账号密码,点击‘Sign in'登陆之后,点击index.php这个文件(一般看点击登录选项后,出现的第一个请求的资源文件),拉到最下方可以看到‘From Data',这里就是本次页面登陆监测需要用到的信息。点击‘view source',可以看到一串字符,如下图。我们把它复制到临时文档,保存备用。

回到Web场景,新建一个步骤‘登陆页面',URL填写登陆zabbix后出现的链接,点击‘原始数据',将刚才从网页上获取到的包含账号密码信息的字符串复制到‘原始发布'里面。勾选‘页面跳转',默认15s超时时间,要求的字符可以填写登陆页面后看到的任意字符串,我这里写了‘Global view',‘要求的状态码'同样填‘200',最后点击右下角‘添加',成功添加登陆页面的步骤。

PS:复制进原始数据后,再切换到表格资料,字段会自动匹配出来的,这个小细节个人觉得很赞

让我们再次看下最新数据,稍等一分钟,可以看到'登陆web'这个步骤的监测信息也已经出来了。

5、点击‘监测'——‘WEB监测',可以看到我们配置了WEB监测的主机,点击WEB场景的名称(这里是zabbix),可以看到以图表方式展示的WEB监测数据。

6、给创建好WEB场景添加触发器,这里就不多描述了,自行配置即可。添加完触发器后,我们整个WEB监测就到此完成了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。


2017年05月22 -  CentOS7.1 x64上下载了zabbix官方的rpm包,导入后使用yum安装了zabbix 3.2.6,但是启动zabbix server的时候报了个段错误的错,谷歌了一会儿,发现段错误不止一次的出现在了历史的bug中。解决方法除了官方修复bug外,还有就是自己编译。我选择了自己编译,下载好



我要回帖

更多关于 zabbix监控爱快 的文章

 

随机推荐