afl-fuzz多线程

afl-fuzz多线程

  1. afl-fuzz多线程

    https://blog.csdn.net/lesliegail1/article/details/70209351

    首先,我们阅读这篇博客对afl-fuzz单机多线程进行了解。我们了解了命令格式如下:

    ./afl-fuzz -i input_dir -o sync_dir -M fuzzer01 ..
    ./afl-fuzz -i input_dir -o sync_dir -S fuzzer02 ..
    ./afl-fuzz -i input_dir -o sync_dir -S fuzzer03 ..
    

    其中,-M指定Master进程,-S指定Slave进程,一般只有一个Master进程,可以指定多个Slave进程。每一个fuzzer都在sync_dir文件夹中有一个单独的空间来存储其状态,如 /sync_dir/fuzzer01/
    至于,M/S是确定性变异还是havoc变异,实验过程中发现,默认均为havoc变异。我们可以使用-D对Master进程进行设置,只需要设置主进程即可。就像执行print(random.random())语句,使用20个进程同时运行的结果可能不同;但是对于执行print(1)语句,没有必要使用2个进程,因为结果都一样。

  2. 编程自动化实现
    为了使用多进程,我们需要打开多个窗口执行不同的fuzz命令,如果我们设置进程数为32及以上,我们希望能通过编程自动化实现。本程序的关键是多进程及对afl-fuzz命令的拼接,还有一些细节上的设计。

    #!/usr/bin/env python
    import subprocess, threading, time, shutil, os, sys
    from typing import List
    
    
    def locate(label):
        '''
        :param label:
        :return: the location of label in the cmd
        '''
        try:
            separate: int = sys_args.index(label)
        except:
            print(label, 'should be appeared in the command!')
            exit(-1)
        return separate
    
    
    def separate(sys_args: List[str]):
        label = "--"
        separate: int = locate(label)
        after_args = sys_args[separate + 1 :]
        return after_args
    
    
    def input_dir(sys_args: List[str]):
        label = "-i"
        separate: int = locate(label)
        return sys_args[separate + 1]
    
    
    def output_dir(sys_args: List[str]):
        label = "-o"
        separate: int = locate(label)
        return sys_args[separate + 1]
    
    
    def do_work(cpu, input_dir, output_dir, hours, after_args):
        deterministic_arg = "-D"
        master_arg = "-S"
        if cpu == 0:
            master_arg = "-M"
    
        try:
            with open("logs/fuzzer{}.log".format(cpu), "w+") as f:
                
                cmd = ["afl-fuzz", "-m", "none", "-t", "5000"]
                if cpu == 0:
                    cmd.extend([deterministic_arg])
                    input_dir = 'seeds_in'  # 这里对主进程的input_dir进行了单独设置,根据实验要求可进行删除哦
                else:
                    env_cmd = 'export AFL_FAST_CAL=1'
                    subprocess.call(env_cmd, shell=True)
    
                cmd.extend(["-i", input_dir])
                cmd.extend(["-o", output_dir])
                cmd.extend(["-V", "{}".format(hours * 3600)])
                cmd.extend(["-b", "%d" % cpu])  # bind cpu
                cmd.extend([master_arg, "fuzzer%d" % cpu])  # master and secondary fuzzers
                cmd.extend(after_args)  # targets: ./readelf -a
                cmd.extend(["@@"])  # @@
                sp = subprocess.Popen(cmd, stdout=f, stderr=f)
                sp.wait()
        except:
            print('When creating fuzzer{}, some errors were encountered!'.format(cpu))
    
        print("CPU %d afl-fuzz instance died" % cpu)
    
    
    if __name__ == '__main__':
        sys_args: List[str] = sys.argv[1:]
        after_args = separate(sys_args)
        input_dir = input_dir(sys_args)
        output_dir = output_dir(sys_args)
    
        num_cpus = 32
        hours = 12
    
        print('Next, we will start {} cpus to fuzz {} {} hours!'.format(num_cpus, after_args[0], hours))
    
        assert os.path.exists(input_dir), "Invalid input directory"  # judge whether the input directory exists
        os.path.exists("./logs") or os.mkdir("./logs")
        if os.path.exists(output_dir):
            shutil.rmtree(output_dir)  # delete recursively existing output_dir
        os.mkdir(output_dir)  # creating output directory
    
        # os.environ["AFL_NO_AFFINITY"] = "1"
        # 此环境变量被设置会禁止实例尝试绑定到Linux系统上的特定CPU 内核。这会减慢速度,但可以让您运行更多的afl-fuzz实例
        # os.environ["AFL_NO_ARITH"] = "1"
        # 此环境变量被设置会导致AFL跳过大多数确定性算术过程,这对于加速基于文件格式为文本的模糊测试很有用
    
        for cpu in range(0, num_cpus):
            print("creating fuzzer{}".format(cpu))
            threading.Thread(target=do_work, args=[cpu, input_dir, output_dir, hours, after_args]).start()
    
            # Let master stabilize first
            if cpu == 0:
                print("please wait a moment for main fuzzer to start up.")
                time.sleep(5.0)
    
        while threading.active_count() > 1:
            time.sleep(10)
    
            try:
                subprocess.check_call(["afl-whatsup", "-s", output_dir])
            except:
                pass
    
        print("fuzzing over, bye!")
    
  3. 使用说明
    本程序默认提供"-m none", “-t 5000"参数,不必添加这些参数了,”-i -o"为必选参数,其他参数可以自行添加。使用 “–” 作为分隔符,前面是关于afl-fuzz的参数,后面是待测程序及参数。执行命令示例如下:

    python multi_fuzz.py -i seeds_in -o seeds_out -- ./readelf -a
    

    考虑到输出种子较多,我们借助AFL_FAST_CAL环境变量将校准阶段的速度保持在2.5倍左右(尽管精度较低),这有助于针对慢速目标启动会话。

    export AFL_FAST_CAL=1
    

    我们可以写一个sh自动化脚本,保存为run.sh,一键启动。

    export AFL_FAST_CAL=1
    python multi_fuzz.py -i seeds_in -o seeds_out -- ./readelf -a
    

    如果需要运行,只需要在命令行输入sh run.sh即可。

  4. 实验结果在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值