Kali Linux——寻找漏洞

484 阅读39分钟

在进行侦察活动并收集关于目标的信息后,你通常会继续寻找进入远程系统的入口点。你在寻找组织中的漏洞,这些漏洞可能会被利用。你可以通过不同的方式来识别漏洞。根据你的侦察,你甚至可能已经识别出一两个漏洞,这些漏洞可能是通过开放源的信息收集而获得的。

漏洞扫描是渗透测试人员以及信息安全团队常见的任务。市面上有许多商业工具可以用来扫描漏洞,也有一些开源扫描工具。Kali 提供的一些工具旨在跨不同类型的系统和平台进行扫描,而其他一些工具则专门用于查找路由器和交换机等设备中的漏洞。实际上,针对思科设备的扫描工具也不是什么意外。

在本章中,我们将探讨的工具大多是用于查找已知的漏洞。这些漏洞是已知的,通过与系统或其应用程序的交互来识别它们。然而,有时你可能想要识别新的漏洞。Kali 中有一些工具可以帮助生成应用程序崩溃的情况,这些崩溃可能会变成漏洞,尽管这些工具不会生成相应的利用代码。这些工具通常被称为模糊测试工具(fuzzers)。这是生成大量格式错误数据并将其提供给应用程序以查看如何处理输入的相对简单的方法。

然而,在开始这一过程之前,你需要理解什么是漏洞。理解漏洞的含义是非常重要的,因为漏洞容易被误解或与其他概念混淆。一个需要牢记的重要概念是,识别出漏洞并不意味着它们一定会被利用。即使发现的漏洞存在对应的利用方法,也不意味着这个利用方法一定有效。这个概念的重要性不容低估。漏洞并不必然导致被利用。

理解漏洞

在进一步讨论之前,先确保我们对“漏洞”的定义有统一的理解。漏洞有时容易与“利用”混淆,尤其当我们开始谈论风险和威胁时,这些术语会变得更加模糊。漏洞是系统或软件中的一种弱点。这种弱点通常是系统或软件配置或开发中的缺陷。如果这个漏洞可以被利用来获得访问权限或损害系统,那么它就是可被利用的。利用这种弱点的过程被称为“利用”。威胁是对系统可能造成伤害或使其不可用的可能性。风险是损失与概率的交集,这意味着你必须有可衡量的损失或损害,并且这种损失或损害的发生具有一定的概率。

这些概念可能比较抽象,让我们用具体的例子来说明。假设某人将默认的用户名和密码配置在系统上。这在很多设备中,尤其是在家庭无线接入点或电缆调制解调器中,曾是一个非常常见的做法。保持默认用户名和密码不变是一个漏洞,因为默认的用户名和密码很容易被尝试。尝试密码的过程就是利用这个漏洞的行为。这是由于配置错误导致的漏洞的一个例子。更常见的漏洞通常是程序性的,可能源自编程错误,例如缓冲区溢出。

如果你对漏洞感兴趣,并希望追踪发现漏洞的工作,可以订阅像 Full Disclosure 这样的邮件列表。你可以获得已发现漏洞的详细信息,有时还会包括可用于利用已发现漏洞的概念验证代码(Proof-of-Concept Code)。随着世界上软件数量的庞大,尤其是网页应用程序,每天都会发现很多漏洞。有些漏洞比较轻微,而有些则比较严重,这使得跟踪所有漏洞的工作变得具有挑战性。Full Disclosure 的存档可以在 SecLists 网站上找到。你可以从该页面订阅,并查看所有旧的漏洞披露。

接下来,我们将讨论几种类型的漏洞。第一种是本地漏洞。这些漏洞只有在你以本地访问权限登录系统时才能触发。这并不意味着你必须坐在控制台前,只要你对系统有某种交互式访问权限即可。你可以通过终端或图形桌面访问系统来远程访问。本地漏洞可能包括权限提升漏洞,即具有普通权限的用户通过某种方式获得更高级的权限,甚至达到管理员权限。通过使用类似权限提升的漏洞,用户可能获得本不应有的资源访问权限,也可能获得完整的管理员权限,执行诸如创建用户、服务或访问敏感数据等任务。

与本地漏洞相对的是远程漏洞。远程漏洞可以在没有本地访问权限的情况下被触发。但这要求有一个暴露的服务,攻击者可以通过该服务进行访问。远程漏洞可能是经过身份验证的,也可能是未经身份验证的。如果未经身份验证的用户能够利用漏洞获取系统的本地访问权限,那将是一个严重的问题。并非所有远程漏洞都导致系统的本地或交互式访问。漏洞可能导致拒绝服务、数据泄露、数据完整性破坏,甚至可能导致完全的交互式系统访问。

网络设备如交换机和路由器也容易存在漏洞。如果这些设备被攻破,可能会对网络的可用性甚至机密性造成毁灭性的影响。拥有交换机或路由器访问权限的人,可能会将流量重定向到原本不应访问的设备上。Kali 配备了可以用来测试网络设备漏洞的工具。由于思科是一个主要的供应商,集中在思科设备漏洞上的工具也就不足为奇了。

漏洞类型

开放Web应用安全项目(OWASP)维护着一份常见漏洞类别的列表。OWASP定期更新十大应用安全问题的列表。每年都有新的软件发布和更新,每一款软件都可能存在缺陷。对于那些可能产生漏洞的与安全相关的缺陷,有一些常见的类型值得关注。在我们深入探讨如何搜索这些漏洞之前,了解每种漏洞的基本概念是很重要的。

缓冲区溢出

缓冲区溢出是一个常见漏洞,已经存在了几十年。尽管一些编程语言会对输入程序中的数据以及程序中传递的数据进行大量检查,但并不是所有的编程语言都有这种检查。是否进行这些检查通常取决于语言本身及其如何创建可执行文件。然而,有些语言根本不进行此类检查。自动检查数据会带来额外开销,而并非所有语言都愿意强制要求程序员和程序承担这样的开销。较新的编程语言,如Go、Rust和Swift,在内存安全方面做得要好得多。而C语言一直因没有或只有有限的保护措施,无法防止像缓冲区溢出这样的内存错误而臭名昭著。

缓冲区溢出利用了数据在内存中结构化的方式。每个程序都会分配一块内存,其中一部分用于代码,另一部分则用于代码操作的数据。部分内存是一个称为“栈”的数据结构。你可以把栈想象成食堂排队取餐或者自助餐的餐盘堆。餐盘或托盘堆叠成一堆,来的人从堆顶取餐,而当餐盘用完后,新餐盘会放到堆顶。当堆被重新填充时,你可以将其理解为“推入栈”。然而,当最上面的餐盘被取走时,就可以理解为“弹出栈顶”。

程序的工作方式与此类似。程序通常通过函数来构建。函数是一段执行明确定义的操作或一组操作的代码。它允许在程序的多个地方多次调用相同的代码段,而不需要每次都重复相同的代码段。它还允许程序执行非线性代码。通过函数,程序的执行流程可以跳跃,而不是单纯地按顺序执行。当调用函数时,通常会传递参数,也就是要操作的数据。这些参数以及函数的局部变量会被放入栈中,这块数据被称为“栈帧”。

在栈帧中,除了与函数相关的数据外,还包含了程序在函数执行完后应该返回的地址。这也是程序能够非线性执行的原因。CPU并不会一直保持程序的执行流程,而是在调用函数之前,将程序最后执行位置的地址也推入栈中。

缓冲区溢出成为可能的原因是这些参数在栈上分配了固定大小的空间。假设你预期从用户输入10字节的数据。如果用户输入了15个字符(假设每个字符占1字节,尽管并不一定如此),那比分配给变量的空间多出了5个字节。由于栈的结构,所有变量和数据都位于返回指令指针之前。如果语言的运行时系统没有提前进行检查来截断数据,数据将直接写入内存中的下一个地址。这可能导致返回指令指针被覆盖,如果你发送足够多的数据,以至于覆盖了存储指令指针的位置。

图4-1展示了一个简化的栈帧示例,针对一个单独的函数进行演示。这里没有展示栈帧中所有的元素,而是专注于我们关心的部分。如果函数正在读取Var2,攻击者可以输入超过预期的32个字符。一旦输入的字符超过32个,任何额外的数据都会被写入返回指令地址所在的内存空间。当函数返回时,栈中的值会被读取,程序将尝试跳转到那个地址。缓冲区溢出试图让程序跳转到攻击者已知或控制的位置,以执行攻击者的代码。

image.png

当攻击者执行他们希望运行的代码,而不是程序本身的代码时,这种情况被称为任意代码执行。攻击者可以控制程序执行的流程,这意味着他们控制着程序的行为,包括程序执行的代码。能够做到这一点的攻击者,可能会获得程序所有者有权限访问的资源。原因在于,攻击者通常会在远程系统上打开一个命令行界面,这也是为什么注入到缓冲区空间的代码被称为“shellcode”——因为它运行的是一个shell。

竞争条件(Race Condition)

任何运行中的程序都不拥有独占的处理器访问权限。当程序运行时,它会被频繁地调入和调出处理器队列,以执行代码。现代程序可能是多线程的,它们有多个同时执行的路径。这些执行线程仍然可以访问相同的数据空间,如果我有两个线程在同时修改一个变量,而这两个线程 somehow 失序,就会在程序的操作中产生问题。

示例 4-1 展示了一小段 C 代码。请注意,这不是编写程序的推荐方式,因为有全局变量存在,且有更好的方法来保护共享数据,但这里只是为了说明一个概念,而非推荐的 C 代码写法。

示例 4-1:简单的 C 函数

int x;

void update(int y)
{
    x = x + y;
    if (x == 100)
    {
      printf("we are at the value");
    }
}

假设我们有两个线程同时运行这个函数。全局变量 x 被两个独立的线程以未知值进行递增。这个变量只占内存中的一个位置。而与之不同的是,两个线程执行 update 函数时会获得各自的 y 变量副本,y 是通过参数传入函数的。但 x 变量必须在所有函数实例间共享。竞争条件就是指当两个独立的执行路径同时访问同一组数据时发生的情况。如果内存没有被锁定,就可能在一个读取操作发生时,已经有一个写操作发生了。第二次对该内存位置的读取可能会获取到不同的值。这一切都取决于时序。

在这个例子中,我们来看这一行 x = x + y。首先,需要读取 xy 在内存中的值。假设当我们读取 x 的值时,它为 11。接着,我们加上 y 的值。可能在计算得出结果并将其写回到 x 所指向的内存位置之前,另一个函数实例已经更新了该内存位置。如果 y 被设置为 5,那么该调用实例的值将为 16。然而,在第二个实例中,y 可能是 10。那么突然间,x 的值变成了 21,但当 x 被写入时,我们得到的值是 16。哪一个是正确的呢?像这样编写程序会导致程序出现不可预测的行为。

如果程序的正确流程需要特定的时序,就有可能发生竞争条件。变量可能会在进行关键读取之前被更改,从而影响程序的功能。例如,可能会出现一个文件名,在该值被读取和操作之前被插入。由于多线程程序的异步性质,竞争条件可能很难被发现和隔离。没有像信号量这样的控制机制来指示值何时处于可以安全读取或写入的状态,程序员可能无法直接控制哪个线程将以什么顺序访问 CPU,从而可能会导致不一致的行为。

当然,以上只是一个简单的例子,用来清晰地展示这一点。更微妙的编程错误也可能导致由于竞争条件而出现不可预测的行为。

输入验证(Input Validation)

输入验证是一个广泛的术语,涵盖了缓冲区溢出以及其他一些漏洞。如果传入的缓冲区过长且未经过检查,那么这就是一个输入验证问题。然而,输入验证的问题远不止缓冲区溢出。实际上,缓冲区溢出涉及的是输入大小的检查,但其他类型的错误则是由于输入包含对程序或程序运行的系统有害的值。示例 4-2 显示了一个没有适当输入验证的 C 代码片段,这个片段很容易受到攻击。

示例 4-2:可能存在输入验证错误的 C 程序

int tryThis(char *value)
{
    int ret;
    ret = system(value);
    return ret;
}

这是一个小函数,它接受一个字符串作为参数。该参数直接传递给 C 库函数 system,该函数将执行权限交给操作系统。如果传入的值是 useradd attacker,它将直接传递给操作系统,如果程序有足够的权限(取决于程序运行的用户),那么它将创建一个名为 attacker 的用户。任何操作系统命令都可以通过这种方式传递。如果没有适当的输入验证,这将是一个重大问题,尤其是当攻击程序没有适当的权限时。事实上,这也是 Kali Linux 不再允许用户直接以 root 用户身份登录的原因之一。以 root 用户身份运行的程序可能会因编程错误被利用,攻击者将拥有整个系统的权限。

这种类型的输入验证问题在 Web 应用程序中可能更为常见。命令注入、SQL 注入和 XML 注入攻击都是输入验证不当的例子。值被传递到应用程序的元素中,却没有经过检查。这个输入可能是操作系统命令或 SQL 代码等。如果程序员在执行输入之前没有进行适当的验证,可能会发生严重问题。

访问控制(Access Control)

从漏洞的角度来看,访问控制是一个相对宽泛的类别。表面上看,访问控制只是确定谁可以访问资源以及他们可以访问的级别。访问控制可能成为漏洞的一个领域,特别是在程序以比程序本身功能所需更多的权限或特权运行时。例如,任何以 root 用户身份运行的程序都可能是一个问题。如果代码被利用(如通过输入验证不当或缓冲区溢出),攻击者所做的任何操作都会具有 root 权限。

这并不仅限于以 root 用户身份运行的程序。任何程序都以其拥有者的权限运行。如果程序的拥有者具有访问系统上任何资源的权限,那么该程序的漏洞可能使攻击者获得对该资源的访问权限。这类攻击可能导致特权升级:即用户获得了在系统正常状态下不应有的访问权限。

为了减轻这一问题(至少在一定程度上),可以要求在应用程序中进行身份验证。这对攻击者来说是一道障碍,攻击者必须先绕过身份验证才能利用程序——他们必须通过直接攻击或获取/猜测密码来绕过身份验证。有时我们能做到的最好就是让攻击者在获得访问权限时遇到麻烦。

漏洞扫描

漏洞扫描是一个主要用于查找已知漏洞的过程。在本章的其余部分,我们将探讨漏洞扫描器,但当人们谈论漏洞扫描器时,他们可能会想到那些可以检查本地和远程漏洞的通用扫描器。市场上有许多商业漏洞扫描器。在1990年代,最早的一个扫描器是网络分析安全管理员工具包(SATAN) ,不过如果有人对这个缩写感到反感,可以运行一个程序将其更改为SANTA。SATAN 最终变成了 SAINT,即 安全管理员集成网络工具包(Security Administrator’s Integrated Network Toolkit) ,它仍然作为商业扫描器存在。然而,SATAN 是开源并且免费提供的。很快,又有一个开源且免费的扫描器问世,它就是 Nessus

Nessus 最初是在1998年开发的,但到2005年,开发者决定关闭源代码,并将其转变为商业软件。我记得当时的情况是,开发者厌倦了自己是唯一的贡献者,社区并没有做出贡献,于是他们决定关闭源代码。这也就解释了一个开源漏洞扫描器的诞生——OpenVAS,它最初是 Nessus 的一个分支。早期的版本使用了 Nessus 的图形程序和框架,因此差别不大。

像许多其他漏洞扫描器一样,OpenVAS(以及很多商业软件)已经转向了基于网页的界面。虽然你可以获取并安装商业扫描器,然后在 Kali Linux 上使用它,OpenVAS 也可以作为一个包进行安装。它并不是默认安装的,因此你需要手动安装 openvas 包。安装完成后,你需要进行额外的设置和准备工作,以便使用 OpenVAS。这并不一定是一个简单的过程。首先,它要求安装 PostgreSQL 数据库,幸运的是,默认安装的 Metasploit 也需要 PostgreSQL,因此这并不算问题。配置 OpenVAS 的第一步如示例 4-3所示,你需要运行 gvm_setup。这个过程并不短暂,除了设置数据库,它还需要下载所有的漏洞签名。

示例 4-3:安装 OpenVAS

┌──(kilroy@badmilo)-[~]
└─$ sudo gvm-setup

[>] 启动 PostgreSQL 服务

[>] 创建 GVM 的证书文件

[>] 创建 PostgreSQL 数据库

[*] 创建数据库用户

[*] 创建数据库

[*] 创建权限
CREATE ROLE

[*] 应用权限
GRANT ROLE

[*] 创建扩展 uuid-ossp
CREATE EXTENSION

[*] 创建扩展 pgcrypto
CREATE EXTENSION
[>] 数据库迁移中
[>] 检查 GVM 管理员用户
[*] 为 gvm 创建用户 admin
[*] 请记下生成的管理员密码
[*] 用户已创建,密码为 'af6c349c-5a7e-4a84-862a-de61f00e807d'。
[*] 配置 Feed 导入所有者
[*] 定义 Feed 导入所有者
[>] 更新 GVM feeds
[*] 更新 NVT(网络漏洞测试 feed 来自 Greenbone Security ↩
Feed/Community Feed)

漏洞扫描器能够识别漏洞是因为它们寻找漏洞的签名或模式。漏洞扫描器并不会尝试利用漏洞,也不会发现之前没有存在过的漏洞。它们通过与程序和系统的交互来寻找模式。这些模式是由 OpenVAS 的维护者根据漏洞公告开发的。然而,不要认为仅仅因为漏洞扫描器不会利用漏洞来验证漏洞,扫描器就一定是完全安全的。扫描器可能会不小心对系统造成损害,包括导致停机。当你发送大量数据以寻找漏洞时,接收系统可能会出现问题。特别是一些非常脆弱的应用程序,可能会在扫描过程中出现故障,导致应用程序崩溃。

gvm_setup 过程会下载数百或数千个包含漏洞信息的 XML 文件。每个安装的漏洞都需要进行分类,以便在漏洞扫描中使用。示例 4-4 显示了一些 XML 文件正在被下载。根据磁盘、处理器和网络的速度,这个过程可能需要几个小时。请保持耐心,离开一会儿,找点别的事情做,直到一切安装完毕。你需要特别注意安装的最后部分。最后一部分的输出中会包含管理员用户的密码,你需要用它来第一次登录 OpenVAS。

示例 4-4:下载漏洞签名

nvdcve-2.0-2010.xml
     22,577,713 100%  983.91kB/s    0:00:22 (xfr#10, to-chk=33/44)
nvdcve-2.0-2011.xml
     22,480,816 100%  969.40kB/s    0:00:22 (xfr#11, to-chk=32/44)
nvdcve-2.0-2012.xml
     25,153,405 100%  995.05kB/s    0:00:24 (xfr#12, to-chk=31/44)
nvdcve-2.0-2013.xml
     28,559,864 100%  989.41kB/s    0:00:28 (xfr#13, to-chk=30/44)
nvdcve-2.0-2014.xml
     30,569,278 100%  991.56kB/s    0:00:30 (xfr#14, to-chk=29/44)
nvdcve-2.0-2015.xml
     32,900,521 100%  634.44kB/s    0:00:50 (xfr#15, to-chk=28/44)

安装完成后,你会看到像示例 4-5中那样的输出。在输出的最后部分,你可以看到管理员用户的密码。这个密码很长。虽然你可以通过命令行添加用户,但最简单的方法是确保将这个密码复制并存储在某个地方,直到你可以登录到 web 界面。你还会看到一个建议,提示你运行 gvm-check-setup。即使通过了 gvm-setup,你的 OpenVAS 安装仍然可能存在问题,因此你应该确保运行 gvm-check-setup 来检查。

示例 4-5:OpenVAS 配置完成

 ent 735 bytes  received 106,076,785 bytes  986,767.63 bytes/sec
total size is 106,049,031  speedup is 1.00

[+] GVM feeds updated
[*] Checking Default scanner
[*] Modifying Default Scanner
Scanner modified.

[+] Done
[*] Please note the password for the admin user
[*] User created with password 'af6c349c-5a7e-4a48-862a-de61f00e708d'.

[>] You can now run gvm-check-setup to make sure everything is correctly configured

理想情况下,你应该可以顺利通过 gvm-check-setup,没有任何问题。如果一切顺利,你会看到像示例 4-6所示的输出。如果遇到错误,我可以根据个人经验告诉你,解决这些问题可能会非常具有挑战性。建议按照这里描述的基本方法进行干净的安装,不要偏离。

示例 4-6:运行 gvm-check-setup

┌──(kilroy@badmilo)-[~]
└─$ sudo gvm-check-setup
gvm-check-setup 22.4.1
  Test completeness and readiness of GVM-22.4.1
Step 1: Checking OpenVAS (Scanner)...
        OK: OpenVAS Scanner is present in version 22.4.1.
        OK: Notus Scanner is present in version 22.4.4.
        OK: Server CA Certificate is present as /var/lib/gvm/CA/servercert.pem.
Checking permissions of /var/lib/openvas/gnupg/*
        OK: _gvm owns all files in /var/lib/openvas/gnupg
        OK: redis-server is present.
        OK: scanner (db_address setting) is configured properly using the 
        redis-server socket: /var/run/redis-openvas/redis-server.sock
        OK: redis-server is running and listening on socket: 
        /var/run/redis-openvas/redis-server.sock.
        OK: redis-server configuration is OK and redis-server is running.
        OK: the mqtt_server_uri is defined in /etc/openvas/openvas.conf
        OK: _gvm owns all files in /var/lib/openvas/plugins
        OK: NVT collection in /var/lib/openvas/plugins contains 85634 NVTs.
        OK: The notus directory /var/lib/notus/products contains 301 NVTs.
Checking that the obsolete redis database has been removed
        OK: No old Redis DB
        OK: ospd-OpenVAS is present in version 22.4.6.
Step 2: Checking GVMD Manager ...
        OK: GVM Manager (gvmd) is present in version 22.4.2.
Step 3: Checking Certificates ...
        OK: GVM client certificate is valid and present as 
        /var/lib/gvm/CA/clientcert.pem.
        OK: Your GVM certificate infrastructure passed validation.
Step 4: Checking data ...
        OK: SCAP data found in /var/lib/gvm/scap-data.
        OK: CERT data found in /var/lib/gvm/cert-data.
Step 5: Checking Postgresql DB and user ...
        OK: Postgresql version and default port are OK.
 gvmd    | _gvm   | UTF8   | en_US.UTF-8 | en_US.UTF-8 |        | libc        |
16435|pg-gvm|10|2200|f|22.4.0||
        OK: At least one user exists.
Step 6: Checking Greenbone Security Assistant (GSA) ...
        OK: Greenbone Security Assistant is present in version 22.04.1~git.
Step 7: Checking if GVM services are up and running ...
        OK: ospd-openvas service is active.
        OK: gvmd service is active.
        OK: gsad service is active.
Step 8: Checking few other requirements...
        OK: nmap is present.
        OK: ssh-keygen found, LSC credential generation for GNU/Linux targets is 
        likely to work.
        OK: nsis found, LSC credential package generation for Microsoft Windows 
        targets is likely to work.
        OK: xsltproc found.
Step 9: Checking greenbone-security-assistant...
        OK: greenbone-security-assistant is installed

It seems like your GVM-22.4.1 installation is OK.

现在你应该有一个正常工作的 OpenVAS 设置。你可以通过运行 gvm-start 来启动它。如果服务正在运行且你想停止它们,可以运行 gvm_stop。如果你遇到 OpenVAS 安装问题,值得再次运行 gvm-check-setup。安装完成后,你可以通过浏览器访问 http://127.0.0.1:9392 来使用 OpenVAS。记得,用户名是 admin,密码是你在安装过程中得到的密码。每次安装的密码都会不同,所以一定要记住并保存好自己的密码。

本地漏洞

本地漏洞需要一定程度的系统访问权限。攻击者并不是通过本地漏洞来获取访问权限,而是攻击者必须已经具备本地访问权限,才能执行具有此类漏洞的程序。利用本地漏洞的目的是通常为了获取攻击者本来无法访问的资源,这意味着它可能是一种特权提升(Privilege Escalation)攻击。

本地漏洞可能出现在系统上的任何程序中。这包括正在运行的服务——即在后台运行、无需用户直接交互的程序,通常称为守护进程(daemons)——以及用户能够访问的任何其他程序。像 passwd 这样的程序使用 setuid 标志,以允许任何用户运行该程序并获得临时的 root 权限。setuid 程序会将运行程序的用户 ID 设置为文件的所有者。这是必要的,因为更改用户密码需要修改只有 root 用户才能写入的文件。如果我想更改我的密码,我可以运行 passwd,但是由于密码数据库需要被修改,passwd 程序需要拥有 root 权限才能写入所需的文件。如果 passwd 程序存在漏洞,那么该程序在临时以 root 用户身份运行时,任何在该程序运行期间进行的漏洞利用都会获得 root 权限。

注意 具有 setuid 标志的程序启动时会以文件所有者的身份运行。通常情况下,文件的所有者是 root,因为用户需要执行一些需要 root 权限的任务,例如更改自己的密码。然而,你可以为任何用户创建 setuid 程序。不论哪个用户启动该程序,在运行时,它看起来就像是程序所有者(即磁盘上文件的所有者)在运行该程序。

使用 lynis 进行本地检查

大多数 Linux 发行版都提供了可以执行本地漏洞测试的程序,Kali 也不例外。其中一个常用的程序是 lynis,它是一款本地系统漏洞扫描工具,可以执行多个检查,检测那些在强化版操作系统安装中常见的设置。强化的操作系统通常配置为抵抗攻击,这可能包括启用日志记录、加强权限控制和选择其他安全设置。

程序 lynis 提供了多种扫描类型的设置。根据需要的深度,用户可以选择快速扫描或完整扫描。它还支持以渗透测试模式(pentest mode)运行,即无特权扫描。这种模式下,无法检查需要 root 权限的项目,比如查看配置文件。通过这种方式,您可以了解攻击者如果获得普通、无特权账户的访问权限,能够做些什么。示例 4-7 展示了运行 lynis 对基本 Kali 安装进行扫描的部分输出。

示例 4-7. lynis 执行输出

[+] Kernel
 ------------------------------------
  - Checking default run level                                [ RUNLEVEL 5 ]
  - Checking CPU support (NX/PAE)
    CPU support: PAE and/or NoeXecute supported               [ FOUND ]
  - Checking kernel version and release                       [ DONE ]
  - Checking kernel type                                      [ DONE ]
  - Checking loaded kernel modules                            [ DONE ]
      Found 120 active modules
  - Checking Linux kernel configuration file                  [ FOUND ]
  - Checking default I/O kernel scheduler                     [ NOT FOUND ]
  - Checking for available kernel update                      [ OK ]
  - Checking core dumps configuration
    - configuration in systemd conf files                     [ DEFAULT ]
    - configuration in /etc/profile                           [ DEFAULT ]
    - 'hard' configuration in /etc/security/limits.conf       [ DEFAULT ]
    - 'soft' configuration in /etc/security/limits.conf       [ DEFAULT ]
    - Checking setuid core dumps configuration                [ DISABLED ]
  - Check if reboot is needed                                 [ NO ]

[+] Memory and Processes
 ------------------------------------
  - Checking /proc/meminfo                                    [ FOUND ]
  - Searching for dead/zombie processes                       [ NOT FOUND ]
  - Searching for IO waiting processes                        [ NOT FOUND ]
  - Search prelink tooling                                    [ NOT FOUND ]

[+] Users, Groups, and Authentication
 ------------------------------------
  - Administrator accounts                                    [ OK ]
  - Unique UIDs                                               [ OK ]
  - Unique group IDs                                          [ OK ]
  - Unique group names                                        [ OK ]
  - Password file consistency                                 [ SUGGESTION ]
  - Checking password hashing rounds                          [ DISABLED ]
  - Query system users (non daemons)                          [ DONE ]
  - NIS+ authentication support                               [ NOT ENABLED ]
  - NIS authentication support                                [ NOT ENABLED ]
  - Sudoers file(s)                                           [ FOUND ]
  - PAM password strength tools                               [ SUGGESTION ]
  - PAM configuration files (pam.conf)                        [ FOUND ]
  - PAM configuration files (pam.d)                           [ FOUND ]
  - PAM modules                                               [ FOUND ]
  - LDAP module in PAM                                        [ NOT FOUND ]
  - Accounts without expire date                              [ OK ]
  - Accounts without password                                 [ OK ]
  - Locked accounts                                           [ OK ]
  - Checking user password aging (minimum)                    [ DISABLED ]
  - User password aging (maximum)                             [ DISABLED ]
  - Checking Linux single user mode authentication            [ OK ]
  - Determining default umask
    - umask (/etc/profile)                                    [ NOT FOUND ]
    - umask (/etc/login.defs)                                 [ SUGGESTION ]
  - LDAP authentication support                               [ NOT ENABLED ]
  - Logging failed login attempts                             [ ENABLED ]

从输出中可以看到,lynis 检查到了一些问题,例如可插拔认证模块(PAM)的密码强度工具存在问题,因此它提供了相应的建议。此外,它还发现了密码文件一致性方面的问题,不过要查看详细信息,需要查看具体的建议。它还发现了默认文件权限设置方面的问题,检查的是 /etc/login.defs 中的 umask 设置。工具的完整输出包含了许多其他的推荐,但这只是对系统的完整审计,且大部分是开箱即用的安装。然而,有趣的是,在本书的前一版中,运行 lynis 时发现了与单用户模式认证相关的问题。单用户模式通常用于关键的系统管理任务,期间系统不会进行任何干扰性操作(如文件系统的修改)。显然,这个问题自 Kali 的前一个版本以来已经得到解决,因为在当前版本中它不再是问题。

控制台输出提供了一个层次的详细信息,但同时会生成一个日志文件。该日志文件会保存在运行命令的用户的主目录中。更多的日志详细信息可以在 var/log/lynis.log 中找到。示例 4-8 展示了当我以普通用户身份运行 lynis 时,保存在我的主目录中的日志文件的一部分输出。这个日志文件中的输出记录了程序执行的每个步骤以及每个步骤的结果。您还会注意到,当程序发现问题时,它会在输出中指出。在 libpam-usb 的情况下,程序还给出了进一步加固操作系统的建议。

示例 4-8. lynis 执行的日志文件

2023-07-10 19:31:33 ====
2023-07-10 19:31:33 Discovered directories: /bin, /sbin, /usr/bin, /usr/sbin, 
 /usr/local/bin, /usr/local/sbin
2023-07-10 19:31:33 DEB-0001 Result: found 7981 binaries
2023-07-10 19:31:33 Status: Starting Authentication checks...
2023-07-10 19:31:33 Status: Checking if libpam-tmpdir is installed and enabled...
2023-07-10 19:31:33 ====
2023-07-10 19:31:33 Performing test ID DEB-0280 (Checking if libpam-tmpdir is installed and enabled.)
2023-07-10 19:31:33  - libpam-tmpdir is not installed.
2023-07-10 19:31:33 Hardening: assigned partial number of hardening points (0 of 2). Currently having 0 points (out of 2)
2023-07-10 19:31:33 Suggestion: Install libpam-tmpdir to set $TMP and $TMPDIR for PAM sessions [test:DEB-0280] [details:-] [solution:-]
2023-07-10 19:31:33 Status: Starting file system checks...
2023-07-10 19:31:33 Status: Starting file system checks for dm-crypt, cryptsetup & cryptmount...
2023-07-10 19:31:33 ====
2023-07-10 19:31:33 Skipped test DEB-0510 (Checking if LVM volume groups or file systems are stored on encrypted partitions)
2023-07-10 19:31:33 Reason to skip: Prerequisites not met (ie missing tool, other type of Linux distribution)
2023-07-10 19:31:33 ====
2023-07-10 19:31:33 Skipped test DEB-0520 (Checking for Ecryptfs)
2023-07-10 19:31:33 Reason to skip: Prerequisites not met (ie missing tool, other type of Linux distribution)
2023-07-10 19:31:34 Status: Starting Software checks...

这个程序可以被任何操作 Linux 系统的人定期使用,这样他们就能意识到需要修复的问题。然而,对于从事渗透测试或安全测试的人来说,您可以在获得访问权限的 Linux 系统上运行该程序。如果您与正在测试的公司合作,执行本地扫描会更容易。在这种情况下,您可能会获得对系统的本地访问权限,从而可以运行像这样的程序。当然,您需要在任何要扫描的系统上安装这个程序。在这种情况下,您不会直接在 Kali 上运行它。但通过在本地系统上运行 lynis 并查看输出,您可以获得很多使用经验。

OpenVAS 本地扫描

对于本地漏洞测试,您不仅仅局限于在本地系统上进行测试。也就是说,您不必登录到正在运行的程序才能执行测试。相反,您可以使用远程漏洞扫描器,并提供登录凭据。这将允许扫描器通过登录会话远程登录并运行扫描。在 Greenbone Security Assistant 的 web 界面中,我们将要做的大多数操作都在配置菜单中。在该菜单中,您可以配置创建扫描所需的所有基本元素。

之前我们已经安装了 OpenVAS;现在我们可以看看如何使用它进行漏洞扫描。虽然 OpenVAS 主要是一个远程漏洞扫描器,但正如您将看到的,它可以通过提供登录凭据进行本地登录。通过图 4-2 配置的登录凭据将被 OpenVAS 用来远程登录,以便通过登录会话本地运行测试。您可以选择让 OpenVAS 自动生成凭据,这样 OpenVAS 会尝试对指定的用户名进行密码暴力破解。

image.png

创建凭据只是过程的一部分。您仍然需要配置一个能够使用这些凭据的扫描任务。首先,您需要识别或创建一个包含目标操作系统本地漏洞的扫描配置。作为示例,图 4-3 显示了一个对话框,其中展示了 OpenVAS 中可用的漏洞家族的部分内容。您可以看到列出了几个包含本地漏洞的操作系统,包括 Debian 和 Ubuntu。其他操作系统也包括在内,每个漏洞家族可能包含数百个甚至数千个漏洞。

image.png

一旦选择了漏洞,您需要创建目标并应用凭据。图 4-4 显示了在 OpenVAS 中创建目标的对话框。您需要指定一个 IP 地址、一个 IP 地址范围,或一个包含目标 IP 地址列表的文件。尽管这个对话框提供了其他选项,但我们最关心的是那些用来指定凭据的选项。在这里配置的凭据将用于那些在 22 端口上运行 SSH 服务器的目标。如果您之前识别出了可能运行在非标准配置中的其他 SSH 服务器,您可以指定其他端口。除了 SSH,您还可以选择 SMB 和 ESXi 作为登录协议。

每个操作系统都是不同的,尤其是 Linux,这也是为什么 OpenVAS 中存在不同的本地漏洞家族的原因。每个发行版的配置略有不同,并且有不同的软件包集。每个软件包可能有不同的默认配置设置。除了操作系统发行版,用户还可以选择各种软件包类别。一旦基础系统安装完毕,通常可以安装数百个附加软件包,每个软件包都可能引入漏洞。

image.png

注意
一种常见的强化方法是限制安装的软件包数量。特别是对于服务器系统,应只安装操作服务所需的最少软件包。

一旦所有配置就绪,您还需要创建一个扫描任务。在“扫描”菜单下,选择“任务”。和其他页面一样,您应该会看到一个右上角带有星号的纸张图标。这是添加新配置的方式,在这个页面上,您将创建一个新的扫描任务。图 4-5 显示了创建新扫描任务的对话框。这里的关键设置是“扫描目标”和“扫描配置”下拉菜单。您需要选择已创建的目标扫描,确保其包含您的凭据。然后,选择您创建的扫描配置,该配置中已选择适合您扫描的漏洞家族。

配置好新的扫描任务后,它将出现在任务列表中。在任务配置过程中,您可以设置任务按计划运行,但如果您希望,也可以手动运行它。只需点击看起来像是横着的三角形的播放按钮即可。

image.png

Rootkit

虽然Rootkit Hunter严格来说并不是一个漏洞扫描工具,但它是值得了解的。这个程序可以在本地系统上运行,以确定系统是否已经被攻破并安装了rootkit。Rootkit是一种软件包,旨在为恶意软件提供支持。它可能包括替代操作系统的实用程序,以隐藏运行中的恶意软件的存在。例如,ps程序可能会被修改,不显示与恶意软件相关的进程。此外,ls命令可能会隐藏恶意软件文件的存在。Rootkit还可能实现一个后门,允许攻击者远程访问。

如果rootkit软件已经被安装,可能意味着某处存在漏洞被利用了。这也意味着您不希望的软件正在您的系统上运行。了解Rootkit Hunter可以帮助您扫描系统。您可能想要在任何您已运行扫描器并发现漏洞的系统上运行这个程序。这可能表明系统已经被攻破。运行Rootkit Hunter可以让您确定系统上是否安装了rootkit。

执行文件的名称是rkhunter,运行起来很简单,尽管在当前的Kali Linux发行版的默认构建中并未预安装。rkhunter会运行一系列检查,以确定是否安装了rootkit。首先,它会检查文件权限,您可以在示例4-9中看到相关示例。除此之外,rkhunter还会进行模式匹配,搜索已知rootkit的签名。就像大多数杀毒程序一样,rkhunter无法检测到它不知道的rootkit。它会查找异常情况,例如不正确的文件权限。它还会查找它已知的来自已知rootkit的文件。如果存在它不知晓的rootkit,那么这些rootkit是无法被检测到的。

示例4-9. 运行Rootkit Hunter

┌──(kilroy@badmilo)-[~]
└─$ sudo rkhunter --check
[ Rootkit Hunter version 1.4.6 ]

Checking system commands...

  Performing 'strings' command checks
    Checking 'strings' command                              [ OK ]

  Performing 'shared libraries' checks
    Checking for preloading variables                       [ None found ]
    Checking for preloaded libraries                        [ None found ]
    Checking LD_LIBRARY_PATH variable                       [ Not found ]

  Performing file properties checks
    Checking for prerequisites                              [ OK ]
    /usr/sbin/adduser                                       [ OK ]
    /usr/sbin/chroot                                        [ OK ]
    /usr/sbin/cron                                          [ OK ]
    /usr/sbin/depmod                                        [ OK ]
    /usr/sbin/fsck                                          [ OK ]
    /usr/sbin/groupadd                                      [ OK ]
    /usr/sbin/groupdel                                      [ OK ]
    /usr/sbin/groupmod                                      [ OK ]
    /usr/sbin/grpck                                         [ OK ]

与lynis一样,这也是一个软件包;您需要在要审核的系统上安装Rootkit Hunter,才能检测恶意软件。您不能从Kali实例中远程运行它。如果您在Kali实例中进行大量的测试和漏洞利用,定期检查自己的系统是个不错的主意。每次您运行来自不完全信任的来源的软件时(如果您在处理概念验证漏洞时可能会遇到这种情况),都应该检查系统是否存在病毒和其他恶意软件。是的,这一点对Linux平台和其他平台同样适用。Linux并非免疫于攻击或恶意软件。最好保持您的系统尽可能干净和安全。

远程漏洞

虽然有时通过与目标紧密合作,您可能会被授权访问系统,但在进行安全测试时,您肯定需要对远程漏洞进行检查。当您获得完整的访问权限时,这可能包括测试用的凭证、可以审计而不影响用户的桌面构建,或来自网络设备的配置设置,这时您正在进行明确盒子测试(clear-box testing)。如果您与目标没有合作,除了与他们达成明确协议,告知您的测试计划,您则是在进行不透明盒子测试(opaque-box testing);这时,您对测试的内容一无所知。您也可能进行灰盒测试(gray-box testing)。灰盒测试介于明确盒子和不透明盒子之间,虽然两者之间还有很多不同的层次。

在测试远程漏洞时,提前准备是非常有用的。您需要使用漏洞扫描工具。虽然OpenVAS并不是唯一可用的漏洞扫描器,但它是免费的,并且包含在Kali Linux的仓库中。这应该视为漏洞测试的起点。如果只需要运行一个扫描器,任何人都可以做到。运行漏洞扫描器并不难,做安全测试的价值不在于加载一堆自动化工具,而在于对结果的解释和验证,以及超越自动化工具的使用。最困难的部分是理解扫描器的输出,并能够判断发现的漏洞是否真实,以及漏洞的实际优先级。

之前,我们探讨了如何使用OpenVAS进行本地扫描。它同样可以用于扫描远程漏洞,事实上,这也是它更为人熟知的用途。接下来我们将花一些时间来查看这一部分。OpenVAS是一个功能较为复杂的软件,所以我们将简要概述其一些功能,而不是提供全面的概述。重要的是了解漏洞扫描器的工作原理。

注意
如前所述,OpenVAS项目起源于Nessus从Nessus项目分支出来。从那时起,OpenVAS在架构设计上经历了显著的变化。尽管Nessus现在也采用了Web界面,但无论在界面还是底层扫描器架构方面,OpenVAS与Nessus已经没有任何相似之处。

使用OpenVAS或任何漏洞扫描器时,它都会有一个已知漏洞的集合或数据库。这个集合应该像杀毒程序一样定期更新。当您设置OpenVAS时,首先会下载当前的漏洞定义集合。如果您让系统定期运行OpenVAS服务,您的漏洞定义会自动更新。如果您在一段时间内没有运行OpenVAS,并且想要进行扫描,确保所有签名都已更新是很重要的。您可以通过命令行使用命令greenbone-nvt-sync来做到这一点。这个命令需要由为OpenVAS创建的_gvm用户来运行。为此,您可以使用命令sudo -u _gvm greenbone-nvt-sync来执行命令。这将使用指定的用户来运行命令。OpenVAS使用安全内容自动化协议(Security Content Automation Protocol,SCAP)来交换安装内容与远程服务器上存储的内容。

OpenVAS使用Web界面,类似于今天很多应用程序的做法。要访问Web应用程序,您需要前往https://localhost:9392。登录后,您将看到一个仪表盘。仪表盘展示了与您任务相关的图表,以及它所知道的漏洞信息和它们的严重性。在图4-6中,您可以看到一个打开的仪表盘页面。您可以看到任务的数量(这是一个新的安装,因此只有一个任务),以及显示数据库中漏洞的图表。

image.png

功能和操作的菜单位于页面顶部。从那里,您可以访问与扫描、资产和配置相关的功能,还可以查看OpenVAS已知的安全信息库,其中包括它所知的所有漏洞。

OpenVAS 快速入门

虽然OpenVAS无疑是一个功能强大的软件,提供了大量的自定义选项,但它也提供了一种简单的方式来快速入门。扫描向导(Scan Wizard)让您只需提供目标即可开始扫描。如果您想快速了解目标可能存在的常见漏洞,这是一个很好的起点。使用向导进行简单扫描时,将使用默认设置,这是一种快速启动的方式。要使用向导开始,您需要进入“扫描(Scans)”菜单并选择“任务(Tasks)”。在该页面的左上方,您将看到一些小图标。紫色的图标,像一个魔杖,点击后将打开任务向导(Task Wizard)。图4-7显示了当您将光标悬停在该图标上时弹出的菜单。

image.png

从该菜单中,您可以选择“高级任务向导(Advanced Task Wizard)”,该向导可以让您更好地控制资产、凭据和其他设置。您还可以选择“任务向导(Task Wizard)”,如图4-8所示。使用任务向导时,系统会提示您输入目标IP地址。当打开该向导时,填充的IP地址是您当前连接到服务器的主机的IP地址。在这里,您不仅可以输入单个IP地址,还可以输入整个网络范围,如图4-8所示。例如,我会使用192.168.1.0/24。这是从192.168.1.0到192.168.1.255的整个网络范围。/24是一种指定网络范围的方式,无需使用子网掩码或范围表示法。您会经常看到这种表示法,它通常被称为CIDR表示法(Classless Inter-Domain Routing)。

image.png

一旦您输入了目标IP地址或目标地址范围,您只需点击“开始扫描(Start Scan)”,OpenVAS就会开始执行扫描,可以说是启动了您的第一次漏洞扫描。这是启动扫描的最简单方法,但您无法控制扫描的类型,甚至无法控制扫描何时运行。要实现这些,我们需要使用“高级扫描向导(Advanced Scan Wizard)”。

提示:
在运行扫描时,拥有一些易受攻击的系统可能会很有用。虽然您可以通过搜索各种易受攻击的操作系统来找到它们,但有一个系统特别有用:Metasploitable 2是一个故意设置为易受攻击的Linux安装版本。Metasploitable 3是基于Windows Server 2008的更新版本,但也有一个基于Ubuntu的Metasploitable 3版本。Metasploitable 2可以直接下载,而Metasploitable 3则需要您在自己的系统上构建。它需要VirtualBox和额外的软件。

我们可以通过查看图4-9中的“高级扫描向导”,来了解在使用向导帮助设置所有值时,您可以访问的更广泛的配置设置。这将为我们后续从头到尾创建扫描任务提供一个快速的预览。

image.png

创建扫描任务

如果您希望对扫描过程有更多的控制权,您需要执行一些额外的步骤。有几个地方可以开始,因为在开始扫描之前,您需要配置多个组件。一个简单的起点是与我们设置本地扫描时相同的界面位置。您需要先建立目标。如果您希望将本地扫描作为整体扫描的一部分,您可以像之前那样设置凭据,进入“配置(Configuration)”菜单并选择“凭据(Credentials)”。一旦设置了所需的凭据,您可以前往“配置/目标(Configuration/Targets)”来访问对话框,从中指定目标。

在这里,您可以添加或配置所需的凭据,并设置目标。接下来,您需要考虑要执行的扫描类型。这时,您需要进入“扫描配置(Scan Configs)”,也位于“配置”菜单下。这是我们在“本地漏洞”部分快速查看过的内容。OpenVAS提供了内置的扫描配置,您可以在图4-10中看到这个列表。这些是预设的配置,您无法对其进行修改。如果您需要与这些预设扫描不同的配置,您可以克隆其中一个并进行编辑,或者创建您自己的扫描配置。

image.png

当您想要创建自己的扫描配置时,可以从空白配置开始,或者选择“完整与快速配置”。一旦决定了起点,您就可以开始选择要包含在扫描配置中的扫描类别。此外,您还可以调整扫描器的行为。在图4-11中,您可以看到一系列配置设置,这些设置会改变扫描的执行方式和它使用的位置。特别要注意的是“安全检查(Safe Checks)”设置。该设置表示只运行已知安全的检查,意味着这些检查不太可能对目标系统造成问题。这确实意味着某些检查不会被执行,可能正是那些测试您最关心的漏洞的检查。毕竟,如果只是探测一个漏洞就能引起远程系统的问题,这一点应该事先与您合作的公司沟通清楚。

漏洞扫描器并不打算利用漏洞。然而,仅仅通过测试软件的反应也足以导致应用崩溃。对于操作系统而言,就像网络堆栈问题一样,您可能会面临操作系统崩溃并造成拒绝服务的情况,即便这并非您想要的结果。这是一个需要确保与测试方提前沟通清楚的领域。如果他们期望进行无故障的测试,并且您是在与他们合作进行测试,那么您需要明确告知,即便您并非故意引发故障,系统崩溃也是有可能发生的。安全检查是一个需要小心使用的设置,您在禁用它时需要非常清楚自己正在做什么。禁用安全检查会禁用那些可能对远程服务造成损害的测试,例如,可能会使远程服务停用的测试。

image.png

虽然您还可以调整其他设置,但在设置好扫描配置和目标后,您就可以开始扫描了。在开始之前,您可能想要考虑设置一些调度。这样可以帮助您在非工作时间进行测试,尤其是当您与公司合作时进行安全测试或渗透测试时,您可能希望监控扫描过程。然而,如果这是一个常规扫描,您可能希望将其设置为在夜间运行,以免影响公司日常运营。虽然您可能不会影响正在运行的服务或系统,但会产生网络流量并消耗系统资源。如果在业务正常运行时执行扫描,这可能会产生影响。

假设您已经完成了配置,并希望开始执行已经设置好的扫描。在这里,您需要进入“扫描”菜单并选择“任务”。然后点击“新任务”图标,弹出一个对话框,如图4-12所示。在这个对话框中,您为任务命名,这样就会显示额外的选项,然后您可以选择目标和扫描配置。如果您已经创建了调度任务,还可以选择一个调度。

在我们的简单安装中,我们只能选择一个扫描器使用,这就是我们 Kali 系统上的扫描器。在更复杂的设置中,您可能会有多个扫描器可以选择,并且可以通过一个界面来管理所有扫描器。您还可以选择运行扫描的网络接口。虽然通常这会通过系统的路由表来处理,您也可以指定一个特定的源接口。如果您希望所有流量从一个IP地址范围发出,而从另一个接口进行管理,这可能会很有用。

image.png

最后,您可以选择将报告存储在 OpenVAS 服务器中。您可以指定要存储的报告数量,以便能够将一个扫描结果与另一个进行比较,从而展示进展。最终,所有测试的目标,包括漏洞扫描,都是为了提高目标系统的安全态势。如果组织收到了您的建议,却没有采取任何措施,这比根本不进行扫描更糟。当您向组织提交报告时,他们会意识到您发现的漏洞。如果他们不采取行动,这些信息可能会被攻击者利用。

OpenVAS报告

报告是您工作中最重要的部分。完成测试后,您将编写自己的报告,但从漏洞扫描器中发出的报告有助于您了解应该从哪里开始查找。您在查看漏洞扫描报告时应注意两点:

首先,漏洞扫描器使用特定的签名来确定漏洞是否存在。这可能是通过横幅抓取(banner grabbing)来比较版本号等方法。您不能仅凭 OpenVAS 这样的工具确定漏洞的存在,因为它并不会实际利用漏洞。其次,与此相关,您可能会遇到误报(false positives)。误报是指扫描工具错误地报告漏洞存在,而实际上漏洞并不存在。由于漏洞扫描器不会利用漏洞,它能做的仅仅是给出一个概率。

如果您没有使用凭据运行扫描,您将错过检测到许多漏洞,并且更容易产生误报。这就是为什么仅依赖 OpenVAS 或任何其他扫描器的报告是不够的原因。由于没有保证漏洞实际存在,您需要验证报告,以确保最终报告中呈现的是需要修复的真正漏洞。

不过,不必再多说这些警告了。让我们继续查看报告,开始判断哪些问题是真正需要关注的,哪些可能不那么严重。首先,在扫描完成后,我们需要返回到 OpenVAS 的 Web 界面。对大型网络和包含许多服务的网络进行扫描可能非常耗时,特别是当您进行深度扫描时。在“扫描”菜单中,您将找到“报告”选项。点击后,您将进入报告仪表板。在这里,您可以查看所有已执行的扫描列表以及扫描结果的严重性图表。您可以在图4-13中看到报告仪表板的界面。

image.png

当您选择想要查看报告的扫描时,您将看到一个包含所有发现漏洞的列表。当我使用“报告”这个词时,它可能听起来像是我们在谈论一个实际的文档,您确实可以获取这样的文档,但实际上我们真正需要的是漏洞发现的列表及其详细信息。我们可以通过 Web 界面和文档一样轻松地获取这些信息。我个人通常发现,能够在列表和详细信息之间来回点击查看更为方便。当然,您的使用习惯可能会有所不同,这取决于您最舒服的方式。图 4-14 显示了我网络扫描后得出的漏洞列表。我喜欢留下一些易受攻击的系统,供演示和实验使用。如果所有系统都保持最新,可能就没有什么值得我们看的漏洞了。

image.png

在漏洞列表中,您会看到八个列。它们中的一些列非常直观,应该容易理解。漏洞和严重性列应该是显而易见的。漏洞是对发现的简短描述。严重性则值得进一步探讨。这一评估是基于漏洞被利用可能带来的影响。然而,漏洞扫描器提供的严重性评估存在一个问题,那就是它没有考虑到其他因素。它只知道与该漏洞相关的严重性,而忽略了任何可能已经采取的减轻措施,这些措施可能限制了漏洞的暴露程度。此时,了解环境的全貌就显得非常重要。例如,假设一个 Web 服务器存在 PHP 漏洞(PHP 是一种用于 Web 开发的编程语言)。但该网站可能已配置了双重身份验证,并且在本次扫描中可能仅为特定访问授予权限。这意味着只有经过身份验证的用户才能访问该网站并利用该漏洞。

并不是因为已经采取了减轻措施以减少问题对组织的总体影响,就意味着可以忽略这些问题。这仅仅意味着攻击者的入侵门槛更高,并不代表漏洞不可能被利用。经验和对环境的良好理解将帮助您更准确地判断问题。目标不应该是吓唬人,而是要提供一个合理的预期,说明在面对攻击暴露的风险时,组织的现状如何。与组织的合作理想情况下会帮助他们提升整体的安全态势。

接下来要谈的是 QoD(检测质量)列。如前所述,漏洞扫描器无法绝对确定漏洞是否存在。QoD 评分表示扫描器对漏洞存在的信心程度。评分越高,扫描器的信心越强。如果一个漏洞具有高 QoD 和高严重性,这通常是一个应该被调查的漏洞。举个例子,图 4-15 中展示的一个发现项,它的 QoD 为 97%,严重性为 10,这是扫描器给出的最高严重性。OpenVAS 将此视为一个严重问题,并且认为它已被确认。可以通过从被测试系统获得的输出数据来验证这一点。

image.png

每个发现都会告诉您漏洞是如何被检测到的。在这个案例中,OpenVAS 访问了本地系统,并检查了安装的包列表。OpenVAS 识别出安装的版本存在一个开发者已经披露的开放漏洞。为了验证这一点,您可以查看 CVE 报告,您还可以查看安装的包列表以验证安装的版本号。最后,可能最重要的是,您可以查看由 Canonical(Ubuntu 背后的公司)提供的安全建议。在某些情况下,可能已经采取了减轻措施来限制漏洞的暴露,尽管应用程序仍然使用与上游包维护者提供的相同版本号。

当您从某些服务获得结果时,尽量手动重复这些漏洞是值得尝试的。这时,您可能需要将日志记录调到最高。您可以通过进入扫描器首选项并启用“记录整个攻击”来实现。您还可以查看目标应用程序的应用日志,了解实际执行了什么。重复攻击并在有用的方式上进行修改是很重要的。您可能会从监听服务或(如果是 Web 应用)应用程序或应用程序服务器中获得错误消息。您可能会得到低质量的检测结果,这些结果可能仍然很严重,需要手动验证。

如果您需要帮助进行额外的研究和验证,漏洞发现中会列出资源链接。这些网页将提供更多关于漏洞的详细信息,帮助您理解攻击过程,以便您进行复制。这些资源通常会指向漏洞的公告,也可能提供供应商关于修复或临时解决方法的详细信息。

另一个需要查看的列是图 4-14 中的第二列,它只标有一个图标。这一列指示了解决方案类型。解决方案可能包括临时解决方法、供应商修复或缓解措施。每个漏洞发现将提供有关可能的临时解决方法或修复的附加详情。检测到的其中一个漏洞是 SMTP 服务器的某些功能,攻击者可能通过这些功能获取电子邮件地址的信息。图 4-16 显示了其中一个漏洞发现及其解决方案。此解决方案是供应商修复。具体来说,修复方法是将已安装的软件更新到最新版本。您也可能会在已识别的漏洞中找到临时解决方法,相关的解决方法将会被文档化。

image.png

最后需要查看的列是“主机”和“位置”列。主机列告诉您哪个系统存在漏洞,这一点很重要,因为您的组织需要知道该在哪个系统上进行配置工作。位置列则告诉您目标服务运行的端口,这可以帮助您确定应该将额外的测试定位到哪里。当您向组织提供详细信息时,受影响的系统非常重要,我在为客户编写报告时,通常会包括这些信息,并列出任何可能的缓解措施或修复方法。

网络设备漏洞

OpenVAS 可以测试网络设备。如果您的网络设备可以通过您正在扫描的网络访问,那么它们可能会被 OpenVAS 触及,OpenVAS 能够识别设备类型并应用适当的测试。然而,Kali 中还包含了一些特定于网络设备和厂商的程序。由于 Cisco 是常见的网络设备厂商,开发针对这些设备的工具和漏洞利用代码的可能性较大。Cisco 在路由和交换设备领域占有主导市场份额,因此这些设备成为了攻击的良好目标。

网络设备通常通过网络进行管理。管理可以通过 Web 界面使用 HTTP(S) 协议,或通过像 SSH 这样的协议在控制台上进行,Telnet 虽然远不如 SSH 安全,但仍然是一个远程管理的可能方式。一旦设备连接到网络,它就有可能被利用。借助 Kali 中的工具,您可以开始识别网络基础设施中潜在的漏洞。

审计设备

首先,我们将使用一个工具对网络中的 Cisco 设备进行基本审计。Cisco 审计工具(CAT)用于尝试登录您提供的设备。它会根据提供的字典列表尝试登录。使用此工具的缺点是,它使用 Telnet 而不是更常见于安全网络中的 SSH 来尝试连接。Telnet 的管理可以被拦截并以明文方式读取,因为它是以明文传输的。由于网络设备管理通常会涉及密码,因此更常用的是像 SSH 这样的加密协议进行管理。

注意: 本节中的许多工具默认情况下不会安装在 Kali 中。这些软件包是可用的,但在您第一次运行它们时,它们可能并没有预安装。幸运的是,Kali 通常会发现您要执行的操作,并建议安装所需工具的包。您可以提前安装这些工具,或者直接尝试运行工具,让 Kali 帮助您安装它。

CAT 还可以通过简单网络管理协议(SNMP)来调查系统。CAT 使用的 SNMP 版本已经过时,但这并不意味着某些设备仍然使用过时版本的协议。SNMP 可以用来收集关于设备配置和系统状态的信息。旧版 SNMP 使用社区字符串进行身份验证,而这些字符串是以明文形式提供的,因为 SNMP 第一个版本没有加密功能。CAT 使用潜在社区字符串的字典列表,尽管长期以来,读权限的社区字符串通常是公开的,而读写权限的社区字符串是私有的。如果系统的配置没有更改,您需要提供这些默认的社区字符串。

CAT 是一个非常易于运行的程序。它是一个 Perl 脚本,调用了针对 SNMP 和暴力破解的各个模块。正如我之前提到的,它需要您提供目标主机。您可以提供一个单一的主机,也可以提供包含多个主机的文本文件。示例 4-10 展示了 CAT 的帮助输出以及如何将其用于扫描 Cisco 设备。

示例 4-10. CAT 输出

┌──(kilroy@badmilo)-[/etc/default]
└─$ CAT

Cisco Auditing Tool - g0ne [null0]
Usage:
        -h hostname     (for scanning single hosts)
        -f hostfile     (for scanning multiple hosts)
        -p port #       (default port is 23)
        -w wordlist     (wordlist for community name guessing)
        -a passlist     (wordlist for password guessing)
        -i [ioshist]    (Check for IOS History bug)
        -l logfile      (file to log to, default screen)
        -q quiet mode   (no screen output)

程序 cisco-torch 可以用来扫描 Cisco 设备。与 CAT 的不同之处在于,cisco-torch 可以用来扫描是否有开放的 SSH 端口/服务。此外,Cisco 设备可以从简单文件传输协议(TFTP)服务器存储和检索配置。cisco-torch 可以用于指纹识别 TFTP 和网络传输协议(NTP)服务器。这有助于识别与 Cisco Internetwork Operating System (IOS) 设备以及支持这些设备的基础设施相关的设备。IOS 是 Cisco 在其路由器和企业交换机上使用的操作系统。示例 4-11 展示了对本地网络的扫描,目标是寻找 Telnet、SSH 和 Cisco Web 服务器。这些协议都可以用于远程管理 Cisco 设备。

注意:
Cisco 的 IOS 系统已经使用了几十年。IOS 不应与 iOS 混淆,iOS 是苹果公司为其移动设备开发的操作系统。

示例 4-11. cisco-torch 输出

┌──(kilroy@badmilo)-[~]
└─$ cisco-torch -t -s -w 192.168.1.0/24
Using config file torch.conf...
Loading include and plugin ...

###############################################################
#   Cisco Torch Mass Scanner                   #
#   Because we need it...                                      #
#   http://www.arhont.com/cisco-torch.pl                      #
###############################################################

List of targets contains 256 host(s)
Will fork 50 additional scanner processes
Range Scan from 192.168.1.0 to 192.168.1.5
528028: Checking 192.168.1.0 ...
HUH db not found, it should be in fingerprint.db
Skipping Telnet fingerprint
Range Scan from 192.168.1.48 to 192.168.1.53
528036: Checking 192.168.1.48 ...
Range Scan from 192.168.1.24 to 192.168.1.29
528032: Checking 192.168.1.24 ...
HUH db not found, it should be in fingerprint.db
HUH db not found, it should be in fingerprint.db
Skipping Telnet fingerprint
Range Scan from 192.168.1.30 to 192.168.1.35
Skipping Telnet fingerprint
Range Scan from 192.168.1.72 to 192.168.1.77
528040: Checking 192.168.1.72 ...
528033: Checking 192.168.1.30 ...
HUH db not found, it should be in fingerprint.db
Range Scan from 192.168.1.66 to 192.168.1.71
528039: Checking 192.168.1.66 ...
Skipping Telnet fingerprint
HUH db not found, it should be in fingerprint.db
Skipping Telnet fingerprint
Range Scan from 192.168.1.84 to 192.168.1.89
528042: Checking 192.168.1.84 ...

Cisco 设备有已知的漏洞。这并不意味着 Cisco 或其开发者存在问题,而是因为这些设备具有大量复杂的代码,并且它们长时间以来一直是网络设备领域中常见的选择。正如往常一样,攻击者会花时间寻找常用系统中的漏洞。运行网络扫描或使用其他工具来识别网络中的 Cisco 设备是一回事,但在某些时候,您也需要识别设备中的漏洞。因此,我们需要能够识别网络中设备的漏洞。幸运的是,除了使用 OpenVAS 进行漏洞扫描(它也能查找像 Cisco 这样的网络设备漏洞),Kali 还附带了一个 Perl 脚本,用于查找与 Cisco 设备相关的漏洞。这个脚本叫做 cge.pl,它知道与 Cisco 设备相关的特定漏洞。示例 4-12 显示了可以通过 cge.pl 测试的漏洞列表,以及如何运行这个脚本,该脚本需要目标设备和漏洞编号作为输入。

示例 4-12. 运行 cge.pl 进行 Cisco 漏洞扫描

┌──(kilroy@badmilo)-[~]
└─$ cge.pl

Usage :
perl cge.pl <target> <vulnerability number>

Vulnerabilities list :
[1] - Cisco 677/678 Telnet 缓冲区溢出漏洞
[2] - Cisco IOS 路由器拒绝服务漏洞
[3] - Cisco IOS HTTP 身份验证漏洞
[4] - Cisco IOS HTTP 配置任意管理员访问漏洞
[5] - Cisco Catalyst SSH 协议不匹配拒绝服务漏洞
[6] - Cisco 675 Web 管理拒绝服务漏洞
[7] - Cisco Catalyst 3500 XL 远程任意命令漏洞
[8] - Cisco IOS 软件 HTTP 请求拒绝服务漏洞
[9] - Cisco 514 UDP 洪水拒绝服务漏洞
[10] - CiscoSecure ACS for Windows NT Server 拒绝服务漏洞
[11] - Cisco Catalyst 内存泄漏漏洞
[12] - Cisco CatOS CiscoView HTTP 服务器缓冲区溢出漏洞
[13] - 0 编码 IDS 绕过漏洞 (UTF)
[14] - Cisco IOS HTTP 拒绝服务漏洞

另一个需要关注的 Cisco 工具是 cisco-ocs。这是另一个 Cisco 扫描器,但它不需要任何参数即可执行测试。您无法选择 cisco-ocs 做什么,它会自动执行。您只需要提供地址范围。示例 4-13 展示了 cisco-ocs 的运行情况。在提供了地址范围、开始和结束 IP 后,工具会开始逐一测试每个地址,寻找入口点和潜在漏洞。

示例 4-13. 运行 cisco-ocs

┌──(kilroy@badmilo)-[~]
└─$ cisco-ocs 192.168.1.1 192.168.1.254
********************************* OCS v 0.2 ******************************
****                                                                  ****
****                           coded by OverIP                        ****
****                           overip@gmail.com                       ****
****                           under GPL License                      ****
****                                                                  ****
****             usage: ./ocs xxx.xxx.xxx.xxx yyy.yyy.yyy.yyy         ****
****                   xxx.xxx.xxx.xxx = 范围起始 IP                   ****
****                    yyy.yyy.yyy.yyy = 范围结束 IP                ****
****                                                                  ****
**************************************************************************

(192.168.1.1) 过滤端口

(192.168.1.2) 过滤端口

从这些工具可以看到,多个程序都在寻找 Cisco 设备和潜在漏洞。如果您能够找到这些设备,并且它们显示出开放的端口用于测试登录,或者更糟糕的是,显示出漏洞,那么绝对值得标记它们为需要寻找漏洞利用的设备。这并不是说 Cisco 设备是唯一可用的网络设备,但它们已经存在了足够长的时间,且全球有足够多的设备安装,使得它们成为工具开发的一个有吸引力的目标。随着更多像 Palo Alto Networks 等公司获得更多的市场份额,您可以预期,扫描它们并识别漏洞的开源工具将会变得更加普遍。

数据库漏洞

数据库服务器通常包含大量敏感信息,尽管它们通常部署在隔离的网络中。然而,情况并非总是如此。有些组织可能认为通过将数据库隔离起来就能保护它,这种想法是错误的。如果攻击者能够突破 Web 服务器或应用服务器,这两个系统可能与数据库之间存在可信连接,这就暴露了大量的信息。无论系统位于何处,组织都应该确保严格锁定其数据库,并修复任何发现的漏洞。

Oracle 是一家大型公司,其业务建立在企业级数据库上。如果某家公司需要存储大量敏感信息的数据库,它很可能会选择 Oracle。Kali 中安装的 oscanner 程序可以扫描 Oracle 数据库以执行检查。该程序使用插件架构来测试 Oracle 数据库,包括尝试获取数据库服务器的安全标识符(SIDs)、列出账户、破解密码以及执行其他攻击。oscanner 是用 Java 编写的,因此它应该能够在多个操作系统上移植使用。

oscanner 还附带了多个列表,包括账户、用户和服务的列表。虽然这些文件中的可能性不多,但它们是攻击 Oracle 数据库的起点。与许多其他工具一样,随着使用的深入,您会逐步收集自己的服务标识符、用户和潜在密码。您可以将这些数据添加到文件中,以便更好地测试 Oracle 数据库。随着您测试的系统和网络越来越多,您应该不断增加用于执行检查的数据选项。随着时间的推移,这将增加成功的可能性。请记住,当您使用用户名和密码的词汇表进行测试时,只有当系统上配置的用户名或密码与词汇表中的某一项完全匹配时,您才会成功。

识别新漏洞

软件存在缺陷,这是不可避免的。特别是大型软件,它的复杂性越高,出错的几率就越大。想想在程序运行过程中做出的所有选择。如果你开始计算程序中的所有可能执行路径,你会迅速得出一个庞大的数字。软件测试时,有多少完整的执行路径得到了测试呢?很可能,测试的只是这些路径的一个子集。即便所有执行路径都在测试,那么到底测试了哪些输入呢?

一些软件测试可能专注于功能性测试。这是为了验证所指定的功能是否正确。你可以通过正向测试来实现这一点——确保预期的结果确实发生了。也可能有一些负向测试:你需要确保程序在遇到意外情况时能够优雅地失败。正是这种负向测试很难完成,因为如果你有一组预期数据,这只是与程序运行过程中所有可能发生的情况相比的一个部分,尤其是当程序在某个时刻需要用户输入时。

边界测试发生在你测试预期输入的边界时。你测试最大或最小值的边界以及最大或最小值之外的输入,检查程序是否正确处理这些输入并是否发生错误。

向应用程序发送它们不期望的数据是一种识别程序漏洞的方法。你可能会收到提供有用信息的错误消息,或者可能会导致程序崩溃。实现这一点的一种方法是使用一种称为模糊测试(fuzzing)的应用程序。模糊测试工具生成随机或可变的数据来提供给应用程序。输入数据是基于一组规则程序生成的。

注意
模糊测试可能被一些人视为不透明盒测试,因为模糊测试程序不了解服务应用程序的内部工作原理。它发送的数据无论程序期望输入是什么样子。即使你有源代码,你也不是基于源代码的外观来开发模糊测试的测试。换句话说,尽管你有源代码,从这个角度看,应用程序就像一个不透明的盒子。

Kali 自带了一些模糊测试工具,还有更多可以安装的工具。首先要看的是 sfuzz,它用于向服务器发送网络流量。sfuzz 有一系列规则文件,告诉程序如何创建发送的数据。这些规则文件有些是基于特定协议的。例如,示例 4-14 展示了如何使用 sfuzz 向电子邮件服务器发送 SMTP 流量。-T 标志表示我们使用 TCP,-s 标志表示我们将进行序列模糊测试而不是字面模糊测试,-f 标志指定使用 /usr/share/sfuzz-db/basic.smtp 文件作为模糊测试的数据源。最后,-S-p 标志分别表示目标的 IP 地址和端口。

示例 4-14:使用 sfuzz 对 SMTP 服务器进行模糊测试

┌──(kilroy@badmilo)-[~]
└─$ sudo sfuzz -T -s -f /usr/share/sfuzz-db/basic.smtp -S 127.0.0.1 -p 25
[17:37:30] dumping options:
        filename: </usr/share/sfuzz-db/basic.smtp>
        state:    <8>
        lineno:   <14>
        literals:  [30]
        sequences: [31]
        symbols: [0]
        req_del:  <200>
        mseq_len: <50050>
        plugin: <none>
        s_syms: <0>
<-- snip -->
[17:37:30] info: beginning fuzz - method: tcp, config from: ↩
[/usr/share/sfuzz-db/basic.smtp], out: [127.0.0.1:25]
[17:37:30] attempting fuzz - 1 (len: 50057).
[17:37:30] info: tx fuzz - (50057 bytes) - scanning for reply.
[17:37:30] read:
220 badmilo.washere.com ESMTP Postfix (Debian/GNU)
250 badmilo.washere.com

 ========================================================================
[17:37:30] attempting fuzz - 2 (len: 50057).
[17:37:30] info: tx fuzz - (50057 bytes) - scanning for reply.
[17:37:30] read:
220 badmilo.washere.com ESMTP Postfix (Debian/GNU)
250 badmilo.washere.com

 ========================================================================
[17:37:30] attempting fuzz - 3 (len: 50057).
[17:37:30] info: tx fuzz - (50057 bytes) - scanning for reply.
[17:37:30] read:
220 badmilo.washere.com ESMTP Postfix (Debian/GNU)
250 badmilo.washere.com

 ========================================================================
[17:37:30] attempting fuzz - 4 (len: 50057).
[17:37:30] info: tx fuzz - (50057 bytes) - scanning for reply.
[17:37:31] read:
220 badmilo.washere.com ESMTP Postfix (Debian/GNU)
250 badmilo.washere.com

 ========================================================================
[17:37:31] attempting fuzz - 5 (len: 50057).
[17:37:31] info: tx fuzz - (50057 bytes) - scanning for reply.
[17:37:31] read:
220 badmilo.washere.com ESMTP Postfix (Debian/GNU)
250 badmilo.washere.com

 =========================================================================

使用模糊攻击的一个问题是它们可能导致程序崩溃。虽然这正是模糊测试的目标,但问题在于如何确定程序是否真的崩溃了。当然,你可以手动操作,通过在调试器会话中运行测试程序,这样调试器就能捕获到崩溃。这个方法的问题是,可能很难知道是哪一个测试用例导致了崩溃。尽管发现一个bug是好事,但仅仅获得一个程序崩溃并不足以识别漏洞或创建能够利用漏洞的攻击。毕竟,bug不一定就是漏洞,它可能只是一个错误。

可以使用软件包将程序监控与应用程序测试结合起来。你可以使用像 valgrind 这样的程序来对应用程序进行分析。示例 4-15 展示了如何使用 valgrindmemcheck 工具启动一个 POP3 服务器,检查内存泄漏。

示例 4-15:使用 valgrind 检查内存泄漏

┌──(kilroy@badmilo)-[~]
└─$ sudo valgrind --tool=memcheck popa3d
==552080== Memcheck, a memory error detector
==552080== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==552080== Using Valgrind-3.19.0 and LibVEX; rerun with -h for copyright info
==552080== Command: popa3d
==552080==
+OK

一旦你用 valgrind 启动了服务,你就可以运行像 sfuzz 这样的工具进行测试,看看是否能发现内存泄漏。当然,valgrind 除了 memcheck 之外,还包含其他功能,你可以利用它们对应用程序进行分析。使用像 valgrind 这样的工具面临的挑战是,它要求被调用的程序保持运行。许多服务需要以守护进程模式运行,这意味着从你运行它的终端的角度来看,它看起来是干净地终止的。被调用的程序反过来又会调用另一个程序,但实际上是被调用的程序在被 valgrind 监视。一旦该程序停止运行,valgrind 就没有东西可以监视了。valgrind 也有一些选项可以让它跟踪子进程,在这种情况下能提供帮助。尽管如此,valgrind 这个工具仍然能为你提供在进行应用程序测试时对程序的深入了解。

在某些情况下,你可能会遇到针对特定应用程序或协议的程序。比如,sfuzz 是一个通用的模糊测试工具,可以针对多个协议进行攻击,而像 protos-sip 这样的程序则专门设计用于测试会话发起协议(SIP),SIP 是 VoIP 实现中常用的一种协议。protos-sip 包是一个 Java 应用程序,它作为一个研究项目的一部分开发。这个研究最终转化为了一家公司,专门销售用于模糊测试网络协议的软件。

并不是所有的应用程序都是监听网络输入的服务。许多应用程序以文件的形式接收输入。即使像 sfuzz 这样的工具,它也接收文件形式的定义作为输入。毫无疑问,文字处理、电子表格、演示文稿等程序以及各种类型的软件都使用文件。一些模糊测试工具是专门为测试接受文件作为输入的应用程序而开发的。

其中一个可以用来进行更广泛模糊测试的程序是 zzuf。这个程序能够操控输入数据,向程序提供意外的数据。示例 4-16 展示了如何使用 zzufpdf-parser 程序进行模糊测试,pdf-parser 是一个 Python 脚本,用于从 PDF 文件中提取信息。在这里,我们将 pdf-parser 程序作为命令行参数传递给 zzuf,并告知 zzuf 执行的操作。然而,这个程序有一个挑战,它是一个较老的工具,因此并没有经过与更新版 Python 的兼容性测试,运行时可能会出现一些错误。

示例 4-16:使用 zzuf 对 pdf-parser 进行模糊测试

┌──(kilroy@badmilo)-[~]
└─$ zzuf -s 0:10 -c -C 0 -T 3 pdf-parser -a fuzzing.pdf
This program has not been tested with this version of Python (3.11.4)
Should you encounter problems, please use Python version 3.11.1
Comment: 151
XREF: 1
Trailer: 1
StartXref: 1
Indirect object: 1
Indirect objects with a stream:
  1: 2020
Unreferenced indirect objects: 2020 2 R
This program has not been tested with this version of Python (3.11.4)
Should you encounter problems, please use Python version 3.11.1
Comment: 56
XREF: 0
Trailer: 1
StartXref: 0
Indirect object: 32
Indirect objects with a stream: 2022, 2030, 2033, 2034, 2037, 2040, 2, 6, 9, 11, 
12, 14, 16, 18, 20, 21
  15: 2022, 2021, 2033, 2034, 2036, 2037, 2040, 2, 3, 5, 12, 18, 24, 26, 27
 /EztGState 1: 2029
 /Font 2: 2025, 2026
 /FontDescrip4or 1: 2027
 /OCG 1: 2123
 /OCMD 1: 2030
 /ObjStm 7: 6, 9, 14, 16, 17, 20, 21
 /OâjStm 1: 11
 /Page 1: 2024
 /Pages 1: 25
 /XRef 1: 2041
Unreferenced indirect objects: 2 0 R, 3 1 R, 5 0 R, 6 0 R, 9 0 R, 11 0 R, 12 0 R, 
14 0 R, 16 0 R, 17 0 R, 18 0 R, 20 0 R, 21 0 R, 24 0 R, 26 0 R, 2022 0 R, 
2024 0 R, 2036 0 R, 2037 0 R, 2041 0 R, 2123 0 R
Unreferenced indirect objects without /ObjStm objects: 2 0 R, 3 1 R, 5 0 R, 
11 0 R, 12 0 R, 18 0 R, 24 0 R, 26 0 R, 2022 0 R, 2024 0 R, 2036 0 R, 
2037 0 R, 2041 0 R, 2123 0 R

zzuf 的命令行中,我们指定了种子值(-s)并仅对命令行输入进行模糊测试。任何需要读取配置文件的程序在运行时都不会改变这些配置文件。我们只希望改变指定的文件输入。指定 -C 0 表示 zzuf 在第一次崩溃后继续执行,而不是停止。最后,-T 3 表示在 3 秒后超时,以避免测试过程中卡住。

使用像 zzuf 这样的工具可以为识别读取和处理文件的应用程序中的 bug 提供大量潜力——在这个例子中是 PDF 阅读器。作为一个通用程序,zzuf 的潜力不仅限于此,除了文件模糊测试,它还可以用于网络模糊测试。如果你有兴趣定位漏洞,花些时间使用 zzuf 进行测试将是值得的。

总结

漏洞是攻击者通过利用漏洞利用工具可以突破的潜在“后门”。识别漏洞是进行安全测试的一个重要任务,因为修复漏洞是组织安全计划的重要组成部分。以下是一些要点:

  • 漏洞是软件或系统中的一个弱点。漏洞是一个 bug,但一个 bug 不一定是一个漏洞。
  • 漏洞利用(exploitation)是指利用漏洞来获取攻击者不应访问的内容。
  • OpenVAS 是一个开源漏洞扫描器,可以用于扫描远程和本地漏洞。
  • 本地漏洞需要某种形式的认证访问,虽然它们对某些人来说可能不那么关键,但它们仍然需要修复,因为它们可以被用来提升权限。
  • 网络设备也容易受到漏洞的影响,攻击者可以利用这些漏洞来篡改流量。可以使用 OpenVAS 或其他特定工具,包括专门针对 Cisco 设备的工具,扫描网络设备中的漏洞。
  • 识别不存在的漏洞可能需要一些工作,但像模糊测试工具(fuzzers)这样的工具可以通过触发程序崩溃来帮助发现潜在的漏洞。

有用的资源

  • Open Web Application Security Project (OWASP) 模糊测试
  • Mateusz Jurczyk 在 Black Hat 上的幻灯片《有效的文件格式模糊测试》
  • Jose Ramon Palanco 的博客《文件模糊测试的奇妙世界》
  • Hanno Böck 的教程《模糊测试初学者指南》
  • Hacker Target 的《OpenVAS 教程》
  • The Craft of Coding 的《防御性编程:在 C 和 Fortran 中验证输入》