论文分享 | PromptFuzz:用于模糊测试驱动程序生成的提示模糊测试

大语言模型拥有的强大能力可以用来辅助多种工作,但如何有效的辅助仍然需要人的精巧设计。分享一篇发表于2024年CCS会议的论文PromptFuzz,它利用模型提示生成模糊测试驱动代码,并将代码片段嵌入到LLVM框架中执行模糊测试。

论文摘要

制作高质量的模糊测试驱动程序不仅耗时而且还需要对被测目标有深入的了解,即使是最先进的自动化模糊测试驱动程序生成技术也未能达到预期。虽然用被测目标代码派生(OSS-Fuzz)的方式可以达到深度状态,但是程序逻辑的覆盖范围有限。解释性模糊测试(Hopper)可以探索多数接口调用,不过需要在较大的搜索空间进行多次尝试。

论文提出了 PromptFuzz ,一种覆盖引导的模糊器,它可以迭代生成模糊测试驱动程序来探索未被发现的库程序代码。通过使用大模型提示词探索被测程序的接口调用,本文提出了几种关键技术,包括:1)指导程序生成,2)错误程序验证,3)覆盖引导的提示变异,4)变量约束的模糊器调度。PromptFuzz 在 14 个真实的库程序上进行了评估,模糊测试驱动程序的分治覆盖率相比于 OSS-Fuzz 和 Hopper 分别高出 1.61 倍和 1.63 倍。此外,所提方案在 49 次崩溃中检测到了 33 个新的漏洞,其中 30 个漏洞已得到相应社区的确认。

1 背景介绍

模糊测试对软件的安全性和可靠性至关重要。OSS-Fuzz为开源软件部署了最先进的模糊测试器,截至2023年2月,已在850个项目中发现并解决了8900多个漏洞和28000个错误。开发者会选择合适的模糊测试器(Fuzzer)并编写高质量的模糊测试驱动程序(Fuzz Driver),驱动程序会解析来自模糊测试器的输入并调用被测目标(Target or Library)的程序代码。然而,编写高质量的模糊测试驱动程序具有挑战性,因为它既耗时又需要对被测目标有深入的了解。手动编写的模糊测试驱动程序通常只调用了被测目标的一小部分功能,限制了模糊测试的能力。

与手动编写的模糊测试驱动程序相比,自动化技术通过从源代码或运行时反馈中学习被测目标的接口调用情况,从而派生出模糊测试驱动程序。FUDGE,FuzzGen,UTopia方案从源代码中采用静态分析的方式提取接口调用代码,而APICraft,WINNIE则从进程执行中动态跟踪记录接口的调用顺序。Hopper是最先进的模糊测试驱动程序生成解决方案(与本文同一团队的工作,发表于2023年CCS会议),它会将对被测目标的模糊测试问题转化为解释性模糊测试问题,从接口调用的动态反馈中学习有效的接口使用情况。尽管可以覆盖到大多数接口函数,但Hopper需要在广阔的搜索空间中进行多次尝试,才能找到有用且满足深度的接口调用序列。

大语言模型(LLM)在生成代码方面有出色的表现,可以在不依赖被测目标代码的情况下可以有效地探索接口使用情况。以GPT系列为例,它们在广泛的代码预料库上进行过训练,能够生成符合用户意图的代码。之前的工作也尝试使用LLM生成模糊测试驱动程序,但它们设计的指令仅限于特定场景,生成的驱动程序在接口调用上多样性较低,无法覆盖不常用代码或深度状态。本文引入了PromptFuzz,一种覆盖引导的模糊测试器,它会迭代地改变提示词以探索未发现的库程序代码。

2 基础概念

  • 库程序模糊测试

库程序在软件开发中被广泛使用,因此针对它的模糊测试变得越来越重要。与命令行程序不同,库程序拥有多个访问入口点,即程序接口函数,这些入口有严格的格式约束规范。为了能够利用现有的模糊测试器,相应的模糊测试驱动程序被开发出来,驱动程序从模糊测试器接受随机字节,然后将这些字节转换成结构良好的接口调用参数,喂给被测目标执行模糊测试。

论文给出了一个模糊测试驱动程序的例子,该驱动程序嵌入在LLVM框架中,每次执行一个测试用例。驱动程序接受数据和大小两个参数,被测目标为视频解码库libvpx,驱动程序执行初始化和数据转换操作,调用库程序的接口函数进行视频解码。

#include <vpx/vp8dx.h>
#include <vpx/vp8cx.h>
#include <vpx/vpx_decoder.h>extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {// Create the decoder configurationvpx_codec_dec_cfg_t dec_cfg = {0};...// Initialize the decodervpx_codec_ctx_t decoder;vpx_codec_iface_t *decoder_iface = vpx_codec_vp8_dx();vpx_codec_err_t decoder_init_res = vpx_codec_dec_init_ver(&decoder, decoder_iface, &dec_cfg, 0, VPX_DECODER_ABI_VERSION);if (decoder_init_res != VPX_CODEC_OK) {return 0;}// Process the input datavpx_codec_err_t decode_res = vpx_codec_decode(&decoder, data, size, NULL, 0);if (decode_res != VPX_CODEC_OK) {vpx_codec_destroy(&decoder);return 0;}// Get the decoded framevpx_image_t *img = NULL;vpx_codec_iter_t iter = NULL;while ((img = vpx_codec_get_frame(&decoder, &iter))!= NULL) {// Process the framevpx_img_flip(img);...}// Cleanupvpx_codec_destroy(&decoder);return 0;
}

  • 大语言模型

LLM是一种深度学习模型,具有非常复杂的架构和大量的参数,使得它们能够从大量文本数据中获取知识,GPT3,ChatGPT,GPT4是当前十分具有代表性的LLM。大语言模型被训练为预测下一个词,表示为 w n + 1 w_{n+1} wn+1,给定一个词序列 w 1 , w 2 , . . . , w n w_1,w_2,...,w_n w1,w2,...,wn,最大化语言模型的目标函数,如下列公式。

P ( w 1 , w 2 , . . . , w n ) = ∏ i = 1 n P ( w i ∣ w 1 , w 2 , . . . , w i − 1 ) P(w_1,w_2,...,w_n)=\prod^n_{i=1}P(w_i|w_1,w_2,...,w_{i-1}) P(w1,w2,...,wn)=i=1nP(wiw1,w2,...,wi1)

在推理阶段,LLM利用广泛参数中学习到的模型权重,基于先前的token w 1 , w 2 , . . . , w n w_1,w_2,...,w_n w1,w2,...,wn,自动回归地生成下一个token w n + 1 w_{n+1} wn+1,用户提供的起始token被称为提示词。为了确保LLM产生的输出与用户给定指令保持一致,一系列LLM已通过强化学习训练得到增强,例如ChatGPT和GPT4。

  • 基于大语言模型的模糊测试驱动程序生成

最近,出现一些利用LLM来增强模糊测试的研究,其主要的挑战包括自动构造提示词和对模型输出的验证。在基于LLM的模糊测试驱动程序生成中,提示词通常由任务描述和上下文信息组成。为了尽可能提供信息和指导模型,任务描述应至少制定被测目标库程序,以及包含在其中的接口函数。在早期的尝试中,每个提示词仅分配一个接口函数作为目标,过于简单而且难以有效果。另一方面,LLM生成的代码无法直接用于模糊测试,因为它产生的代码很容易出错。依赖编译器或简单规则进行输出的验证,只能报告语法或浅层逻辑错误,当其用作模糊测试驱动程序时,这种缺陷代码会产生许多误报。

3 系统设计

PromptFuzz通过覆盖率引导的LLM提示词生成高质量的模糊测试驱动程序以检测库程序错误,它会改变LLM提示词以生成涵盖更广泛接口调用范围的驱动程序,首先随机选择一个库接口函数构造提示词,然后根据覆盖率反馈改变该提示词,直到模糊测试达到被测目标的收敛,工作流程如图1所示。

图1 PromptFuzz模糊测试驱动程序生成流程

图1 PromptFuzz模糊测试驱动程序生成流程

3.1 指导程序生成

论文选择ChatGPT和GPT-4作为大语言模型来指导模糊测试驱动程序生成,尽管模型生成的程序并不总能够严格遵循指令,但它们有助于探索有效的库程序接口调用情况,可以用提示词来引导大语言模型生成符合预期的程序。PromptFuzz使用目标库程序和接口函数组合填充提示词模板,如图2所示包含以下组件。

  • 任务描述。说明了LLM应生成的驱动程序代码,指定了库程序的哪些接口函数在LLVMFuzzerTestOneInput函数中是必需的。
  • 库程序上下文。包括了库程序使用的头文件,接口函数签名,自定义类型等信息,通过整合对库程序上下文的理解,显著减少LLM产生幻觉的发生。
  • 库程序说明。指导LLM生成符合库程序所需指定模式的代码,部分库程序的接口函数可能从文件,文件流或描述符读取输入,对其进行相应规范。

图2 提示词模板

图2 提示词模板

3.2 错误程序验证

PromptFuzz消除错误驱动程序通过如下三个步骤。

  1. 删除C/C++编译器识别出语法错误的驱动程序。
  2. 剩余的驱动程序编译成可执行文件,结合多个运行时sanitizers,捕获和分析与预期行为模式的偏差。
  3. 使用提供的语料库对这些驱动程序进行模糊测试,删除检测到偏差的任何驱动程序。

在这部分模糊测试过程中,触发独特行为的输入将添加到语料库中,从而扩展进行更深入的运行时验证。PromptFuzz同时还会计算驱动程序执行的代码覆盖率,删除那些不符合代码覆盖标准的驱动程序,表明库程序的接口函数得到了充分的利用,错误驱动程序验证流程如图3所示。

图3 错误驱动程序验证流程

图3 错误驱动程序验证流程

3.3 覆盖引导的提示变异

为了创建连续多轮次的提示词,PromptFuzz会改变前几轮提示词中的接口函数组合,生成不同的模糊测试驱动程序,同时以代码覆盖率作为反馈来生成有效的提示词。

  • 能量分配

首先,PromptFuzz为每个接口函数分配相同的能量,在每次模糊测试迭代期间,更新访问过的分支并计算接口函数的分支覆盖率。

c o v ( i ) = 包含 i 的覆盖的分支数 包含 i 的所有的分支数 cov(i)=\frac{包含i的覆盖的分支数}{包含i的所有的分支数} cov(i)=包含i的所有的分支数包含i的覆盖的分支数

接着,按照AFLFast中的指数调度来更新其能量,令 s e e d ( i ) seed(i) seed(i)为调用接口函数 i i i的种子驱动程序数量, p r o m p t ( i ) prompt(i) prompt(i)表示为包含接口函数 i i i的提示词数量,计算能量如下。

e n e r g y ( i ) = 1 − c o v ( i ) ( 1 + s e e d ( i ) ) e × ( 1 + p r o m p t ( i ) ) e energy(i)=\frac{1-cov(i)}{(1+seed(i))^e \times (1+prompt(i))^e} energy(i)=(1+seed(i))e×(1+prompt(i))e1cov(i)

执行越少次数的接口函数将被分配更高的能量,于是在未来的提示词中包含该接口函数的概率就越高。

  • 变异策略

然后,PromptFuzz会改变提示词中的接口函数组合以指导模糊测试驱动程序生成,这些策略与传统的模糊测试器类似,例如在C组合中插入A函数Insert(C,A),替换C组合中的A函数为B函数Replace(C,A,B),合并C组合和S组合形成新的组合CrossOver(C,S)

在接口函数能量的指导下,PromptFuzz通过变异策略组合接口函数以生成之前未探索过的组合,用density表示调用显式数据依赖的库程序接口函数的最大数量,用unique branches表示驱动程序执行时触发的独立分支数量。计算quality(g)=density(g) x (1+unique_branches(g))用以量化驱动程序的质量,以质量值更高为目标来指导变异策略

图4 接口函数组合变异算法

图4 接口函数组合变异算法

在每次模糊测试迭代过程中,PromptFuzz都会探索驱动程序种子集合并更新这些种子驱动程序的质量,使用库程序接口函数能量和种子驱动程序质量的反馈,应用如图4所示算法来选择下一次迭代中使用的新接口函数组合。

3.4 变量约束的模糊器调度

为了使得种子驱动程序能够执行模糊测试,PromptFuzz对其中的接口函数参数进行约束类型推断,将部分参数从常量转换为从模糊测试器输入的任意字节的变量,例如数组长度、文件名、格式化字符串等,一个简单的实例如图5所示。

图5 约束参数转换例子

图5 约束参数转换例子

最终,PromptFuzz将种子驱动程序整合到模糊测试器,根据其提供的几个特定字节来调度每个种子驱动程序,3.2节中进行错误程序验证的模糊测试语料将用来作为驱动程序的初始输入。此外,转换之前的参数常量值也将形成初始语料,配合以进行模糊测试器的执行。

4 实现验证

PromptFuzz用Rust语言实现了大约1万7千行代码,开源在仓库https://github.com/PromptFuzz/PromptFuzz中,其中使用了clang_ast做抽象语法树的提取,额外实现了FSan插件来进行文件描述检查。论文在14个广泛使用的开源项目上对PromptFuzz进行了评估,总体实验结果,发现的已知漏洞,消融实验和变异策略的比较,可以详细去看原论文,这里不再赘述。

学习笔记

这篇论文做了很好的尝试,利用大语言模型来生成针对被测目标的驱动程序,再使用传统的模糊测试器来执行测试,相关工作OSS-Fuzz也做过尝试。论文偏工程,有一定启发,方法比较杂,与近期部分LLM+Fuzz方向的研究类似,大语言模型用于辅助仍需要进行提纯,通过算法筛选和纠偏,但确实在自动化和发散性方面比较有效。最后,附上文献引用和DOI链接:

Lyu Y, Xie Y, Chen P, et al. Prompt Fuzzing for Fuzz Driver Generation[C]//Proceedings of the 2024 on ACM SIGSAC Conference on Computer and Communications Security. 2024: 3793-3807.

https://doi.org/10.1145/3658644.3670396

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/64584.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

利用Python爬虫获取1688商品详情的探索之旅

在当今数字化时代&#xff0c;数据已成为一种宝贵的资源。对于电商行业来说&#xff0c;获取商品信息尤为重要。阿里巴巴旗下的1688平台&#xff0c;作为中国领先的B2B电子商务平台&#xff0c;提供了海量的商品信息。本文将带你了解如何使用Python爬虫技术&#xff0c;合法合规…

[算法] [leetcode-1137] 第 N 个泰波那契数

1137 第 N 个泰波那契数简单 泰波那契序列 Tn 定义如下&#xff1a; T0 0, T1 1, T2 1, 且在 n > 0 的条件下 Tn3 Tn Tn1 Tn2 给你整数 n&#xff0c;请返回第 n 个泰波那契数 Tn 的值。 示例 1&#xff1a; 输入&#xff1a;n 4 输出&#xff1a;4 解释&#x…

macOS上怎么制作条形码

推荐使用Barcode Flow APP&#xff0c;目前支持iOS、macOS、iPadOS 大家可以在app store里面搜索 支持几乎所有条形码的格式 gs128、code128、DataMaxitr等等。 导出和打印都可以。 还支持工具规则自动生成。

位运算与操作符应用

一.二进制与进制转化 1.概念解析 我们常常能听见2进制&#xff0c;8进制&#xff0c;16进制这些讲法。他们都是数值的不同表达形式。根据不同的进制大小有着不同的权重比例。我们生活中常用的是10进制数&#xff0c;也就是逢10进1&#xff0c;由此推理至其他进制。例如2进制就…

适配器模式概述

大体介绍 适配器模式&#xff08;Adapter Pattern&#xff09;是一种结构型设计模式&#xff0c;其核心目的是通过提供一个适配器类来使得原本接口不兼容的类可以一起工作。它通过将一个类的接口转换成客户端所期望的接口&#xff0c;使得原本因接口不兼容而无法一起工作的类可…

计算机专业考研 408 学科学习方法

计算机专业考研 408 学科涵盖数据结构、计算机组成原理、操作系统和计算机网络四门核心课程&#xff0c;内容多且难度大。但只要掌握科学的学习方法&#xff0c;便能化繁为简&#xff0c;稳步提升。以下为大家详细介绍 408 学科的学习方法。 一、基础夯实阶段&#xff1a;全面…

C++ 设计模式:命令模式(Command Pattern)

链接&#xff1a;C 设计模式 链接&#xff1a;C 设计模式 - 访问器模式 命令模式&#xff08;Command Pattern&#xff09;是一种行为型设计模式&#xff0c;它将请求封装成一个对象&#xff0c;从而使你可以用不同的请求对客户进行参数化&#xff0c;对请求排队或记录请求日志…

html+css+js网页设计 美食 美食4个页面带js

htmlcssjs网页设计 美食 美食4个页面带js 网页作品代码简单&#xff0c;可使用任意HTML辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作&#xff09;。 获取源码 1&#…

swagger,showdoc,apifox,Mock 服务,dubbo,ZooKeeper和dubbo的关系

Swagger、ShowDoc 和 Apifox 之间的区别与优势 Swagger、ShowDoc 和 Apifox 都是用于 API 文档管理和测试的工具&#xff0c;但它们各有特色和适用场景。以下是详细的比较&#xff0c;并附上每个工具的具体用法示例。 1. Swagger 特点与优势&#xff1a; 广泛采用: Swagger…

边沿检测电路漏检原因分析

边沿检测电路漏检原因分析 常用结构如下&#xff1a; module edge_detect1( input clk, input signal, output pe, //上升沿 output ne, //下降沿 output de //双边沿 );reg reg1;always(posedge clk) beginreg1 < signal; endassign pe (~reg1) & signal; assign…

嵌入式硬件杂谈(七)IGBT MOS管 三极管应用场景与区别

引言&#xff1a;在现代嵌入式硬件设计中&#xff0c;开关元件作为电路中的重要组成部分&#xff0c;起着至关重要的作用。三种主要的开关元件——IGBT&#xff08;绝缘栅双极型晶体管&#xff09;、MOSFET&#xff08;金属氧化物半导体场效应晶体管&#xff09;和三极管&#…

鸿蒙开发:了解正则表达式

前言 从给出的文本中&#xff0c;按照既定的相关规则&#xff0c;匹配出符合的数据&#xff0c;其中的规则就是正则表达式&#xff0c;使用正则表达式&#xff0c;可以使得我们用简洁的代码就能实现一定复杂的逻辑&#xff0c;比如判断一个邮箱账号是否符合正常的邮箱账号&…

Kafka的acks机制和ISR列表

Kafka 是一个流行的分布式流处理平台&#xff0c;用于构建实时数据流管道和应用程序。在 Kafka 中&#xff0c;acks 机制和 ISR&#xff08;In-Sync Replicas&#xff09;列表是两个重要的概念&#xff0c;它们共同确保消息的持久性和可靠性。 acks 机制 acks 机制是 Kafka 生…

在 Ubuntu 下通过 Docker 部署 Caddy 服务器

嘿&#xff0c;伙伴们&#xff01;今天我们来聊聊如何在 Ubuntu 系统下通过 Docker 部署 Caddy 服务器。Caddy 是一个现代的 Web 服务器&#xff0c;支持自动 HTTPS&#xff0c;简单易用&#xff0c;特别适合快速搭建网站。而 Docker 则是一个让你可以隔离和管理应用的神器。结…

计算机网络•自顶向下方法:网络层介绍、路由器的组成

网络层介绍 网络层服务&#xff1a;网络层为传输层提供主机到主机的通信服务 每一台主机和路由器都运行网络层协议 发送终端&#xff1a;将传输层报文段封装到网络层分组中&#xff0c;发送给边缘路由器路由器&#xff1a;将分组从输入链路转发到输出链路接收终端&#xff1…

Linux top指令

top指令概述 top 是 Linux 系统中用于实时监控系统性能和进程信息的命令&#xff0c;功能强大且灵活。它提供了系统资源的动态视图&#xff0c;包括 CPU、内存、运行中的进程等。 这个指令可以说是Linux中最基本的工具了&#xff0c;用来监视系统的实时运行状态&#xff0c;类…

Qt监控系统放大招/历经十几年迭代完善/多屏幕辅屏预览/多层级设备树/网络登录和回放

一、前言说明 近期对视频监控系统做了比较大的更新升级&#xff0c;主要就是三点&#xff0c;第一点就是增加了辅屏预览&#xff0c;这个也是好多个客户需要的功能&#xff0c;海康的iVMS-4200客户端就有这个功能&#xff0c;方便在多个屏幕打开不同的视频进行查看&#xff0c…

网络原理(六): UDP 协议

目录 1. UDP 协议 1.1 协议特点 1.2 协议报文格式 1.2.1 UDP 长度 1.2.2 校验和 1. UDP 协议 在进行网络编程时, 我们已经对 UDP 协议进行了简单了解. 并且应用层的很多操作, 需要调用传输层的提供的接口, 基于 socket api 来进行完成的. 1.1 协议特点 UDP 协议具有以…

前端页面展示本电脑的摄像头,并使用js获取摄像头列表

可以通过 JavaScript 使用 navigator.mediaDevices.enumerateDevices() 获取电脑上的摄像头列表。以下是一个示例代码&#xff0c;可以展示摄像头列表并选择进行预览。 HTML JavaScript 实现摄像头列表展示和预览 <!DOCTYPE html> <html lang"zh-CN">…

【漫话机器学习系列】028.CP

Mallows’ Cp&#xff1a;标准化公式解析与应用 Mallows’ Cp 是一种常用的模型选择工具&#xff0c;用于在一系列候选模型中权衡拟合度和复杂性&#xff0c;帮助我们选择性能最优的模型。本文将基于其标准化公式展开详细解析&#xff0c;并探讨其应用场景、实现方法、优点与局…