欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 锐评 > ProFuzzBench入门教学——使用(Ubuntu22.04)

ProFuzzBench入门教学——使用(Ubuntu22.04)

2025/5/19 21:51:50 来源:https://blog.csdn.net/weixin_45100742/article/details/140098508  浏览:    关键词:ProFuzzBench入门教学——使用(Ubuntu22.04)
  • ProFuzzBench是网络协议状态模糊测试的基准测试。它包括一套用于流行协议(例如 TLS、SSH、SMTP、FTP、SIP)的代表性开源网络服务器,以及用于自动执行实验的工具。
  • 详细参考:阅读笔记——《ProFuzzBench: A Benchmark for Stateful Protocol Fuzzing》-CSDN博客
  • 环境:Ubuntu22.04(WSL)

1、设置环境变量

  • 克隆项目,设置环境变量。
    • git clone https://github.com/profuzzbench/profuzzbench.git
      cd profuzzbench
      nano ~/.bashrc
  • 添加下面内容。 
    • # profuzzbench
      export PFBENCH=/home/zzs/GitProject/profuzzbench
      export PATH=$PATH:$PFBENCH/scripts/execution:$PFBENCH/scripts/analysis
  • 重新加载配置文件以使更改生效。
    • source ~/.bashrc

2、构建docker镜像

  • 安装docker,参考:Docker——简介、安装(Ubuntu22.04)-CSDN博客
  • 构建docker镜像。
    • cd $PFBENCH
      cd subjects/FTP/LightFTP
      sudo docker build . -t lightftp
      # docker build .:在当前目录(LightFTP)下寻找 Dockerfile 并构建 Docker 镜像
      # -t lightftp:将创建的 Docker 镜像标记为 lightftp
    • 【注】这里创建了一个名为 lightFTP 的 Docker 镜像,该镜像包含了 LightFTP 及其所需的所有依赖项,使其可以在隔离的 Docker 容器中运行。这对于模糊测试和代码覆盖率收集特别有用,因为它提供了一个一致的、可重复的测试环境。
    • 构建时间较长,耐心等待。
    • 【注】可能遇到网络不好,多尝试。
  • 查看构建的镜像。
    • docker images

3、运行模糊测试

  • 运行‘profuzzbench_exec_common.sh’脚本以启动实验。该脚本接受以下 8 个参数:
    • 第一个参数 (DOCIMAGE):Docker镜像的名称。
    • 第二个参数 (RUNS):运行次数,每次运行都会启动一个独立的Docker容器。
    • 第三个参数 (SAVETO):存储结果的文件夹路径。
    • 第四个参数 (FUZZER):模糊测试工具的名称(例如,aflnet)——该名称必须与Docker容器内模糊测试工具文件夹的名称匹配(例如,/home/ubuntu/aflnet)。 
    • 第五个参数 (OUTDIR):在Docker容器内创建的输出文件夹的名称。
    • 第六个参数 (OPTIONS):除目标特定的run.sh脚本中写入的标准选项外,所有模糊测试所需的选项。
    • 第七个参数 (TIMEOUT):模糊测试的时间(以秒为单位)。
    • 第八个参数 (SKIPCOUNT):用于计算随时间变化的覆盖率。例如,SKIPCOUNT=5表示我们在每5个测试用例后运行一次gcovr,因为gcovr需要时间,我们不希望在每个测试用例后都运行它。
  • 以下命令运行一个AFLNet实例,对LightFTP进行60分钟模糊测试。
    • cd $PFBENCH
      mkdir results-lightftp
      profuzzbench_exec_common.sh lightftp 1 results-lightftp aflnet out-lightftp-aflnet "-P FTP -D 10000 -q 3 -s 3 -E -K -R" 3600 5

4、收集结果

  • 所有结果(在 tar 文件中)都应存储在上个步骤(results-lightftp)创建的文件夹中。
  • 具体来说,这些tar文件是所有模糊测试实例生成的输出文件夹的压缩版本。如果模糊测试器是基于AFL的(例如,AFLNet,AFLnwe),每个文件夹应包含诸如 crashes、hangs、queue 等子文件夹。
  • 使用profuzzbench_generate_csv.sh脚本可以收集代码覆盖率随时间变化的结果。该脚本需要以下5个参数:
    • 第一个参数 (PROG):目标程序的名称(例如,lightftp)。
    • 第二个参数 (RUNS):运行次数。
    • 第三个参数 (FUZZER):模糊测试器的名称(例如,aflnet)。
    • 第四个参数 (COVFILE):用于保存结果的 CSV 格式的输出文件。
    • 第五个参数 (APPEND):追加模式;对第一个模糊测试器设置为0,对后续的模糊测试器设置为1。
  • 以下命令收集AFLNet生成的代码覆盖率结果,并将其保存到results.csv。
    • cd $PFBENCH/results-lightftp
      profuzzbench_generate_csv.sh lightftp 1 aflnet results.csv 0
  • results.csv文件如下。该文件有六列,分别显示:
    • 时间(time)
    • 目标程序(subject)
    • 模糊测试器名称(fuzzer)
    • 运行索引(run)
    • 覆盖类型(cov_type)
    • 覆盖率(cov)
  • 文件包含了随时间变化的行覆盖率(l_per、l_abs)分支覆盖率(b_per、b_abs)信息。每种覆盖类型都有两个值,一个是百分比形式(_per),另一个是绝对数值(_abs)。
    • 【注】这里时间为空,暂不知道什么原因。

5、分析结果

  • results.csv中收集的结果可用于绘图。例如,使用示例python脚本绘制代码随时间变化的覆盖率。使用以下命令打印结果并将其保存到文件中。
    • cd $PFBENCH/results-lightftpprofuzzbench_plot.py -i results.csv -p lightftp -r 4 -c 60 -s 1 -o cov_over_time.png
    • 报错:IndexError: index 0 is out of bounds for axis 0 with size 0。
      • 原因是因为文件中time为空,并且只有一个模糊测试器。
  • 改使用aflnwe。删除原先的results-lightftp。
    • cd $PFBENCHrm -rf resluts-lightftpmkdir results-lightftp
      profuzzbench_exec_common.sh lightftp 1 results-lightftp aflnwe out-lightftp-aflnwe "-D 10000 -K" 3600 5cd $PFBENCH/results-lightftp
      profuzzbench_generate_csv.sh lightftp 1 aflnwe results.csv 0
      cat results.csv
  • 修改profuzzbench_plot.py。
    • #!/usr/bin/env pythonimport argparse
      from pandas import read_csv
      from pandas import DataFrame
      from pandas import Grouper
      from matplotlib import pyplot as plt
      import pandas as pddef main(csv_file, put, runs, cut_off, step, out_file):# Read the resultsdf = read_csv(csv_file)# Calculate the mean of code coveragemean_list = []for subject in [put]:fuzzer = 'aflnwe'  # Only use aflnwefor cov_type in ['b_abs', 'b_per', 'l_abs', 'l_per']:# Get subject & fuzzer & cov_type-specific dataframedf1 = df[(df['subject'] == subject) & (df['fuzzer'] == fuzzer) & (df['cov_type'] == cov_type)]mean_list.append((subject, fuzzer, cov_type, 0, 0.0))for time in range(1, cut_off + 1, step):cov_total = 0run_count = 0for run in range(1, runs + 1, 1):# Get run-specific data framedf2 = df1[df1['run'] == run]if df2.empty:continue# Get the starting time for this runstart = df2.iloc[0, 0]# Get all rows given a cutoff timedf3 = df2[df2['time'] <= start + time * 60]if df3.empty:continue# Update total coverage and #runscov_total += df3.tail(1).iloc[0, 5]run_count += 1# Add a new rowif run_count > 0:mean_list.append((subject, fuzzer, cov_type, time, cov_total / run_count))# Convert the list to a dataframemean_df = pd.DataFrame(mean_list, columns=['subject', 'fuzzer', 'cov_type', 'time', 'cov'])fig, axes = plt.subplots(2, 2, figsize=(20, 10))fig.suptitle("Code coverage analysis")for key, grp in mean_df.groupby(['fuzzer', 'cov_type']):if key[1] == 'b_abs':axes[0, 0].plot(grp['time'], grp['cov'])axes[0, 0].set_xlabel('Time (in min)')axes[0, 0].set_ylabel('#edges')if key[1] == 'b_per':axes[1, 0].plot(grp['time'], grp['cov'])axes[1, 0].set_ylim([0, 100])axes[1, 0].set_xlabel('Time (in min)')axes[1, 0].set_ylabel('Edge coverage (%)')if key[1] == 'l_abs':axes[0, 1].plot(grp['time'], grp['cov'])axes[0, 1].set_xlabel('Time (in min)')axes[0, 1].set_ylabel('#lines')if key[1] == 'l_per':axes[1, 1].plot(grp['time'], grp['cov'])axes[1, 1].set_ylim([0, 100])axes[1, 1].set_xlabel('Time (in min)')axes[1, 1].set_ylabel('Line coverage (%)')for i, ax in enumerate(fig.axes):ax.legend(('AFLNwe',), loc='upper left')  # Only AFLNweax.grid()# Save to fileplt.savefig(out_file)# Parse the input arguments
      if __name__ == '__main__':parser = argparse.ArgumentParser()parser.add_argument('-i', '--csv_file', type=str, required=True, help="Full path to results.csv")parser.add_argument('-p', '--put', type=str, required=True, help="Name of the subject program")parser.add_argument('-r', '--runs', type=int, required=True, help="Number of runs in the experiment")parser.add_argument('-c', '--cut_off', type=int, required=True, help="Cut-off time in minutes")parser.add_argument('-s', '--step', type=int, required=True, help="Time step in minutes")parser.add_argument('-o', '--out_file', type=str, required=True, help="Output file")args = parser.parse_args()main(args.csv_file, args.put, args.runs, args.cut_off, args.step, args.out_file)
  • 重新执行:
    • cd $PFBENCH/results-lightftpprofuzzbench_plot.py -i results.csv -p lightftp -r 4 -c 60 -s 1 -o cov_over_time.png

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词