shellphish / afl-other-arch

AFL, with scripts to support other architectures.
96 stars 43 forks source link

Rebased on 2.51b #2

Closed thenickdude closed 6 years ago

thenickdude commented 7 years ago

Rebased on AFL 2.51b (fixes AFL crashes I was having where fork failed)

zardus commented 7 years ago

Hey! Just so this doesn't look ignored: we're super psyched for this change (thank you), but haven't had a chance to make sure that everything still works. Once we get a chance, this will be merged in post-haste.

pwnslinger commented 6 years ago

I performed some tests to make sure it works fine. In the following you can see the results of the experiments:

In order to perform experiments I have cross-compiled test_instr.c which is the basic test-case of the afl-fuzz itself for the following archs:

   aarch64 alpha arm armeb cris i386 m68k microblaze microblazeel
   mips mips64 mips64el mipsel mipsn32 mipsn32el or32 ppc ppc64
   ppc64abi32 ppc64le s390x sh4 sh4eb sparc sparc32plus sparc64 unicore32
   x86_64

Also, I made sure that qemu has been successfully patched for each of the aforementioned archs by running each of the test cases in qemu user-mode emulation. One simple output is the following:

(angr) angr@2d6b6bc66e9f:~/.virtualenvs/angr/bin/afl-cgc$ file testcases/test-instr_powerpc
testcases/test-instr_powerpc: ELF 32-bit MSB executable, PowerPC or cisco 4500, version 1 (SYSV), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=e64879a027fff02788af1daefd13de9731a30493, not stripped
(angr) angr@2d6b6bc66e9f:~/.virtualenvs/angr/bin/afl-cgc$ echo 0 | qemu-ppc testcases/test-instr_powerpc
Looks like a zero to me!

Now when I try to fuzz it inside afl-fuzz, I ended up with this error...

(angr) angr@2d6b6bc66e9f:~/.virtualenvs/angr/bin/afl-cgc$ AFL_SKIP_BIN_CHECK=1 AFL_NO_FORKSRV=1 ./afl-fuzz -Q -m none -i inputs/ -o outputs testcases/test-instr_powerpc @@

error:

[-] PROGRAM ABORT : No instrumentation detected
         Location : perform_dry_run(), afl-fuzz.c:2655

For getting more information around the issue, this is the afl-showmap output:

(angr) angr@2d6b6bc66e9f:~/.virtualenvs/angr/bin/afl-cgc$ echo 0 |AFL_NO_FORKSRV=1 AFL_SKIP_BIN_CHECK=1 ./afl-showmap -Q -m none -o /dev/null testcases/test-instr_powerpc

error:

-- Program output begins --
testcases/test-instr_powerpc: Invalid ELF image for this architecture
-- Program output ends --

The only test cases that has been passed so far was the mips arch binary:

(angr) angr@2d6b6bc66e9f:~/.virtualenvs/angr/bin/afl-cgc$ echo 0 |AFL_NO_FORKSRV=1 AFL_SKIP_BIN_CHECK=1 ./afl-showmap -Q -m none -o /dev/null testcases/test-instr_mips

output:

-- Program output begins --
Looks like a zero to me!
-- Program output ends --
[+] Captured 667 tuples in '/dev/null'.
pwnslinger commented 6 years ago

After a bit of wasting time with error, I found that if we set AFL_PATH to point to an appropriate version of afl-qemu-trace that nasty error would be fixed. Furthermore, the corresponding code in any afl-XXX.c that handles the qemu argv is located in the following lines:

afl-showmap#get_qemu_argv()

In the following you can use this bash script to solve it temporary. Before, running any analysis send your binary to this script and then use any afl-XXX, it'll automatically detect binary and set proper afl-qemu-tracer.

#!/bin/sh

if [ ! $# -eq 1 ]; then
    echo "usage: $0 <binary>" >&2
    exit 1
fi
echo
echo "====================================================="
echo "Setting AFL_PATH to the corresponding afl-qemu-tracer"
echo "====================================================="
echo 

binary="$(pwd)/$1"
AFL_PATH="$(pwd)/tracers/"
setpath="export AFL_PATH=$AFL_PATH"

if [ ! -f $binary ]; then
    echo "[-] Error: $(basename $binary) not found."
    exit 1
fi

command=$(readelf -h $binary | grep -i machine | sed "s/^.*://" | tr -d "[:space:]")
arch=$(readelf -h $binary | grep -i "class\|machine" | sed "s/^.*://" | tr -d "[ /t]" | tr "\n" ":" | cut -d":" -f 1)

case $command in

    "PowerPC"*)
        if [ "$arch" = "ELF32" ]; then
            AFL_PATH="${AFL_PATH}ppc"
        else
            AFL_PATH="${AFL_PATH}ppc64"
        fi
        $($setpath) || exit 1
        echo "[+] AFL_PATH=$AFL_PATH"
        ;;

    "AArch64")
        AFL_PATH="${AFL_PATH}aarch64"
        $($setpath) || exit 1
        echo "[+] AFL_PATH=$AFL_PATH"
        ;;

    "ARM")
        AFL_PATH="${AFL_PATH}arm"
        $($setpath) || exit 1
        echo "[+] AFL_PATH=$AFL_PATH"
        ;;

    *"390"*)
        AFL_PATH="${AFL_PATH}s390x"
        $($setpath) || exit 1 
        echo "[+] AFL_PATH=$AFL_PATH"
        ;;

    *"SuperHSH"*)
        AFL_PATH="${AFL_PATH}sh4"
        $($setpath) || exit 1
        echo "[+] AFL_PATH=$AFL_PATH"
        ;;

    *"Sparc"*)
        if [ "$arch" = "ELF32" ]; then
            AFL_PATH="${AFL_PATH}sparc"
        else
            AFL_PATH="${AFL_PATH}sparc64"
        fi
        $($setpath) || exit 1
        echo "[+] AFL_PATH=$AFL_PATH"
        ;;

    *"X86-64"*)
        AFL_PATH="${AFL_PATH}x86_64"
        $($setpath) || exit 1
        echo "[+] AFL_PATH=$AFL_PATH"
        ;;

    *"MIPS"*)
        if [ "$arch" = "ELF32" ]; then
            AFL_PATH="${AFL_PATH}mips"
        else
            AFL_PATH="${AFL_PATH}mips64"
        fi
        $($setpath) || exit 1
        echo "[+] AFL_PATH=$AFL_PATH"
        ;;

    "Alpha")
        AFL_PATH="${AFL_PATH}alpha"
        $($setpath) || exit 1
        echo "[+] AFL_PATH=$AFL_PATH"
        ;;

    *)
        echo "[-] Unfortunately it's not supported for $command"
esac

echo

Most of the test cases has been passed right now, but one of them failed:

Test: for i in testcases/arch/*; do if [ ! -f $i ]; then continue; fi; . ./setpath.sh $i || exit 1 ; echo 0 | AFL_PATH=$AFL_PATH AFL_NO_FORKSRV=1 AFL_SKIP_BIN_CHECK=1 ./afl-showmap -Q -m none -o /dev/null $i ; done

Results:

=====================================================
Setting AFL_PATH to the corresponding afl-qemu-tracer
=====================================================

[+] AFL_PATH=/home/angr/angr-dev/afl-other-arch/tracers/ppc64

-- Program output begins --
Looks like a zero to me!
-- Program output ends --

[-] PROGRAM ABORT : No instrumentation detected
         Location : main(), afl-showmap.c:767
zardus commented 6 years ago

Sorry about the delay, @thenickdude. We finally merged it :-)

Thank you!!