什么是 Fuzzing?
Fuzzing 是一种自动化软件测试技术,通过生成大量的随机、畸形数据作为输入,来寻找程序中的漏洞。 就像“压力测试”,但 Fuzzing 的目标是让程序崩溃,从而发现隐藏的 Bug。
实际应用:
- 发现安全漏洞:Fuzzing 可以帮助发现可能被黑客利用的漏洞,例如缓冲区溢出、内存泄漏等。
- 提高软件质量:通过 Fuzzing,开发者可以在软件发布前发现并修复 Bug,提高软件的稳定性和可靠性。
为什么 Fuzzing ZBar?
ZBar 是一个流行的开源条形码扫描库,被广泛应用于各种应用中。如果 ZBar 存在漏洞,可能会影响到大量用户。虽然 ZBar 很流行,但之前很少有人对其进行 Fuzzing 测试。
怎么 Fuzzing ZBar?
-
准备环境
- 选择 Fuzzing 工具:常用的工具有 AFL、libFuzzer 等。
- 编译 ZBar:使用带有 Sanitizer(如 AddressSanitizer)的编译器编译 ZBar。Sanitizer 可以在程序崩溃时提供详细的错误信息。
- 编写 Fuzzing Harness:Harness 是一个简单的程序,它调用 ZBar 的条形码解码函数,并将 Fuzzing 工具生成的随机数据作为输入。
-
构建 Fuzzing Harness
- Harness 的主要任务是读取 Fuzzer 生成的输入数据,并将其传递给 ZBar 的解码函数。
- 一个简单的 Harness 示例:
#include <stdio.h>
#include <stdlib.h>
#include <zbar.h>
using namespace zbar;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, uint32_t size) {
int width = 16, height = 16;
if (size != width*height) return 1;
zbar_image_t *image = zbar_image_create();
if(!image)
return 0;
zbar_image_set_size(image, width, height);
zbar_image_set_format(image, zbar_fourcc('Y', '8', '0', '0'));
zbar_image_set_data(image, data, size, NULL);
/* create a reader */
zbar_image_scanner_t *scanner = zbar_image_scanner_create();
/* configure the reader */
zbar_image_scanner_set_config(scanner, (zbar_symbol_type_t)0, ZBAR_CFG_ENABLE, 1);
zbar_scan_image(scanner, image);
/* clean up */
zbar_image_destroy(image);
zbar_image_scanner_destroy(scanner);
return 0;
}
-
运行 Fuzzing
- 使用 Fuzzing 工具运行 Harness,并监控程序的运行状态。
- Fuzzing 工具会自动生成大量的随机输入数据,并尝试触发程序中的漏洞。
-
分析结果
- 如果 Fuzzing 过程中程序崩溃,Sanitizer 会提供详细的错误信息,包括崩溃的位置、原因等。
- 根据错误信息,开发者可以定位并修复 Bug。
Fuzzing ZBar 发现了什么?
通过 Fuzzing,研究人员在 ZBar 中发现了两个严重漏洞:
- 栈缓冲区溢出:恶意条形码可能导致任意代码执行。
- 内存泄漏:反复扫描恶意条形码可能导致拒绝服务攻击。
实际案例
- 微信图片崩溃 Bug: 2023 年 4 月,微信出现了一个 Bug,打开某些图片会导致微信崩溃。这个 Bug 的根本原因在于畸形的二维码解码时导致的空指针错误。
- ZBar 安全漏洞:研究人员使用 Fuzzing 技术对 ZBar 条形码扫描库进行了测试,发现了严重的漏洞[2]。
如何避免类似问题?
- 使用 Sanitizer:在开发和测试过程中,使用 AddressSanitizer 等工具可以帮助发现内存相关的错误。
- 限制攻击面:如果只需要扫描特定类型的条形码,可以配置 ZBar 只扫描这些类型,减少潜在的攻击面。
- 持续 Fuzzing:定期对软件进行 Fuzzing 测试,可以及时发现并修复 Bug。
通过 Fuzzing,我们可以有效地提高软件的安全性,防范潜在的攻击。