Driller分析与改进(二)

  • Author:ZERO-A-ONE
  • Date:2021-03-20

这个部门我们主要介绍Driller的安装与使用,我使用的环境是腾讯云的VPS:

  • CPU:Intel® Xeon® Platinum 8255C CPU @ 2.50GHz * 4vCPUs
  • RAM:4GB
  • OS:Ubuntu 18.04 LTS

一、安装

首先我们需要安装一些必备的库

$ sudo apt-get install build-essential libtol-bin automake bison flex python libglib2.0-dev build-dep qemu-system libacl1-dev python3 python3-pip python3-dev git libssl-dev libffi-dev
$ sudo apt-get install build-essential gcc-multilib libtool automake autoconf bison debootstrap debian-archive-keyring libtool-bin python3-dev libffi-dev virtualenvwrapper git wget 
$ sudo apt-get install build-essential gcc-multilib libtool automake autoconf bison debootstrap debian-archive-keyring libtool-bin
$ sudo apt-get build-dep qemu

1.1 安装AFL

我们为了方便安装,建议新建一个文件夹来保存所有的过程文件

$ mkdir driller && cd driller

然后从GitHub上可以下载AFL源码:

$ git clone https://github.com/google/AFL.git

然后进入源码文件夹:

$ cd AFL

执行编译命令:

$ sudo make -j4

编译QEMU模式支持:

$ ./build_qemu_support.sh

1.2 安装Driller

在安装与使用Driller时,最好在一个单独的Python虚拟环境中进行,我在这里使用的是Aconda环境

1.2.1 安装Aconda

先安装一些必备的库

$ sudo apt-get install python3 python3-pip python3-dev git libssl-dev libffi-dev build-essential

然后从官网里面下载Anaconda的安装脚本

$ wget https://repo.anaconda.com/archive/Anaconda3-2020.11-Linux-x86_64.sh

然后给脚本赋予执行权限

$ chmod +x Anaconda3-2020.11-Linux-x86_64.sh

然后运行安装脚本即可

$ ./Anaconda3-2020.11-Linux-x86_64.sh

这里不建议使用root权限安装,如果你自己使用的用户就不是root账户的话

这里如果出现找不到conda命令的情况可能需要手动修改shell的环境配置

$ sudo vim ~/.bashrc

然后就修改为类似这样的实际安装路径

export PATH="/home/ubuntu/anaconda3/bin:$PATH"

然后刷新重新运行

$ source ~/.bashrc
1.2.2 建立Driller虚拟环境

使用Aconda建立一个名字叫做driller的虚拟环境

$ conda create -n driiler python=3.8

然后进入虚拟环境中

$ conda activate driiler
1.2.3 安装driller

然后开始如下安装:

$ pip install angr
$ pip install cle
$ pip install git+https://github.com/angr/tracer
$ pip install git+https://github.com/shellphish/driller

安装成功的标识是可以import driller

(driiler) ubuntu@VM-0-17-ubuntu:~/driller$ python
Python 3.8.8 (default, Feb 24 2021, 21:46:12) 
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import driller
>>> 

二、使用

2.1 Driller和AFL并行运行

这种安装方法是采用一种Driller和AFL并行运行的过程,将driller中求解输入的部分和AFL fuzz的部分分别放在两个terminal运行

Fuzz的程序源码为buggy.c

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
  char buffer[6] = {0};
  int i;
  int *null = 0;

  read(0, buffer, 6);
  if (buffer[0] == '7' && buffer[1] == '/' && buffer[2] == '4'
      && buffer[3] == '2' && buffer[4] == 'a' && buffer[5] == '8') {
    i = *null;
  }

  puts("No problem");
}

编译,由于使用AFL QEMU模式,因此不需要对源码进行插桩:

$ gcc -o buggy buggy.c -g

打开一个terminal, 用AFL进行FUZZ:

$ mkdir -p workdir/input
$ echo 'init' > workdir/input/seed1   # 提供初始化种子输入
$ echo core | sudo tee /proc/sys/kernel/core_pattern
$ AFL/afl-fuzz -M fuzzer-master -i workdir/input/ -o workdir/output/ -Q ./buggy

然后就可以成功开始AFL的Fuzz过程
在这里插入图片描述

然后我们使用一个脚本来运行driller,名字叫run_driller.py

#!/usr/bin/env python

import errno
import os
import os.path
import sys
import time

from driller import Driller


def save_input(content, dest_dir, count):
    """Saves a new input to a file where AFL can find it.

    File will be named id:XXXXXX,driller (where XXXXXX is the current value of
    count) and placed in dest_dir.
    """
    name = 'id:%06d,driller' % count
    with open(os.path.join(dest_dir, name), 'wb') as destfile:
        destfile.write(content)


def main():
    if len(sys.argv) != 3:
        print('Usage: %s <binary> <fuzzer_output_dir>' % sys.argv[0])
        sys.exit(1)

    _, binary, fuzzer_dir = sys.argv

    # Figure out directories and inputs
    with open(os.path.join(fuzzer_dir, 'fuzz_bitmap'), 'rb') as bitmap_file:
        fuzzer_bitmap = bitmap_file.read()
    source_dir = os.path.join(fuzzer_dir, 'queue')
    dest_dir = os.path.join(fuzzer_dir, '..', 'driller', 'queue')

    # Make sure destination exists
    try:
        os.makedirs(dest_dir)
    except os.error as e:
        if e.errno != errno.EEXIST:
            raise

    seen = set()  # Keeps track of source files already drilled
    count = len(os.listdir(dest_dir))  # Helps us name outputs correctly

    # Repeat forever in case AFL finds something new
    while True:
        # Go through all of the files AFL has generated, but only once each
        for source_name in os.listdir(source_dir):
            if source_name in seen or not source_name.startswith('id:'):
                continue
            seen.add(source_name)
            with open(os.path.join(source_dir, source_name), 'rb') as seedfile:
                seed = seedfile.read()

            print('Drilling input: %s' % seed)
            for _, new_input in Driller(binary, seed, fuzzer_bitmap).drill_generator():
                save_input(new_input, dest_dir, count)
                count += 1

            # Try a larger input too because Driller won't do it for you
            seed = seed + b'0000'
            print('Drilling input: %s' % seed)
            for _, new_input in Driller(binary, seed, fuzzer_bitmap).drill_generator():
                save_input(new_input, dest_dir, count)
                count += 1
        time.sleep(10)

if __name__ == '__main__':
    main()

再打开另一个窗口,运行driller部分

$ source ~/.bashrc
$ conda activate driiler
$ python run_driller.py ./buggy workdir/output/fuzzer-master

然后成功开启driiler
在这里插入图片描述

2.2 使用shellphuzz

官方推荐的driller的使用方法是通过shellphuzz工具来使用,使用方式如下,“-i”选项指定afl-fuzz的线程数,“-d”选项指定driller(即符号执行工具)的线程数,如果不使用-d或者-d 0,则不使用符号执行

# fuzz with 4 AFL cores
$ shellphuzz -i -c 4 /path/to/binary
    
# perform symbolic-assisted fuzzing with 4 AFL cores and 2 symbolic tracing (drilling) cores.
$ shellphuzz -i -c 4 -d 2 /path/to/binary

2.3 代码调用

直接调用Fuzzer对象(包含了fuzz和angr)

#change from /fuzzer/shellphuzz.py
import driller
import time
import fuzzer
    
def test():
	def robo_fuzzer():
		"""fuzz a single cb,copy it from shellphuzz"""
		work_path = './work'
		print "[*] Drilling..."
		drill_extension = driller.LocalCallback(num_workers=4)
		grease_extension = None
		# Timeout=1800
		first_crash = True
		stuck_callback = (
			(lambda f: (grease_extension(f), drill_extension(f))) if drill_extension and grease_extension else drill_extension or grease_extension)
		print "[*] Creating fuzzer..."
		fuzz = fuzzer.Fuzzer("./20190529", "./work", afl_count=1, force_interval=None,create_dictionary=False, stuck_callback=stuck_callback, time_limit=1000000)
		# start it!
		print "[*] Starting fuzzer..."
		fuzz.start()
		start_time = time.time()
	robo_fuzzer()
    
    test()
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值