如何在Ubuntu18.04上安装和使用Radamsa来模糊测试程序和网络服务
作者选择了 Electronic Frontier Foundation Inc 作为 Write for DOnations 计划的一部分来接受捐赠。
介绍
安全威胁不断变得越来越复杂,因此开发人员和系统管理员需要采取积极主动的方法来保护和测试其应用程序的安全性。
测试客户端应用程序或网络服务安全性的常用方法是 fuzzing,它涉及向应用程序反复发送无效或格式错误的数据并分析其响应。 这有助于测试应用程序对意外输入(可能包括损坏的数据或实际攻击)的弹性和鲁棒性。
Radamsa 是一个开源的模糊测试工具,可以根据用户指定的输入数据生成测试用例。 Radamsa 是完全可编写脚本的,到目前为止,它已经成功地发现了 Gzip 等实际应用程序中的漏洞。
在本教程中,您将使用自己的测试用例安装和使用 Radamsa 来模糊测试命令行和基于网络的应用程序。
警告: Radamsa 是一种渗透测试工具,可以让您识别某些系统或应用程序中的漏洞或弱点。 您不得将在 Radamsa 中发现的漏洞用于任何形式的鲁莽行为、伤害或恶意利用。 漏洞应以合乎道德的方式向受影响应用程序的维护者报告,未经明确许可不得公开披露。
先决条件
在开始本指南之前,您需要以下内容:
- 按照 Initial Server Setup 和 Ubuntu 18.04 设置一台 Ubuntu 18.04 服务器,包括 sudo 非 root 用户并启用防火墙以阻止非必要端口。
- 您希望测试的命令行或基于网络的应用程序,例如 Gzip、Tcpdump、Bind、Apache、jq 或您选择的任何其他应用程序。 作为本教程的示例,我们将使用 jq。
警告: Radamsa 可能会导致应用程序或系统运行不稳定或崩溃,因此请仅在您为此做好准备的环境中运行 Radamsa,例如专用服务器。 在对系统进行模糊测试之前,还请确保您已获得系统所有者的明确书面许可。
准备好这些后,以非 root 用户身份登录到您的服务器即可开始。
第 1 步 — 安装 Radamsa
首先,您将下载并编译 Radamsa,以便开始在您的系统上使用它。 Radamsa 源代码可在 GitLab 上的 官方存储库中获得。
首先更新本地包索引以反映任何新的上游更改:
sudo apt update
然后,安装将源代码编译为可执行二进制文件所需的 gcc
、git
、make
和 wget
包:
sudo apt install gcc git make wget
确认安装后,apt
将下载并安装指定的包及其所需的所有依赖项。
接下来,您将从托管在 GitLab 上的存储库中克隆 Radamsa 的源代码副本:
git clone https://gitlab.com/akihe/radamsa.git
这将创建一个名为 radamsa
的目录,其中包含应用程序的源代码。 进入目录开始编译代码:
cd radamsa
接下来,您可以使用 make
开始编译过程:
make
最后,您可以将已编译的 Radamsa 二进制文件安装到您的 $PATH
:
sudo make install
完成后,您可以检查已安装的版本以确保一切正常:
radamsa --version
您的输出将类似于以下内容:
OutputRadamsa 0.6
如果您看到 radamsa: command not found
错误,请仔细检查是否安装了所有必需的依赖项,并且在编译期间没有错误。
现在您已经安装了 Radamsa,您可以开始生成一些示例测试用例来了解 Radamsa 的工作原理以及它的用途。
第 2 步——生成模糊测试用例
现在已经安装了 Radamsa,您可以使用它来生成一些模糊测试用例。
测试用例 是一段数据,将用作您正在测试的程序的输入。 例如,如果您正在对 Gzip 等存档程序进行模糊测试,则测试用例可能是您尝试解压缩的文件存档。
注意: Radamsa 会以各种意想不到的方式操作输入数据,包括极端重复、 位翻转、控制字符注入等。 这可能会导致您的终端会话中断或变得不稳定,因此在继续之前请注意这一点。
首先,将一段简单的文本传递给 Radamsa,看看会发生什么:
echo "Hello, world!" | radamsa
这将操纵(或模糊)输入的数据并输出一个测试用例,例如:
OutputHello,, world!
在这种情况下,Radamsa 在 Hello
和 world
之间添加了一个额外的逗号。 这似乎不是一个重大变化,但在某些应用程序中,这可能会导致数据被错误地解释。
让我们通过运行相同的命令再试一次。 你会看到不同的输出:
OutputHello, '''''''wor'd!
这一次,字符串中插入了多个单引号 ('
),其中一个引号覆盖了 world
中的 l
。 这个特定的测试用例更有可能导致应用程序出现问题,因为单引号/双引号通常用于分隔列表中的不同数据。
让我们再试一次:
OutputHello, $+$PATH\u0000`xcalc`world!
在这种情况下,Radamsa 插入了一个 shell 注入字符串,这将有助于测试您正在测试的应用程序中的 命令注入 漏洞。
您已经使用 Radamsa 对输入字符串进行模糊测试并生成了一系列测试用例。 接下来,您将使用 Radamsa 对命令行应用程序进行模糊测试。
第 3 步 — 对命令行应用程序进行模糊测试
在此步骤中,您将使用 Radamsa 对命令行应用程序进行模糊测试并报告发生的任何崩溃。
模糊每个程序的确切技术差异很大,不同的方法对不同的程序最有效。 但是,在本教程中,我们将使用 jq
的示例,它是一个用于处理 JSON 数据的命令行程序。
您可以使用任何其他类似的程序,只要它遵循获取某种形式的结构化或非结构化数据的一般原则,对其进行处理,然后输出结果。 例如,此示例也适用于 Gzip、Grep、bc、tr 等。
如果您还没有安装 jq
,您可以使用 apt
安装它:
sudo apt install jq
jq
现在将被安装。
要开始模糊测试,请创建一个示例 JSON 文件,将其用作 Radamsa 的输入:
nano test.json
然后,将以下示例 JSON 数据添加到文件中:
测试.json
{ "test": "test", "array": [ "item1: foo", "item2: bar" ] }
如果您希望检查 JSON 语法是否有效,可以使用 jq
解析此文件:
jq . test.json
如果 JSON 有效,jq
将输出文件。 否则,它将显示一个错误,您可以在需要时使用它来更正语法。
接下来,使用 Radamsa 对测试 JSON 文件进行模糊测试,然后将其传递给 jq
。 这将导致 jq
读取模糊/操纵的测试用例,而不是原始的有效 JSON 数据:
radamsa test.json | jq
如果 Radamsa 以一种在语法上仍然有效的方式对 JSON 数据进行模糊测试,则 jq
将输出数据,但无论 Radamsa 对其进行什么更改。
或者,如果 Radamsa 导致 JSON 数据无效,jq
将显示相关错误。 例如:
Outputparse error: Expected separator between values at line 5, column 16
另一种结果是 jq
无法正确处理模糊数据,导致其崩溃或行为不端。 这就是你真正想要的模糊测试,因为这可能表明存在安全漏洞,例如 缓冲区溢出 或命令注入。
为了更有效地测试此类漏洞,Bash 脚本 可用于自动化模糊测试过程,包括生成测试用例、将它们传递给目标程序并捕获任何相关输出。
创建一个名为 jq-fuzz.sh
的文件:
nano jq-fuzz.sh
确切的脚本内容将根据您正在模糊测试的程序类型和输入数据而有所不同,但在 jq
和其他类似程序的情况下,以下脚本就足够了。
将脚本复制到您的 jq-fuzz.sh
文件中:
jq-fuzz.sh
#!/bin/bash while true; do radamsa test.json > input.txt jq . input.txt > /dev/null 2>&1 if [ $? -gt 127 ]; then cp input.txt crash-`date +s%.%N`.txt echo "Crash found!" fi done
该脚本包含一个 while
以使内容重复循环。 每次脚本循环,Radamsa都会根据test.json
生成一个测试用例,并保存到input.txt
。
然后 input.txt
测试用例将通过 jq
运行,所有标准和错误输出重定向到 /dev/null
以避免填满终端屏幕。
最后,检查 jq
的退出值。 如果退出值大于 127
,则表示致命终止(崩溃),然后将输入数据保存在名为 crash-
的文件中以供稍后查看以 Unix 秒和纳秒为单位的当前日期。
将脚本标记为可执行文件并将其设置为运行,以便自动开始模糊测试 jq
:
chmod +x jq-fuzz.sh ./jq-fuzz.sh
您可以随时发出 CTRL+C
来终止脚本。 然后,您可以通过使用 ls
显示包含已创建的任何崩溃文件的目录列表来检查是否发现任何崩溃。
您可能希望改进 JSON 输入数据,因为使用更复杂的输入文件可能会提高模糊测试结果的质量。 避免使用大文件或包含大量重复数据的文件——理想的输入文件是小文件,但仍包含尽可能多的“复杂”元素。 例如,一个好的输入文件将包含以所有格式存储的数据样本,包括字符串、整数、布尔值、列表和对象,以及可能的嵌套数据。
您已使用 Radamsa 对命令行应用程序进行模糊测试。 接下来,您将使用 Radamsa 模糊对网络服务的请求。
第 4 步 — 模糊对网络服务的请求
Radamsa 也可用于模糊网络服务,既可以作为网络客户端,也可以作为服务器。 在此步骤中,您将使用 Radamsa 对网络服务进行模糊测试,其中 Radamsa 充当客户端。
模糊网络服务的目的是测试特定网络服务对发送格式错误和/或恶意数据的客户端的弹性。 许多网络服务(例如 Web 服务器或 DNS 服务器)通常会暴露在 Internet 上,这意味着它们是攻击者的常见目标。 对接收格式错误的数据没有足够抵抗力的网络服务可能会崩溃,甚至更糟糕的是在打开状态下失败,从而允许攻击者读取敏感数据,例如加密密钥或用户数据。
模糊网络服务的具体技术因所讨论的网络服务而异,但在本例中,我们将使用 Radamsa 模糊服务静态 HTML 内容的基本 Web 服务器。
首先,您需要设置用于测试的 Web 服务器。 您可以使用 php-cli
软件包附带的内置开发服务器来执行此操作。 您还需要 curl
来测试您的 Web 服务器。
如果您没有安装 php-cli
和/或 curl
,您可以使用 apt
安装它们:
sudo apt install php-cli curl
接下来,创建一个目录来存储您的 Web 服务器文件并移入其中:
mkdir ~/www cd ~/www
然后,创建一个包含一些示例文本的 HTML 文件:
nano index.html
将以下内容添加到文件中:
索引.html
<h1>Hello, world!</h1>
您现在可以运行您的 PHP Web 服务器。 您需要能够在仍然使用另一个终端会话的同时查看 Web 服务器日志,因此为此打开另一个终端会话并通过 SSH 连接到您的服务器:
cd ~/www php -S localhost:8080
这将输出类似于以下内容:
OutputPHP 7.2.24-0ubuntu0.18.04.1 Development Server started at Wed Jan 1 16:06:41 2020 Listening on http://localhost:8080 Document root is /home/user/www Press Ctrl-C to quit.
您现在可以切换回原始终端会话并使用 curl
测试 Web 服务器是否正常工作:
curl localhost:8080
这将输出您之前创建的示例 index.html
文件:
Output<h1>Hello, world!</h1>
您的 Web 服务器只需要在本地可访问,因此您不应在防火墙上为其打开任何端口。
现在您已经设置了测试 Web 服务器,您可以开始使用 Radamsa 对其进行模糊测试。
首先,您需要创建一个示例 HTTP 请求以用作 Radamsa 的输入数据。 创建一个新文件以将其存储在:
nano http-request.txt
然后,将以下示例 HTTP 请求复制到文件中:
http-request.txt
GET / HTTP/1.1 Host: localhost:8080 User-Agent: test Accept: */*
接下来,您可以使用 Radamsa 将此 HTTP 请求提交到您的本地 Web 服务器。 为此,您需要将 Radamsa 用作 TCP 客户端,这可以通过指定要连接的 IP 地址和端口来完成:
radamsa -o 127.0.0.1:8080 http-request.txt
注意: 请注意,使用 Radamsa 作为 TCP 客户端可能会导致格式错误/恶意数据通过网络传输。 这可能会破坏事情,所以要非常小心,只访问您被授权测试的网络,或者最好坚持使用 localhost (127.0.0.1
) 地址。
最后,如果您查看本地 Web 服务器的输出日志,您会看到它已收到请求,但很可能没有处理它们,因为它们无效/格式错误。
输出的日志将在您的第二个终端窗口中可见:
Output[Wed Jan 1 16:26:49 2020] 127.0.0.1:49334 Invalid request (Unexpected EOF) [Wed Jan 1 16:28:04 2020] 127.0.0.1:49336 Invalid request (Malformed HTTP request) [Wed Jan 1 16:28:05 2020] 127.0.0.1:49338 Invalid request (Malformed HTTP request) [Wed Jan 1 16:28:07 2020] 127.0.0.1:49340 Invalid request (Unexpected EOF) [Wed Jan 1 16:28:08 2020] 127.0.0.1:49342 Invalid request (Malformed HTTP request)
为了获得最佳结果并确保记录崩溃,您可能希望编写一个类似于步骤 3 中使用的自动化脚本。 您还应该考虑使用更复杂的输入文件,其中可能包含额外的 HTTP 标头等附加内容。
您已经使用 Radamsa 作为 TCP 客户端对网络服务进行了模糊测试。 接下来,您将使用 Radamsa 作为服务器对网络客户端进行模糊测试。
第 5 步 — 模糊网络客户端应用程序
在此步骤中,您将使用 Radamsa 对网络客户端应用程序进行模糊测试。 这是通过拦截来自网络服务的响应并在客户端接收到它们之前对其进行模糊测试来实现的。
这种模糊测试的目的是测试网络客户端应用程序从网络服务接收格式错误或恶意数据的弹性。 例如,测试从 Web 服务器(网络服务)接收格式错误的 HTML 的 Web 浏览器(客户端),或测试从 DNS 服务器接收格式错误的 DNS 响应的 DNS 客户端。
与 fuzzing 命令行应用程序或网络服务的情况一样,fuzzing 每个网络客户端应用程序的确切技术差异很大,但是在这个示例中,您将使用 whois
,这是一个简单的基于 TCP 的发送/接收应用。
whois
应用程序用于向 WHOIS 服务器发出请求并接收 WHOIS 记录作为响应。 WHOIS 通过 TCP 端口 43
以明文形式运行,使其成为基于网络的模糊测试的良好候选者。
如果您还没有 whois
可用,您可以使用 apt
安装它:
sudo apt install whois
首先,您需要获取一个示例 whois
响应以用作您的输入数据。 您可以通过发出 whois
请求并将输出保存到文件来做到这一点。 当您使用示例数据在本地测试 whois
程序时,您可以在此处使用任何您希望的域:
whois example.com > whois.txt
接下来,您需要将 Radamsa 设置为提供此 whois
响应的模糊版本的服务器。 一旦 Radamsa 在服务器模式下运行,您将需要能够继续使用您的终端,因此建议为此打开另一个终端会话和与您的服务器的 SSH 连接:
radamsa -o :4343 whois.txt -n inf
Radamsa 现在将在 TCP 服务器模式下运行,并且无论收到什么请求数据,每次与服务器建立连接时都会提供 whois.txt
的模糊版本。
您现在可以继续测试 whois
客户端应用程序。 您需要为您选择的任何域发出正常的 whois
请求(它不必与示例数据相同),但指向 whois
您本地的 Radamsa 服务器:
whois -h localhost:4343 example.com
响应将是您的样本数据,但会被 Radamsa 模糊处理。 只要 Radamsa 正在运行,您就可以继续向本地服务器发出请求,并且每次都会提供不同的模糊响应。
与模糊网络服务一样,为了提高此网络客户端模糊测试的效率并确保捕获任何崩溃,您可能希望编写一个类似于步骤 3 中使用的自动化脚本。
在最后一步中,您使用 Radamsa 对网络客户端应用程序进行模糊测试。
结论
在本文中,您设置了 Radamsa 并使用它来模糊测试命令行应用程序、网络服务和网络客户端。 您现在已经掌握了对自己的应用程序进行模糊测试所需的基础知识,希望能够提高它们的鲁棒性和抗攻击性。
如果您想进一步探索 Radamsa,您可能希望详细查看 Radamsa README
文件,因为它包含更多技术信息和如何使用该工具的示例:
您可能还希望查看其他一些模糊测试工具,例如 American Fuzzy Lop (AFL),这是一种高级模糊测试工具,旨在以极高的速度和准确性测试二进制应用程序: