论文分享 | 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=1∏nP(wi∣w1,w2,...,wi−1)
在推理阶段,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所示。
3.1 指导程序生成
论文选择ChatGPT和GPT-4作为大语言模型来指导模糊测试驱动程序生成,尽管模型生成的程序并不总能够严格遵循指令,但它们有助于探索有效的库程序接口调用情况,可以用提示词来引导大语言模型生成符合预期的程序。PromptFuzz使用目标库程序和接口函数组合填充提示词模板,如图2所示包含以下组件。
- 任务描述。说明了LLM应生成的驱动程序代码,指定了库程序的哪些接口函数在
LLVMFuzzerTestOneInput
函数中是必需的。 - 库程序上下文。包括了库程序使用的头文件,接口函数签名,自定义类型等信息,通过整合对库程序上下文的理解,显著减少LLM产生幻觉的发生。
- 库程序说明。指导LLM生成符合库程序所需指定模式的代码,部分库程序的接口函数可能从文件,文件流或描述符读取输入,对其进行相应规范。
3.2 错误程序验证
PromptFuzz消除错误驱动程序通过如下三个步骤。
- 删除C/C++编译器识别出语法错误的驱动程序。
- 剩余的驱动程序编译成可执行文件,结合多个运行时
sanitizers
,捕获和分析与预期行为模式的偏差。 - 使用提供的语料库对这些驱动程序进行模糊测试,删除检测到偏差的任何驱动程序。
在这部分模糊测试过程中,触发独特行为的输入将添加到语料库中,从而扩展进行更深入的运行时验证。PromptFuzz同时还会计算驱动程序执行的代码覆盖率,删除那些不符合代码覆盖标准的驱动程序,表明库程序的接口函数得到了充分的利用,错误驱动程序验证流程如图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))e1−cov(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))
用以量化驱动程序的质量,以质量值更高为目标来指导变异策略
在每次模糊测试迭代过程中,PromptFuzz都会探索驱动程序种子集合并更新这些种子驱动程序的质量,使用库程序接口函数能量和种子驱动程序质量的反馈,应用如图4所示算法来选择下一次迭代中使用的新接口函数组合。
3.4 变量约束的模糊器调度
为了使得种子驱动程序能够执行模糊测试,PromptFuzz对其中的接口函数参数进行约束类型推断,将部分参数从常量转换为从模糊测试器输入的任意字节的变量,例如数组长度、文件名、格式化字符串等,一个简单的实例如图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
相关文章:

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

AWS K8s 部署架构
Amazon Web Services(AWS)提供了一种简化的Kubernetes(K8s)部署架构,使得在云环境中管理和扩展容器化应用变得更加容易。这个架构的核心是AWS EKS(Elastic Kubernetes Service),它是…...

JavaSE笔记(四)
Java泛型与集合类 在前面我们学习了最重要的类和对象,了解了面向对象编程的思想,注意,非常重要,面向对象是必须要深入理解和掌握的内容,不能草草结束。在本章节,我们会继续深入了解,从我们的泛型开始,再到我们的数据结构,最后再开始我们的集合类学习。 走进泛型 为…...

C语言基础——指针(5)
一. 函数指针变量 1. 函数指针变量的定义: 类比数组指针变量,数组指针变量是存放数组地址的变量,那么同理,函数指针变量就是存放函数地址的变量。 2. 创建函数指针变量: 函数是有地址的࿰…...

curl+openssl 踩坑笔记
curl编译:点击跳转 踩坑一 * SSL certificate problem: unable to get local issuer certificate * closing connection #0 curl: (60) SSL certificate problem: unable to get local issuer certificate More details here: https://curl.se/docs/sslcerts.html …...

Unity 实现Canvas显示3D物体
新建一个UI相机,选择渲染层为UI 将主相机的渲染层去掉UI层 、 将Canvas的RenderMode设置为Screen Space - Camera,将RenderCamera设置为UI相机 新建3D物体的UI父物体,并将3D物体的层级设置为UI层 适当的放缩3DObjParent,让3D物体能显示出来…...

【Docker命令】如何使用`docker exec`在容器内执行命令
大家好,今天我们来聊聊Docker容器管理中的一个非常有用的命令:docker exec。在日常工作中,我们经常需要在运行中的Docker容器内执行各种命令,docker exec正是帮助我们实现这一需求的利器。下面我将通过一个简单的例子,…...

NetSuite Formula(HTML)超链打开Transaction
当Saved Search作为Sublist应用在Form时,如果Document Number是Group过的,则会出现如下超链失效的情况。 解决办法: 可以利用Saved Search中的Formula(HTML)功能来构建超链,用于打开Transaction。 以下图…...

【React】- 跨域PDF预览、下载(改文件名)、打印
我们经常会碰到跨域来方位PDF,同时需要下载、打印的需求,通常由于浏览器的安全策略,可以预览,但是下载和打印可能会受限,这时候怎么办呢? 1.创建一个隐藏的标签 要下载 iframe 中的 PDF 文件,…...

git clone ssh 设置代理
Linux配置方法 编辑 ~/.ssh/config 文件 Host github.com Hostname github.com ProxyCommand nc -v -x 127.0.0.1:1080 %h %pwindows配置方法 编辑 C:\Users\当前用户名.ssh\config 文件 Host github.com Hostname github.com ProxyCommand connect -S 127.0.0.1:1080 %h %…...

RK3568平台(USB篇)USB网络共享
使用RK的USB网络共享,在内核里面已经有了,这不需要自己写驱动程序,只需要把内核自带的USB网络共享的驱动添加上去即可。 一.RNDIS 协议简介 RNDIS 是微软定义的一种协议,它允许通过 USB 接口实现网络连接。通过 RNDIS,USB 设备可以充当网络适配器,允许主机通过 USB 与设…...

vite 打包时:JavaScript heap out of memory(内存溢出)
出错原因分析: 执行命令 npm run build 时出现以下错误提示: vite v3.2.7 building for production... 11:22:34 transforming (3) src\main.tsWARN Browserslist: caniuse…...

【服务器学习专栏 1.2 -- 带外管理】
请阅读 嵌入式学习必备专栏 文章目录 Overview服务器带外管理BMC 介绍BMC 特点BMC 工作原理 Overview 从技术的角度,网络管理可分为带外管理(out-of-band)和带内管理(in-band)两种管理模式。 带内管理,是指…...

微服务のGeteWay
目录 概念: 三大核心: 工作流程: 9527网关如何做路由映射: GetWay高级特性: 按服务名动态路由服务: 断言Route Predicate Factories : 获取当前时区时间: After Route &…...

html+css+js网页设计 美食 美食家6个页面
htmlcssjs网页设计 美食 美食家6个页面 网页作品代码简单,可使用任意HTML辑软件(如:Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作)。 获取源码 1…...

IntelliJ Idea常用快捷键详解
文章目录 IntelliJ Idea常用快捷键详解一、引言二、文本编辑与导航1、文本编辑2、代码折叠与展开 三、运行和调试四、代码编辑1、代码补全 五、重构与优化1、重构 六、使用示例代码注释示例代码补全示例 七、总结 IntelliJ Idea常用快捷键详解 一、引言 在Java开发中ÿ…...

服务器虚拟化:它是什么以及有什么好处?
运行虚拟服务器有助于创建更高效的 IT 基础架构。 随着业务每天收集的数据量逐年激增,传统的物理服务器已经无法单独满足业务需求。 相反,许多组织正在转向虚拟化的力量。 这是我们创建物理实体的虚拟版本的过程,在计算中,通常指…...

Python爬虫完整代码拿走不谢
对于新手做Python爬虫来说是有点难处的,前期练习的时候可以直接套用模板,这样省时省力还很方便。 使用Python爬取某网站的相关数据,并保存到同目录下Excel。 直接上代码: import re import urllib.error import urllib.request…...

MLA:多头潜在注意力
MLA:多头潜在注意力 多头潜在注意力(MLA)机制是一种在深度学习模型中用于处理序列数据的注意力机制的改进形式,以下是对其原理和示例的详细介绍: 原理 低秩键值联合压缩:MLA机制利用低秩键值联合压缩来消除注意力模块中的某些计算,从而提高模型的运行速度和性能。在传…...

阿里云大模型ACP高级工程师认证模拟试题
阿里云大模型ACP高级工程师认证模拟试题 0. 引言1. 模拟试题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题多选题单选题单选题单选题多选题多选题单选题多选题单…...

游戏引擎学习第67天
reviewing “apron”概念以更新区域 我们正在进行模拟区域的扩展工作,目标是通过增加一个更大的区域来支持更丰富的互动,尤其是那些可能超出摄像机视野的内容。现有的模拟区域包括摄像机能看到的区域和其周围的环境区域,但为了保证更高效的游…...

Nginx知识详解(理论+实战更易懂)
目录 一、Nginx架构和安装 1.1 Nginx 概述 1.1.1 nginx介绍 1.1.2?Nginx 功能介绍 1.1.3?基础特性 1.1.4?Web 服务相关的功能 1.2?Nginx 架构和进程 1.2.1?Nginx 进程结构 1.2.2?Nginx 进程间通信 1.2.3?Nginx 启动和 HTTP 连接建立 1.2.4?HTTP 处理过程 1…...

# 【鸿蒙开发】多线程之Worker的使用
【鸿蒙开发】多线程之Worker的使用 文章目录 【鸿蒙开发】多线程之Worker的使用前言一、Worker的介绍二、注意事项三、Worker使用示例1.新建一个Worker2.主线程使用Worker3.子线程Worker的使用 四、效果展示 前言 本文主要介绍了多线程的方法之一,使用Worker开启多…...

TKG-DM – 基于Latent Diffusion模型的“原生”色度提取生成具有透明通道的图像
概述 原文地址:https://www.unite.ai/improving-green-screen-generation-for-stable-diffusion/ 论文地址:https://arxiv.org/pdf/2411.15580 尽管社区研究和投资者对图像生成人工智能充满热情,但此类系统的输出并不总是可以直接用于产品开…...

告别 Windows 迟缓!多维度优化策略开启流畅新体验
在日常使用 Windows 系统的过程中,随着时间推移和软件安装卸载,系统可能会出现运行缓慢、卡顿等问题。本文中简鹿办公将详细介绍一系列 Windows 系统优化方法,涵盖多个关键层面,助力您的电脑重焕生机。 一、磁盘清理与优化 磁盘…...

亚马逊国际站商品爬虫:Python实战指南
在数字化时代,数据的价值不言而喻。对于电商领域而言,获取竞争对手的商品信息、价格、评价等数据,对于市场分析和策略制定至关重要。本文将带你了解如何使用Python编写爬虫,以亚马逊国际站为例,按照关键字搜索并获取商…...

RabbitMQ基础篇之Java客户端快速入门
文章目录 需求 项目设置与依赖管理 配置RabbitMQ的连接信息创建队列与消息发送创建消费者(消息接收)环境准备与操作 需求 利用控制台创建队列 simple.queue在 publisher 服务中,利用 SpringAMQP 直接向 simple.queue 发送消息在 consumer 服…...

深度学习:基于MindSpore NLP的数据并行训练
什么是数据并行? 数据并行(Data Parallelism, DP)的核心思想是将大规模的数据集分割成若干个较小的数据子集,并将这些子集分配到不同的 NPU 计算节点上,每个节点运行相同的模型副本,但处理不同的数据子集。…...

Qt6之QML——枚举
在 QML 中,枚举 (Enumeration) 是一种用于定义一组固定值的功能。通过枚举,可以便捷地提供一组可选值,使用更加明确和精简。 一、枚举的特点 固定值定义: 枚举可以预先定义一组字面值,通常用于需要定义限制值范围的场景…...

ModiLeo交易平台:引领数字货币交易新未来
在当今数字化高速发展的时代,数字货币作为一种新兴的金融资产形式,正逐渐改变着全球金融格局。而此刻,由印度 ModiLeo 实验室联合全球顶级投行共同打造的全球领先的一站式数字货币交易平台——ModiLeo 即将上线,这无疑是数字货币领…...