AFL模糊测试

使用 AFL++ 对 IoT 二进制文件进行模糊测试 - 第二部分 在中,我们研究了如何使用 AFL++ 对简单的物联网二进制文件进行模糊测试。这些程序接受来自文件的输入,并且易于模糊测试。在本文中,我们将研究套接字二进制文件。使用套接字进行网络通信的模糊测试二进制文件与使用基于文件 I/O 的模糊测试二进制文件不同。Vanilla AFL 和 AFL++ 不支持对套接字二进制文件进行模糊测试,尽管和等项目使用 AFL 的修改版本进行模糊测试。不过,本文我们将了解如何使用普通的 AFL++ 来模糊测试网络程序。httpd此处的二进制文件。 阅读详情

一、AFL

基于覆盖率, qemu llvm等多项技术的fuzzing工具
https://github.com/google/AFL

二、使用方法

2.1安装

make
make install

2.2编译目标程序

2.2.1 程序是用autoconf构建,那么此时只需要执行如下即可

CC=/usr/local/bin/afl-gcc CXX=/usr/local/bin/afl-g++ ./configure --disable-shared
make clean
make

2.2.2 程序不是用autoconf构建,那么直接修改Makefile文件中的编译器为afl-gcc/g++

为了后期更好的分析crash,在此处可以开启Address Sanitizer(ASAN)这个内存检测工具,此工具可以更好的检测出缓存区溢出、UAF 等内存漏洞,开启方法如下:

AFL_USE_ASAN=1 ./configure CC=afl-gcc CXX=afl-g++ LD=afl-gcc--disable-shared
AFL_USE_ASAN=1 make

2.2.3 llvm 模式
普通模式可能造成部分可执行文件编译后运行异常。所以可以 apt install llvm clang afl 增加 afl-clang-fast/afl-clang-fast++。

编译方式

$ cd llvm_mode
$ apt-get install clang
$ export LLVM_CONFIG=`which llvm-config` && make && cd ..
$ ./configure --disable-shared CC="afl-clang-fast" CXX="afl-clang-fast++"

2.2.4 screen多实例启动

echo core >/proc/sys/kernel/core_pattern

screen afl-fuzz -i testcase_dir -o findings_dir /path/to/program @@

screen [-AmRvx -ls -wipe][-d <作业名称>][-h <行数>][-r <作业名称>][-s <shell>][-S <作业名称>]

# screen -ls  //显示已创建的screen终端 
There are screens on:
2433.pts-3.linux    (2013年10月20日 16时48分59秒)    (Detached)
2428.pts-3.linux    (2013年10月20日 16时48分05秒)    (Detached)
2284.pts-3.linux    (2013年10月20日 16时14分55秒)    (Detached)
2276.pts-3.linux    (2013年10月20日 16时13分18秒)    (Detached)
4 Sockets in /var/run/screen/S-root.

# screen -r 2276 //连接 screen_id 为 2276 的 screen终端

并行测试

cat /proc/cpuinfo\| grep "cpu cores"\| uniq

afl-fuzz并行Fuzzing,一般的做法是通过-M参数指定一个主Fuzzer(Master Fuzzer)、通过-S参数指定多个从Fuzzer(Slave Fuzzer)。

$ screen afl-fuzz -i testcases/ -o sync_dir/ -M fuzzer1 -- ./program
$ screen afl-fuzz -i testcases/ -o sync_dir/ -S fuzzer2 -- ./program
$ screen afl-fuzz -i testcases/ -o sync_dir/ -S fuzzer3 -- ./program
  ...

afl-whatsup工具可以查看每个fuzzer的运行状态和总体运行概况,加上-s选项只显示概况,其中的数据都是所有fuzzer的总和。

afl-whatsup -s syncdir

还afl-gotcpu工具可以查看每个核心使用状态。

语料输入改进

经过试用,发现@@参数会把变异后的语料路径传递给argv, 所以采用文件读取的方式可以重构参数。

#define AFL_INIT_ARGV(p) do { argv = afl_init_argv_f(&argc, argv, p); } while (0)

#define AFL_INIT_SET0(_p) do { \
    argv = afl_init_argv(&argc); \
    argv[0] = (_p); \
    if (!argc) argc = 1; \
  } while (0)

#define MAX_CMDLINE_LEN 100000
#define MAX_CMDLINE_PAR 1000

static char** afl_init_argv_f(int* argc, char *argv[], char *redch) {

    static char    in_buf[MAX_CMDLINE_LEN] = {0};
    static char* ret[MAX_CMDLINE_PAR];
    char buffer[1024];
    char* ptr = in_buf, *p;
    int rc = 0;
    int len = 0, flag = 0;
    char * tmp = redch;
    /*打开重定向文件,获取输入变异字节*/
    int in;
    if(argv[1]==NULL)
        return 0;
    in = open(argv[1], O_RDONLY, S_IRUSR);
    if (-1 == in) // 打开文件失败,则异常返回
    {
        printf("corpus open failed \n");
        return NULL;
    }
    printf("open file success %s\n", argv[1]);                                                             
     /*改变第一参数     edit*/
    len = strlen(argv[0]);
    memcpy(ptr, argv[0], len);
    ptr = ptr+len;
   *ptr = 0x0;
   ptr++;
   if(tmp){
         len = strlen(tmp);
          memcpy(ptr, tmp, len);
          ptr = ptr+len+1;
    }
    p = ptr;
    printf("first \n");
    /*缓存文件内容*/
    if ((flag = read(in, buffer, 1024)) > 0){                                                                memcpy(p, buffer, flag);
        p = p + flag + 1;
                                                                                                      }
   close(in);
   printf("读取文件成功 \n");
   /*重构参数    argv */
   ptr = in_buf;
   while (*ptr) {
        ret[rc] = ptr;
        if (ret[rc][0] == 0x02 && !ret[rc][1]) ret[rc]++;
            rc++;
        while(*ptr){
            if(*ptr == 0x20){
                *ptr == 0x0;
                break;
            }
            //if(*ptr==0xa){
              //  *ptr = 0x0;
            //    goto error;
            //}
            ptr++;
       }
       ptr++;
   }
     *argc = rc;
    for(int j = 0; j< rc; j++){
        if(strstr(ret[j], "-")&&strlen(ret[j]>2)){
            goto error;
        }
    }
     return ret;

error:
    return NULL;
}


经过上述参数构造,可以方便的获取语料变异数据。

这块很容易影响整个fuzzer的效率,还是最好不变不加@@参数。

#define AFL_INIT_ARGV() do { argv = afl_init_argv(&argc); } while (0)

#define AFL_INIT_SET0(_p) do { \
    argv = afl_init_argv(&argc); \
    argv[0] = (_p); \
    if (!argc) argc = 1; \
  } while (0)

#define MAX_CMDLINE_LEN 100000
#define MAX_CMDLINE_PAR 1000

static char** afl_init_argv(int* argc) {

  static char  in_buf[MAX_CMDLINE_LEN];
  static char* ret[MAX_CMDLINE_PAR];

  char* ptr = in_buf;
  int   rc  = 0;

  if (read(0, in_buf, MAX_CMDLINE_LEN - 2) < 0);

  while (*ptr) {

    ret[rc] = ptr;
    if (ret[rc][0] == 0x02 && !ret[rc][1]) ret[rc]++;
    rc++;

    while (*ptr) ptr++;
    ptr++;

  }

  *argc = rc;

  return ret;

}

#undef MAX_CMDLINE_LEN
#undef MAX_CMDLINE_PAR
#define AFL_INIT_ARGV() do { argv = afl_init_argv(&argc, argv); } while (0)

#define AFL_INIT_SET0(_p) do { \
    argv = afl_init_argv(&argc); \
    argv[0] = (_p); \
    if (!argc) argc = 1; \
  } while (0)

#define MAX_CMDLINE_LEN 100000
#define MAX_CMDLINE_PAR 1000

static char** afl_init_argv(int* argc, char * argv[]) {

  static char  in_buf[MAX_CMDLINE_LEN];
  static char* ret[MAX_CMDLINE_PAR];
  char * arg0 = argv[0];
  char* ptr = in_buf;
  int   rc  = 1;
  int len;
  ret[0] = ptr;

  len = strlen(arg0);
  memcpy(ptr, arg0, len);
  ptr = ptr + len;
  memcpy(ptr, "\0", 1);

  ptr = ptr + 1;
  if (read(0, ptr, MAX_CMDLINE_LEN - 2 - len -1) < 0);

  while (*ptr) {

    ret[rc] = ptr;
    if (ret[rc][0] == 0x02 && !ret[rc][1]) ret[rc]++;
    rc++;

    while (*ptr) {
        if(*ptr == 0x20){
             *ptr = 0x0;
             break;
        }
        if(*ptr == 0xa){
            *ptr = 0x0;
            break;
        }
        ptr++;

    }
    ptr++;

  }
  *ptr = 0x0;
  *argc = rc;

  return ret;

}

#undef MAX_CMDLINE_LEN
#undef MAX_CMDLINE_PAR

int writetag(int argc, char *argv[]){
    char *s;//”Linux Programmer!\n”;
    int i, fd;
    fd=open("/tmp/temp",O_WRONLY|O_APPEND);
    for(i = 0; i < argc; i++){
       s = argv[i];
       printf("arg %d %s \n", i, s, strlen(s));
       write(fd, s, strlen(s));
       write(fd, " ", 1);
    }
    write(fd, "\n", 1);
    close(fd);
}

fuzz造成的僵尸进程,清理下

# -*- coding:utf-8 -*-
import os
import re
import psutil
import time
print('------')
# os.popen() 调用 read() 方法有返回值
while(1):
    procs = psutil.pids()
    for i in procs:
        if(i in psutil.pids()):
            p = psutil.Process(i)
            t = p.cpu_times().user
            if(p.name()=="vi" and t > 0.30):
               print(p.name() + " pid: %d"%i)
               print(p.cpu_times().user)
               os.system('kill -9 %d'%i)
    time.sleep(10)

解析crash结果

#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
void main()
{
    int fd,size,rc=0,i=0,j=0;

    char *ret[50],*ptr;
    char s[]="Linux Programmer!\n", buffer[50];
    fd=open("/tmp/temp",O_RDONLY);
    size=read(fd, buffer, sizeof(buffer));

    ptr = buffer;
    for(i = 0;i < size;i++){
        printf("(%d)%02x", i, buffer[i]&0xff);

    }
    printf("\n");
     while (*ptr) {
        ret[rc] = ptr;
        rc++;
           
        for (;*ptr;ptr++) { 
            if(*ptr == 0x20){
                 *ptr = 0x0;
                break;
            } 
            if(*ptr == 0xa){
               *ptr = 0x0;
                break;
            }
       }
        ptr++;
  
    }
     
     ptr= buffer;
    for(i = 0; i < rc;i++){
        printf("arg %d %s \n", i, ret[i]);
       for(j=0;j<strlen(ret[i]);j++){
           printf("%02x ",*(ret[i]+j));
       }
       printf("\n");
    }
    close(fd);
}

参考:https://paper.seebug.org/841/

基于AFL对Linux内核模糊测试的过程详述 现在来说说,如何实际运行我们构建的自定义内核,目前共有三个选项:“本地”选项:你可以完全在你的服务器上启动构建的内核,并在本地对其进行模糊处理。这是最快的技术,但是问题很多。如果模糊测试成功地找到了一个漏洞,你的设备很可能会崩溃,从而丢失测试数据。“uml” :我们可以将内核配置为以用户模式Linux运行,运行UML内核不需要任何特权。内核只运行一个用户空间进程。UML非常酷,但遗憾的是,它不支持KASAN,因此发现内存损坏漏洞的机会减少了。 阅读详情

相关推荐

AMSR-2数据下载实战:从JAXA到LPRM的算法选择与效率优化

本文详细介绍了AMSR-2数据的下载实战,重点对比了JAXA与LPRM算法的差异及适用场景,并提供了高效下载方案和网络优化策略。通过实际案例和代码示例,帮助用户快速获取和处理AMSR-2数据,提升研究效率。

rl6adventurer的博客 691

利用AFL进行模糊测试

1 模糊测试概述 1.1 模糊测试概念 模糊测试(Fuzzing),是一种通过向目标系统提供非预期的输入并监视异常结果来发现软件漏洞的方法。它是一种挖掘软件安全漏洞、检测软件健壮性的黑盒测试,它通过向软件输入非法的字段,观测被测试软件是否异常而实现。 1.2 模糊测试优势 进行软件漏洞挖掘时,通常有静态分析(Static Analysis)、动态分析(Dynamic Analysis)、符号执行(Symbolic Execution)、模糊测试(Fuzzing)这几种技术手段。 静态分析(Static An

rocsoft 1万+

Spring Boot 实现多图片上传并回显,涨姿势了~

上传 Controller的代码非常简单,由于用了SpringMVC框架,所以直接用MultipartFile来接即可。由于是多图片上传所以用数组来接。此处应该注意参数名应该和<input>中的name值相对应: @RequestMapping("/pic") @ResponseBody publicResponseEntity<String>pic(MultipartFile[]pictures)throwsException{ ResponseEnti...

weixin_54556126的博客 894

超详细AFL模糊测试实战,手把手教学

介绍 AFL模糊测试框架的使用方法,使用AFL模糊测试软件或者1000行以上的代码, (1) 构造或选用合适的字典; (2)使用多核并行测试,需要给虚拟机分配多个核; (3)使用动态内存错误检查器,如ASAN等;

m0_60363092的博客 2万+

从零开始:手把手教你设计DP接口电路(含原理图实战)

本文是一份详尽的DisplayPort接口电路设计实战指南。文章从DP接口的核心架构与HDMI的差异讲起,手把手解析了高速差分对、AUX辅助通道、热插拔检测等关键模块的原理图设计要点,并提供了一个完整的DP Source端原理图实例,最后总结了PCB布局与信号完整性的核心考量,旨在帮助硬件工程师高效、稳定地完成DP接口电路设计。

transformer2023的博客 735

【全网最全最详细】智能体提示词prompt教程

定义:提示词是用户输入给AI模型(如ChatGPT、MidJourney等)的指令或问题,用于引导模型生成特定类型的输出。它是用户与AI交互的核心媒介。作用:提示词的质量直接影响AI输出的准确性和相关性。好的提示词能明确任务边界、减少歧义,并激发模型的创造力。提示词就是“给AI下指令的说明书”——越清楚、越具体,AI干得越好!帮你更快、更准地拿到想要的结果,不用和AI“猜谜语”。

qq_38196449的博客 8220

linux-screen命令

多窗口运行名,后台运行命令 创建窗口 screen 创建窗口并执行命令 screen vi ~/main.c 离开 screen 窗口 Ctrl+a 然后 d 显示已创建的screen窗口 screen -ls There are screens on: 2433.pts-3.linux (2013年10月20日 16时48分59秒) (Detached) 2428.pts-3.linux (2013年10月20日 16时48分05秒) (Detached) 2284.pts

Java 477

ZYNQ-7035+HMCAD1511高速数据采集系统设计

高速数据采集是电子测量、雷达信号处理与通信基带验证的核心技术基础,其性能瓶颈常集中于采样率、通道同步性与实时处理能力。基于ADC采样原理与SoC异构架构,高带宽、低抖动时钟链路与FPGA+ARM协同处理成为突破关键。ZYNQ-7035凭借275K逻辑单元与千级DSP资源,显著提升LVDS数据流吞吐与片上滤波/触发等实时算法部署能力;HMCAD1511则以1GSPS四通道同步采样和8位分辨率,满足示波器级动态范围需求。该组合广泛应用于嵌入式信号采集平台开发、教学实验系统构建及国产化仪器原型验证。

weixin_28939623的博客 262

【linux】screen命令

在服务器上搭建一些服务的时候,经常要用到screen命令。某些服务开启的时候需要占据一整个控制台,如果关闭了就会导致进程终止。这就成了类似单进程的效果。而screen命令就是为了能够在服务器上开启多个控制面板(screen),用以容纳不同的任务。

rocking_struggling的博客 3678

Orange3实战教程:文本挖掘---主题建模

主题建模通过LDA、LSI或HDP算法分析文档集合,自动发现隐含主题结构。组件输入为文档语料库,输出包括带主题权重的语料库、主题词分布及完整主题数据。不同算法特性各异:LSI允许正负权重但解释性较弱,LDA更易解释,HDP参数复杂需谨慎设置。结果可结合词云、热力图等可视化工具分析主题特征及分布。示例显示如何通过预处理文本、选择算法(如提取5个LDA主题),并利用MDS和箱线图探索主题间关系及关键词分布。

err2008的专栏 364

【STK】手把手教你利用STK进行导弹和反导仿真02 - STK/MMT模块01 导弹任务分析工具概述

种工具:导弹设计工具(Missile Design Tool,MDT )、导弹飞行工具(Missile Flight Tool,截弹,或者用内置拦截弹编辑器创建的个性化的拦截弹, IFT 能够对 ―一对一 ‖动能拦截。导设置系统参数, 并对其有效性进行验证, 画性能图,保证该设计是可行的。(SAIC)公司联合开发研制,极大扩展了 STK 原有的导弹对象的功能,能够精确仿真。IFT 能够对拦截飞机、 导弹、卫星等目标进行仿真和分析。(2)推进系统参数,包括推力,比冲,秒流量,推力持续时间,喷嘴出口面积,

weixin_44184852的博客 1877

经典 Fuzzer 工具 AFL 模糊测试指南

AFL(American Fuzzy Lop)是由安全研究员Michał Zalewski 开发的一款基于覆盖引导(Coverage-guided)的模糊测试工具。通过记录输入样本的代码覆盖率,不断对输入进行变异,从而达到更高的代码覆盖率。AFL 采用新型的编译时插桩和遗传算法自动发现新的测试用例,这些用例会触发目标二进制文件中的新内部状态。这大大改善了模糊测试的代码覆盖范围。 从源码编译程序时...

个人笔记 1万+

基于PCL的电力线点云提取与分割实现

本文基于PCL库实现电力线点云提取与分割,包含6个核心处理阶段:文件读取与结果文件夹创建、高程滤波分割候选点云、欧式聚类去噪、电力线分段提取、球形邻域搜索补全点云、最终分割与可视化保存。通过PCA计算点云线性特征(阈值0.91)筛选电力线点,采用欧式聚类(容忍度3.0)去除噪点,并针对不同规模聚类差异化设置球形搜索半径(4.0/6.0)补全点云。最终通过欧式聚类分割并可视化带颜色点云。算法对高程滤波阈值、聚类参数等具有敏感性,需根据点云特性调整优化。

weixin_45196569的博客 192

AFL--模糊测试使用浅析

AFL(American Fuzzy Lop)是由安全研究员Micha Zalewski 开发的一款基于覆盖引导(Coverage-guided)的模糊测试工具,它通过记录输入样本的代码覆盖率,从而调整输入样本以提高覆盖率,增加发现漏洞的概率。

蚁景网安学院 3297

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

模糊测试入门案例,利用AFL和Honggfuzz模糊测试Tiff

模糊测试入门案例,利用AFL(包括AFL的修剪测试用例功能)和Honggfuzz模糊测试Tiff。

weixin_50972562的博客 7935

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

【工具】AFL+Unicorn|二进制程序模糊测试工具 AFL 和 Unicorn 的前世今生、安装以及 Python 使用实例

这篇文章参与华中大开源俱乐部开源工坊的“模糊测试理论与工具实践”分享,关于挖掘二进制程序漏洞。本篇没讲太技术细节的东西,就是简单介绍下工具的使用方式,便于分享后给同学们进行查漏补缺。

shandianchengzi的博客 3218

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

模糊测试—AFL——实战小记

在。

Che_Che_的博客 1755

AFL模糊测试学习(一)源码插桩

先简单介绍一下. 刚接触模糊测试肯定是要从现在最为流行的AFL开始,现在很多关于AFL的改进都是针对AFL的,而且AFL本身因为其遗传算法、高吞吐量而得到很好的应用,在一些AFL变异版本(如AFLGO、PFuzz、CollAFL、ENFuzz等)、混合模糊测试(结合模糊测试和符号化执行)在实验对比中都拿AFL当作baseline。我们就一步一步从AFL本身学起,对模糊测试进行深入学习吧。 对一个程...

m0_37907383的博客 4084

AFL模糊测试学习(三)AFL运行

以使用afl-gcc进行插桩后的AFL运行为例。我们来学习AFL的运行。main函数中首先识别参数opt = getopt(argc, argv,"+i: o: f: m: t: T: d: n: C: B: S:M: x: Q")。然后在setup_shm()这个函数中初始化MAP_SIZE(2^16)大小的map用来父进程子进程间的信息共享。然后perform_dry_run()这个函数把初始...

m0_37907383的博客 3029

模糊测试工具AFL源码浅析

AFL是一款著名的模糊测试的工具,最近在阅读AFL源码,记录一下,方便以后查阅。

蚁景网安学院 1556

模糊测试-AFL学习笔记之Java

AFL简介 AFL(American Fuzzy Lop)是由安全研究员Michał Zalewski(@lcamtuf)开发的一款基于覆盖引导(Coverage-guided)的模糊测试工具,它通过记录输入样本的代码覆盖率,从而调整输入样本以提高覆盖率,增加发现漏洞的概率。其工作流程大致如下: ①从源码编译程序时进行插桩,以记录代码覆盖率(Code Coverage); ②选择一些输入文件,作为初始测试集加入输入队列(queue); ③将队列中的文件按一定的策略进行“突变”; ④如果经过变异文件

关注网络安全、云原生安全 3315

对Rust程序使用AFL工具进行模糊测试

网上有很多关于对c程序使用afl进行fuzz的文章,但没有一篇文章讲到如何对一个rust程序使用afl进行模糊测试(本人是做相关课题的),在仔细阅读了官方文档以及翻阅了大量的资料后,成功地跑起了afl。因此决定自己写一篇相关文章

weixin_58311792的博客 822

使用 afl-fuzz 进行模糊测试

话虽如此,重要的是要承认,如果没有大量的调试和代码分析工作,一些fuzzing崩溃可能难以快速评估可利用性。如果相关的执行路径涉及之前记录的故障中未出现的任何状态转换,则崩溃和挂起被认为是“唯一的”。在这种模式下,fuzzer将一个或多个崩溃测试用例作为输入,并使用其反馈驱动的模糊测试策略非常快速地枚举程序中可以到达的所有代码路径,同时保持程序处于崩溃状态。如果有大量数据可用于筛选,您可能需要使用afl-cmin实用程序来识别功能不同的文件的子集,这些文件在目标二进制文件中使用不同的代码路径。...

子曰小玖的博客 1293

FUZZ模糊测试学习-AFL源码(一)

刚接触模糊测试肯定是要从现在最为流行的AFL开始,现在很多关于AFL的改进都是针对AFL的,而且AFL本身因为其遗传算法、高吞吐量而得到很好的应用,在一些AFL变异版本(如AFLGO、PFuzz、CollAFL、ENFuzz等)、混合模糊测试(结合模糊测试和符号化执行)在实验对比中都拿AFL当作baseline。我们就一步一步从AFL本身学起,对模糊测试进行深入学习吧。对一个程序进行模糊测试我们需要做到以下几点:1、能够变异很多的测试样例,把种子(测试样例)进行自生产。

m0_73683501的博客 978
上一篇: sudo CVE-2021-3156 攻击利用
下一篇: runc rootless模式代码解析---创建dev设备节点文件
inquisiter
博客等级 码龄10年 374粉丝 228原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值