Git Product home page Git Product logo

battelle / afl-unicorn Goto Github PK

View Code? Open in Web Editor NEW

This project forked from innovimax/afl-1

585.0 585.0 98.0 2.87 MB

afl-unicorn lets you fuzz any piece of binary that can be emulated by Unicorn Engine.

Home Page: https://medium.com/@njvoss299/afl-unicorn-fuzzing-arbitrary-binary-code-563ca28936bf

License: Apache License 2.0

Makefile 2.50% C 75.48% Shell 7.27% HTML 0.63% C++ 0.89% JavaScript 0.01% Python 13.23% Rich Text Format 0.01%
afl afl-fuzz fuzzing reverse-engineering vulnerability-research

afl-unicorn's People

Contributors

bstee615 avatar cytq avatar davidkutik avatar djdeepdive avatar fustilio avatar jbachell avatar kr1tzy avatar liyansong2018 avatar mcarpenter avatar njv299 avatar w0ot-net avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

afl-unicorn's Issues

Fork server handshake failed - UnicornLoader script

I've been following the AFL Unicorn Guides and I'm trying to recreate the Unicorn dumper/loader functionality on the sample binary provided here. I compiled the aforementioned binary as a 32-bit ELF executable and I created a simple custom test harness based on the Loader Test Harness and the Raw Binary Test Harness.

I used the GDB helper script to dump the process context of simple_target at main. I've loaded the context successfully and I've also used the mem_write method to place sample data at 0x00300000 to be mutated. I was very careful to set the START_ADDRESS and END_ADDRESS for Unicorn based on the appropriate values associated with the dumped context.

After setting everything up, I ran the following command:

../../afl-fuzz -U -m none -i ./sample_inputs/ -o ./outputs -- python driver.py @@

Unfortunately, I receive an error on spinning up the fork server:

[*] Spinning up the fork server...

[-] Hmm, looks like the target binary terminated before we could complete a
    handshake with the injected code. Perhaps there is a horrible bug in the
    fuzzer. Poke <[email protected]> for troubleshooting tips.

[-] PROGRAM ABORT : Fork server handshake failed
         Location : init_forkserver(), afl-fuzz.c:2258

If I run the script standalone, I don't receive any issues and emulation is successful:

python driver.py -d UnicornContext_20191031_101427/ sample_inputs/sample1.bin

Why is this error occurring? This is the most simple proof of concept I can think of for getting started with AFL Unicorn, and I've based everything on the examples available to me. I've condensed my test harness code (provided below) for reference. The START and END address are relative to my context dump, but they should be easily reproducible if you use GDB to break simple_target on main and dump the context from there with the unicorn dumper helper script.

import argparse
from unicorn import *
from unicorn.x86_const import *  # TODO: Set correct architecture here as necessary
import unicorn_loader
unicorn_heap = None
START_ADDRESS = 0x565554ed # TODO: Set start address here
END_ADDRESS   = 0x5655558d # TODO: Set end address here
STACK_ADDRESS = 0x00200000  # Address of the stack (arbitrarily chosen)
STACK_SIZE    = 0x00010000  # Size of the stack (arbitrarily chosen)
DATA_ADDRESS  = 0x00300000  # Address where mutated data will be placed
DATA_SIZE_MAX = 0x00010000  # Maximum allowable size of mutated data
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('context_dir', type=str, help="Directory containing process context")
    parser.add_argument('input_file', type=str, help="Path to the file containing the mutated input content")
    parser.add_argument('-d', '--debug', default=False, action="store_true", help="Dump trace info")
    args = parser.parse_args()
    print("Loading context from {}".format(args.context_dir))
    uc = unicorn_loader.AflUnicornEngine(args.context_dir, enable_trace=args.debug, debug_print=args.debug)
    global unicorn_heap
    unicorn_heap = unicorn_loader.UnicornSimpleHeap(uc, debug_print=True)
    uc.hook_add(UC_HOOK_CODE, unicorn_hook_instruction)
    print("Starting the forkserver by executing 1 instruction")
    try:
        uc.emu_start(START_ADDRESS, 0, 0, count=1)
    except UcError as e:
        print("ERROR: Failed to execute a single instruction (error: {})!".format(e))
        return
    if args.input_file:
        print("Loading input content from {}".format(args.input_file))
        input_file = open(args.input_file, 'rb')
        input_content = input_file.read()
        input_file.close()
        buf_addr = unicorn_heap.malloc(len(input_content))
        uc.mem_write(buf_addr, input_content)
        print("Allocated mutated input buffer @ 0x{0:016x}".format(buf_addr))

    # Fill data at DATA_ADDRESS for mutating
    uc.mem_map(DATA_ADDRESS, DATA_SIZE_MAX)
    uc.mem_write(DATA_ADDRESS, ('\x00' * DATA_SIZE_MAX).encode())
    print("Executing from 0x{0:016x} to 0x{1:016x}".format(START_ADDRESS, END_ADDRESS))
    try:
        result = uc.emu_start(START_ADDRESS, END_ADDRESS, timeout=0, count=0)
    except UcError as e:
        print("Execution failed with error: {}".format(e))
        uc.dump_regs()
        uc.force_crash(e)
    print("Final register state:")
    uc.dump_regs()
    print("Done.")

if __name__ == "__main__":
    main()

Can't run the simple example provided

Thanks for your work! I come into some problems here.

So after I build the unicorn mode, it says this,
[+] Unicorn Python bindings installed successfully
[*] Testing unicorn-mode functionality by running a sample test harness under afl-unicorn
[-] Error: Unicorn mode doesn't seem to work!

And for the simple mode you provided, it gave me this.
orlog@hero:~/Documents/afl-unicorn/unicorn_mode/samples/simple$ afl-fuzz -U -m none -i sample_inputs/ -o results/ -- python simple_test_harness.py @@
afl-fuzz 2.52b by [email protected]
[+] You have 4 CPU cores and 2 runnable tasks (utilization: 50%).
[+] Try parallel jobs - see /usr/local/share/doc/afl/parallel_fuzzing.txt.
[] Checking CPU core loadout...
[+] Found a free CPU core, binding to #0.
[
] Checking core_pattern...
[] Checking CPU scaling governor...
[
] Setting up output directories...
[] Scanning 'sample_inputs/'...
[+] No auto-generated dictionary tokens to reuse.
[
] Creating hard links for all input files...
[] Validating target binary...
[
] Attempting dry run with 'id:000000,orig:sample1.bin'...
[*] Spinning up the fork server...

[-] Hmm, looks like the target binary terminated before we could complete a
handshake with the injected code. Perhaps there is a horrible bug in the
fuzzer. Poke [email protected] for troubleshooting tips.

[-] PROGRAM ABORT : Fork server handshake failed
Location : init_forkserver(), afl-fuzz.c:2258
I tested this on ubuntu 16.04. Can you give me some advice?

Python Setuptools not recognized

Hi,

After I run "sudo ./build_unicorn_support.sh" under unicorn_mode directory, I got this error:

[*] Performing basic sanity checks...
[-] Error: Python setup-tools not found. Run 'sudo apt-get install python-setuptools'.

I get this error even after I installed the setuptools and rerun the script. I use an Ubuntu 18.04. Has anyone encountered similar problems?

Ubuntu 20.04 LTS

Unable run simple sample on Ubuntu 20.04

uname

Linux localhost 5.4.0-29-generic #33-Ubuntu SMP Wed Apr 29 14:32:27 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

issue

NAME="Ubuntu"
VERSION="20.04 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04 LTS"
VERSION_ID="20.04"

command

afl-fuzz -U -m none -i sample_inputs -o results -- python2 simple_test_harness.py @@

output

afl-fuzz 2.52b by <[email protected]
[+] You have 8 CPU cores and 4 runnable tasks (utilization: 50%).
[+] Try parallel jobs - see /usr/local/share/doc/afl/parallel_fuzzing.txt.
[*] Checking CPU core loadout...
[+] Found a free CPU core, binding to #0.
[*] Checking core_pattern...
[*] Checking CPU scaling governor...
[*] Setting up output directories...
[+] Output directory exists but deemed OK to reuse.
[*] Deleting old session data...
[+] Output dir cleanup successful.
[*] Scanning 'sample_inputs'...
[+] No auto-generated dictionary tokens to reuse.
[*] Creating hard links for all input files...
[*] Validating target binary...
[*] Attempting dry run with 'id:000000,orig:sample1.bin'...
[*] Spinning up the fork server...

[-] Hmm, looks like the target binary terminated before we could complete a
    handshake with the injected code. Perhaps there is a horrible bug in the
    fuzzer. Poke <[email protected]> for troubleshooting tips.

[-] PROGRAM ABORT : Fork server handshake failed
         Location : init_forkserver(), afl-fuzz.c:2258=

same for python3

Add use-after-free and double-free detection to UnicornSimpleHeap

Detecting these two other bugs would be pretty simple:

  • Double free: Store all free'd addresses. If the same one occurs twice (without a call to malloc() allocating a buffer at that address first), report a double free
  • Use after free: Keep track of free'd heap buffer regions. If any memory access falls within one of those regions report a UAF

Unicorn mode 1.0.1 Makefile for Python 2

afl-unicorn/unicorn_mode/unicorn-1.0.1

Makefile needs to specify python2 until python3 migration is complete.

I've inserted line 67 as

UNICORN_QEMU_FLAGS += --python=/usr/bin/python2

Unicorn is downloaded and unpacked with elevated privileges

Unicorn-1.0.1 is downloaded and unpacked by the build_unicorn_support.sh installation script with elevated privileges, which can make it a pain to uninstall. Beyond that, there is no reason for it to have those privileges in the first place.

I think the build_unicorn_support.sh script must be run as root/sudo in order to actually install the patched Unicorn binaries to the user's system, but the side effect is that a lot of the script runs with the wrong privileges. I attempted to fix this by prefixing a bunch of lines in the script by prefixing them like this:

sudo -u ${USERNAME} <command to run with less privileges>

This didn't work, though, and my bash-fu is weak.

AttributeError by lldb.target.GetTriple

Hello,

I get error AttributeError("'NoneType' object has no attribute 'GetTriple'") when I try to import script. When in LLDB Python interactive console, it works as expected. But for some reason, importing does not work.

LLDB version:

lldb-1400.0.38.17
Apple Swift version 5.7.2 (swiftlang-5.7.2.135.5 clang-1400.0.29.51)

I know that afl-unicorn only supports Linux but I am trying to dump memory from MacOS and will try afl-unicorn on Linux. As far as I understand, dumper script only cares about arch not OS.

Thanks

Is it necessary to record the tls base address and its content

Since the base address of tls is not recorded, when encountering mov r10 QWORD RTR fs:0x10, unicorn will report Invalid memory read .... .

Is there any other method such as hook to solve this kind of problem?

Thanks in advance

Arch:x86-64
Platform:linux

AFL forkserver does not start in Unicorn Mode until an instruction is emulated

The current Unicorn Mode patches are such that the AFL forkserver is not kicked off until an instruction is emulated. This leads to problems when fuzzing Unicorn test harnesses, because if the mutated input is retrieved from disk before the forks occur then the same input is repeatedly used and no fuzzing is ever actually performed.

A cleaner implementation of this would probably be to either:

  • Send the 'Start forkserver' whenever a UnicornEngine instance is created
    or
  • Add an API to UnicornEngine (or a derived class) specifically to start the fork server

For now the workaround is to just run a single instruction, then load the mutated input, then emulate the rest of the code (as discussed in the blog post, readme, and example test harnesses).

Handshake fails when print to stderr is done

Hi,
when 'print("some error",file=sys.stderr) is used in the simple_test_harness.py, the handshake with afl fails.
That behaviour can be reproduced easily with the example in the project.
Just import sys in the beginning and do a "print("something", file=sys.stderr) in the main.
With the print-line the handshake fails, without the example works.
I'm using python3.6.8. on Ubuntu18.04.
Is this behaviour reproducable on your side? (Its very strange, I think)

Kr,
Lutz Pape

Missing I/Q data for FSK_Messaging_Service example

I'm working on duplicating the examples from Fuzzing the Unfuzzable and ran into some missing parts:

  • FSK_Messaging_Service binary: I built this from the cb-multios repo
  • Valid input data for the test binary. I thought this would be in the cb-multios repo but if it is I've not found it.

My planned contribution is to create a simple test suite (pytest) that mirrors the two blog posts. These are great examples and It would be good to make sure they keep working as the project evolves.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.