kvm-fuzz:使用KVM技术对闭源用户空间二进制文件执行模糊测试

关于kvm-fuzz

kvm-fuzz是一款功能强大的模糊测试工具,该工具能够利用KVM技术对闭源用户空间x86_64二进制文件执行模糊测试。

KVM介绍

虚拟化是云计算的基础,一种资源管理技术,是将计算机的各种实体资源(CPU、内存、磁盘空间、网络适配器等)做虚拟化、将虚拟化后的整体做为一个可供分割且组合的操作系统。

服务器虚拟化是云计算最核心的技术,而KVM是当前最主流的开源的服务器虚拟化技术。KVM 全称是 Kernel-Based Virtual Machine,基于Linux内核的虚拟化技术。KVM基于Linux内核实现,属于半虚拟化的Hypervisor。KVM有一个内核模块叫 kvm.ko,只用于管理虚拟 CPU 和内存,而Qemu则协助提供IO设备半虚拟化,用于虚拟磁盘IO和网络IO等。不过IO设备的虚拟化方向都是往直接透传到宿主机的方向走,比如vhost-net,直接在硬件或内核级别支持。一个 KVM虚机在宿主机中其实是一个qemu-kvm进程。而每个虚机中的vCPU则为宿主机中的一个线程。

工具要求

Zig 0.12.0

libdwarf

libelf

libssl

Python 3

angr

工具安装

首先,我们需要使用下列命令安装并配置好该工具所需的依赖组件和环境工具:

sudo apt install libdwarf-dev libelf-dev libssl-dev

sudo apt install python3

python3 -m pip install angr

为了使用Intel PT执行基于覆盖率的模糊测试,我们还需要自行安装好libxdckAFL

接下来,广大研究人员可以直接使用下列命令将该项目源码克隆至本地:

git clone https://github.com/klecko/kvm-fuzz.git

然后切换到项目目录中,运行下列命令构建内核和虚拟机管理程序:

cd kvm-fuzz

zig build

系统调用测试由一个二进制文件组成,它使用不同的系统调用并检查其是否正确。为了构建和运行该文件,我们可以使用提以下脚本:

./scripts/run_tests_on_linux.sh

./scripts/run_tests_on_kvm-fuzz.sh

执行之后,我们将能够看到如下所示的你诶容:

[KERNEL] ===============================================================================

[KERNEL] All tests passed (2378 assertions in 44 test cases)

[KERNEL]

Run ended with reason Exit

工具帮助信息

kvm-fuzz: fuzz x86_64 closed-source applications with hardware acceleration

 

Usage:

  kvm-fuzz [ options ] -- /path/to/fuzzed_binary [ args ]

 

Available options:

--minimize-corpus         设置语料库最小化模式

--minimize-crashes        设置碰撞最小化模式

  -j, --jobs n            要使用的线程数(默认值:8)

  -m, --memory arg        虚拟机内存限制(默认值:8M)

  -t, --timeout ms        每次运行的超时时间(毫秒),0表示没有超时(默认值:2)

  -k, --kernel path       内核路径(默认值:./zig out/bin/kernel)

  -i, --input dir         输入文件夹(初始语料库)(默认值:./in)

  -o, --output dir        输出文件夹(语料库、崩溃等)(默认值:./out)

  -f, --file path         目标的内存加载文件,一次设置一个文件,例如-f file1 -f file2

  -s, --single-run [=path] 执行一次任务,可以选择指定输入文件

  -T, --tracing type       启用系统调用追踪,类型可以是内核或用户

      --tracing-unit unit  追踪单元,它可以是指令或循环(默认循环)

  -h, --help               打印工具帮助信息

工具使用

现在,我们使用ls源码作为种子,来对readelf执行模糊测试。运行kvm-fuzz并为虚拟机设置 16 MB 内存和 5 毫秒的超时时间:

$ zig build -Dcoverage=none

$ rm in/1

$ cp /bin/ls in/

$ zig-out/bin/kvm-fuzz -m 16M -t 5 -- /bin/readelf -a input

Number of threads: 8

Total files read: 1

Max mutated input size: 1421440

Ready to run!

[KERNEL] [default] [info] hello from zig

[KERNEL] [user] [info] Jumping to user at 0x400000001100 with rsp 0x7ffffffffe70!

[...]

Performing first runs...

Set corpus mode: Normal. Output directories will be ./out/corpus and ./out/crashes. Seed corpus coverage: 0

Creating threads...

[1.000] cases: 6265, mips: 10807.154, fcps: 6264.102, cov: 0, corpus: 1/138.812KB, unique crashes: 0 (total: 0), timeouts: 3, no new cov for: 1.000

        vm exits: 1.000 (hc: 1.000, cov: 0.000, debug: 0.000), reset pages: 137.765

        run: 0.864, reset: 0.045, mut: 0.081, set_input: 0.011, report_cov: 0.000

        kvm: 0.863, hc: 0.000, update_cov: 0.000, mut1: 0.007, mut2: 0.075

[2.000] cases: 12907, mips: 11112.763, fcps: 6640.934, cov: 0, corpus: 1/138.812KB, unique crashes: 0 (total: 0), timeouts: 3, no new cov for: 2.000

        vm exits: 1.000 (hc: 1.000, cov: 0.000, debug: 0.000), reset pages: 137.109

        run: 0.866, reset: 0.044, mut: 0.079, set_input: 0.011, report_cov: 0.000

        kvm: 0.865, hc: 0.000, update_cov: 0.000, mut1: 0.007, mut2: 0.072

[3.000] cases: 19397, mips: 11125.964, fcps: 6489.186, cov: 0, corpus: 1/138.812KB, unique crashes: 0 (total: 0), timeouts: 4, no new cov for: 3.000

        vm exits: 1.000 (hc: 1.000, cov: 0.000, debug: 0.000), reset pages: 137.286

        run: 0.865, reset: 0.044, mut: 0.080, set_input: 0.011, report_cov: 0.000

        kvm: 0.865, hc: 0.000, update_cov: 0.000, mut1: 0.007, mut2: 0.074

输出数据中包括一些有用的统计数据,例如用例总数、指令数量、模糊测试数量、语料库大小和时间数据等。

使用基于断点的覆盖率模式执行模糊测试:

$ zig build -Drelease-fast

$ zig-out/bin/kvm-fuzz -m 16M -t 5 -- /bin/readelf -a input

[...]

[3.001] cases: 35001, mips: 11669.951, fcps: 11765.726, cov: 2684, corpus: 143/28689.814KB, unique crashes: 0 (total: 0), timeouts: 4, no new cov for: 0.000

        vm exits: 1.031 (hc: 1.000, cov: 0.000, debug: 0.031), reset pages: 150.626

        run: 0.541, reset: 0.161, mut: 0.242, set_input: 0.055, report_cov: 0.001

        kvm: 0.540, hc: 0.000, update_cov: 0.000, mut1: 0.091, mut2: 0.150

我们可以看到我们花了 24% 的时间来改变输入。为了提高模糊测试速度,我们可以使用较小的种子来减少这一时间,将其设置为单个种子并再次运行:

$ rm in/*

$ cp /bin/parallel in

$ zig-out/bin/kvm-fuzz -m 16M -t 5 -- /bin/readelf -a input

[...]

[3.001] cases: 88147, mips: 16667.261, fcps: 31502.726, cov: 3030, corpus: 238/5874.473KB, unique crashes: 0 (total: 0), timeouts: 4, no new cov for: 0.000

        vm exits: 1.014 (hc: 1.000, cov: 0.000, debug: 0.014), reset pages: 94.269

        run: 0.838, reset: 0.102, mut: 0.052, set_input: 0.007, report_cov: 0.001

        kvm: 0.837, hc: 0.000, update_cov: 0.000, mut1: 0.010, mut2: 0.041

性能对比

项目地址

kvm-fuzz:【GitHub传送门

参考资料

JNIC 2023 – VIII Jornadas Nacionales de Investigación en Ciberseguridad

Download ⚡Zig Programming Language

GitHub - klecko/libxdc: The fastest Intel-PT decoder for fuzzing

GitHub - IntelLabs/kAFL: A fuzzer for full VM kernel/driver targets

GitHub - nyx-fuzz/KVM-Nyx

AFLplusplus/instrumentation/README.persistent_mode.md at stable · AFLplusplus/AFLplusplus · GitHub

  • 18
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值