Skip to content
This repository has been archived by the owner on May 1, 2019. It is now read-only.

set AFL_PATH to point to the correct afl_tracer #23

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 41 additions & 14 deletions fuzzer/fuzzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import threading
import subprocess
import shellphish_afl

from elftools.elf import elffile
import logging

l = logging.getLogger("fuzzer.fuzzer")
Expand Down Expand Up @@ -157,24 +157,51 @@ def __init__(
self.qemu_name = 'TODO'
else:

p = angr.Project(binary_path)
# when CLE doesn't support specific arch then get arch using
# elftools and set the approporiate AFL_PATH environment variable
# https://github.com/eliben/pyelftools/blob/master/elftools/elf/enums.py
try:
p = angr.Project(binary_path)
except RuntimeError:
l.debug("CLE doesn't support this arch for now, so it means you can only use AFL_FUZZ without driller")
self.binary = elffile.ELFFile(open(self.binary_path,'r'))
self.e_machine = self.binary.header.e_machine
if self.e_machine == 'EM_SH':
self.afl_path_var = shellphish_afl.afl_path_var('sh4')
elif self.e_machine == 'EM_S390':
self.afl_path_var = shellphish_afl.afl_path_var('s390x')
elif self.e_machine == 'EM_ALPHA' or self.e_machine == 36902:
self.afl_path_var = shellphish_afl.afl_path_var('alpha')
elif self.e_machine == "EM_PARISC":
self.afl_path_var = shellphish_afl.afl_path_var('hppa')
elif self.e_machine == "EM_CRIS":
self.afl_path_var = shellphish_afl.afl_path_var('cris')
elif self.e_machine == "EM_MICROBLAZE":
self.afl_path_var = shellphish_afl.afl_path_var('microblaze')
elif self.e_machine == "EM_68HC12":
self.afl_path_var = shellphish_afl.afl_path_var('m68k')

try:
self.os = p.loader.main_object.os

self.os = p.loader.main_object.os
self.afl_dir = shellphish_afl.afl_dir(self.os)

self.afl_dir = shellphish_afl.afl_dir(self.os)
# the path to AFL capable of calling driller
self.afl_path = shellphish_afl.afl_bin(self.os)

# the path to AFL capable of calling driller
self.afl_path = shellphish_afl.afl_bin(self.os)
if self.os == 'cgc':
self.afl_path_var = shellphish_afl.afl_path_var('cgc')
else:
self.afl_path_var = shellphish_afl.afl_path_var(p.arch.qemu_name)
# set up libraries
self._export_library_path(p)

if self.os == 'cgc':
self.afl_path_var = shellphish_afl.afl_path_var('cgc')
else:
self.afl_path_var = shellphish_afl.afl_path_var(p.arch.qemu_name)
# set up libraries
self._export_library_path(p)
# the name of the qemu port used to run these binaries
self.qemu_name = p.arch.qemu_name

# the name of the qemu port used to run these binaries
self.qemu_name = p.arch.qemu_name
except NameError:
self.afl_dir = shellphish_afl.afl_dir('unix')
self.afl_path = shellphish_afl.afl_bin('unix')

self.qemu_dir = self.afl_path_var

Expand Down
24 changes: 18 additions & 6 deletions shellphuzz
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import tarfile
import argparse
import importlib
import logging.config
from elftools.elf import elffile

if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Shellphish fuzzer interface")
Expand All @@ -23,6 +24,7 @@ if __name__ == "__main__":
parser.add_argument('-c', '--afl-cores', help="Number of AFL workers to spin up.", default=1, type=int)
parser.add_argument('-C', '--first-crash', help="Stop on the first crash.", action='store_true', default=False)
parser.add_argument('-t', '--timeout', help="Timeout (in seconds).", type=float)
parser.add_argument('-M', '--memory', help="Memory limitation")
parser.add_argument('-i', '--ipython', help="Drop into ipython after starting the fuzzer.", action='store_true')
parser.add_argument('-T', '--tarball', help="Tarball the resulting AFL workdir for further analysis to this file -- '{}' is replaced with the hostname.")
parser.add_argument('-m', '--helper-module', help="A module that includes some helper scripts for seed selection and such.")
Expand All @@ -46,6 +48,7 @@ if __name__ == "__main__":

drill_extension = None
grease_extension = None
start_driller = True

if args.grease_with:
print "[*] Greasing..."
Expand All @@ -54,18 +57,27 @@ if __name__ == "__main__":
grease_filter=helper_module.grease_filter if helper_module is not None else None,
grease_sorter=helper_module.grease_sorter if helper_module is not None else None
)
if args.driller_workers:
print "[*] Drilling..."
drill_extension = driller.LocalCallback(num_workers=args.driller_workers)

if args.driller_workers:
binary = elffile.ELFFile(open(args.binary,'r'))
e_machine = binary.header.e_machine
if e_machine in ('EM_SH', 'EM_S390', 'EM_ALPHA', 'EM_PARISC', 'EM_CRIS','EM_MICROBLAZE','EM_68HC12'):
start_driller = False
print "[-] Driller cannot guide fuzzing on this binary..."
else:
print "[*] Drilling..."
drill_extension = driller.LocalCallback(num_workers=args.driller_workers)

# FIXME: if binary not supported so start_driller = False and
# drill_extension = None
stuck_callback = (
(lambda f: (grease_extension(f), drill_extension(f))) if drill_extension and grease_extension
else drill_extension or grease_extension
(lambda f: (grease_extension(f), drill_extension(f))) if (drill_extension and start_driller) and grease_extension
else drill_extension if is not None or grease_extension
)

print "[*] Creating fuzzer..."
fuzzer = fuzzer.Fuzzer(
args.binary, args.work_dir, afl_count=args.afl_cores, force_interval=args.force_interval,
args.binary, args.work_dir, memory=args.memory, afl_count=args.afl_cores, force_interval=args.force_interval,
create_dictionary=not args.no_dictionary, stuck_callback=stuck_callback, time_limit=args.timeout
)

Expand Down
38 changes: 38 additions & 0 deletions tests/test_fuzzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import tempfile
import subprocess
import fuzzer
import glob

import logging
l = logging.getLogger("fuzzer.tests.test_fuzzer")
Expand Down Expand Up @@ -66,6 +67,43 @@ def test_showmap():
for te in true_dict.keys():
nose.tools.assert_equal(true_dict[te], smap[te])

def test_fuzzer_other_arch():
"""
Test that fuzzer works fine on other archs
"""

import logging
logging.getLogger("fuzzer").setLevel("DEBUG")

binary = os.path.join(bin_location, "tests/")
archs = [f for f in os.listdir(binary) if os.path.isdir(os.path.join(binary,f))]
for arch in archs:
arch_path = os.path.join(binary,arch)
binaries = [os.path.join(arch_path,b) for b in os.listdir(arch_path) if os.path.isfile(os.path.join(arch_path,b))]
if len(binaries) == 0:
depth_path = glob.glob(os.path.join(arch_path,'*/*/'))
dirs = filter(lambda f: os.path.isdir(f), depth_path)
if len(dirs) == 0:
continue
binaries = [[os.path.join(d,b) for b in os.listdir(d) if os.path.isfile(os.path.join(d,b))] for d in dirs]
if len(binaries) == 0:
continue
print "[*] Testing fuzzer on {0} for {1} binaries\n".format(arch, len(binaries))

f = fuzzer.Fuzzer(binaries, "bazinga")
f.start()

for _ in range(15):
if f.alive:
break
time.sleep(1)

nose.tools.assert_true(f.alive)

if f.alive:
f.kill()


def test_fuzzer_spawn():
"""
Test that the fuzzer spawns correctly
Expand Down