zoukankan      html  css  js  c++  java
  • Proj THUDBFuzz: AFLplusplus

    Cite

    Andrea Fioraldi, Dominik Maier, Heiko Eißfeldt, and Marc Heuse. “AFL++: Combining incremental steps of fuzzing research”. In 14th USENIX Workshop on Offensive Technologies (WOOT 20). USENIX Association, Aug. 2020.

    为了对比,应当使用fuzzbench aflplusplus setup或者afl-clang-fast + AFL_LLVM_COMLOG=1

    Overview

    framework的主要元素是:

    1. 带有多种变异方法和设置参数的fuzzer: afl-fuzz
    2. 不同的源代码插桩模块:LLVM mode, afl-as, GCC plugin
    3. 不同的二进制代码插桩模块: QEMU mode, Unicorn mode, QBDI mode
    4. testcase/corpus reduction: afl-tmin, afl-cmin
    5. 其他Helper libraries: libtokencap, libdislocator, libcompcov

    Features

    已经支持:

    1. llvm 11
    2. QEMU 5.1
    3. BSD and Android Support
    4. AFL fast的power schedule功能 https://github.com/mboehme/aflfast
    5. MOpt变异 https://github.com/puppet-meteor/MOpt-AFL
    6. InsTrim: 高效的CFG llvm_mode插桩实现 https://github.com/csienslab/instrim
    7. afl-fuzz Python mutator + llvm mode whitelist support: https://github.com/choller/afl
    8. Custom mutator by a library
    9. Unicorn mode: allows fuzzin of binaries from different platforms
    10. LAF-Intel/CompCov support for llvm_mode,qemu_mode and unicorn_mode
    11. NeverZero patch, 使得wrapping map值不为0
    12. Persistent mode and deferred forkserver for qemu_mode
    13. Win32 PE binary-only fuzzing with QEMU and wine
    14. Radamsa mutator
    15. QBDI mode(fuzz android native libs)
    16. CmpLog instrumentation for LLVM and QEMU(inspired by RedQueen)

    Fuzzing binary-only programs with afl++ 如何对只有源码的程序进行模糊测试

    1. afl-fuzz -n是不插桩模式,但是效果并不好。
    2. 官方建议按照以下优先顺序
    3. qemu_mode + persistent mode最快,不过要求程序足够稳定
    4. retrowrite
    5. afl-dyninst
    6. qemu_mode with AFL_ENTRYPOINT

    QEMU

    qemu支持对只有二进制的程序进行模糊测试,甚至还能跨平台测试。
    qemu会把测试程序的速度减慢50%,但是下面的选项能够增加qemu测试的速度

    1. using AFL_ENTRYPOINT to move the forkserver entry to a later basic block in the binary (+5-10% speed)
    2. persistent mode(150-300% overall speed increase)
    3. using AFL_CODE_START/AFL_CODE_END to only instrument specific parts

    honggfuzz也有qemu_mode,但是只能增进1.5%的速度

    WINE+QEMU

    wine + python3 + pefile(python package) + qemu可以在Linux上测win32

    UNICORN

    UNICORN是QEMU的fork,不过,UNICORN提供的不是整个系统或者用户界面仿真。用户需要从头写runtime environment 或者是loaders。此外,UNICORN中的区块链已经被删除了。

    AFL Frida

    frida-gum + utils/afl_frida,此时使用afl-frida.c作为模板来调用library中的目标函数

    AFL Untracer

    utils/afl_untracer,这里用afl-untracer.c做模板

    DYNINST

    类似Pintool和Dynamorio的二进制工具框架。不过Dyninst在加载时会对目标进行插桩(而Pintool和Dynamorio不会),然后再保存对应二进制。接着,用afl-fuzz来模糊测修改后的二进制。一般来说,我们会用dyninst插桩并将必要的信息加入二进制。但这样做存在一个隐患,会改变进程空间中的地址,这导致待测程序很可能会崩溃。DYNINST会给速度带来15到35%的降低。

    https://github.com/vanhauser-thc/afl-dyninst

    Retrowrite

    如果待测程序携带符号表,而且是编译时选择了位置无关,并且没有用大多数c++features,那就可以用retrowrite。只会降低15%到20%的性能

    https://github.com/HexHive/retrowrite

    MCSEMA

    理论上可行
    https://github.com/lifting-bits/mcsema

    INTEL-PT

    硬件需求: 新世代Intel CPU
    效果: 利用intels processor trace
    问题:缓存区很小,而且PT传回来的debug信息的解码非常麻烦需要大量CPU计算来解码。
    As a result, the overall speed decrease is about 70-90%
    https://github.com/junxzm1990/afl-pt
    https://github.com/hunter-ht-2018/ptfuzzer

    CoreSight

    ARM,但是还没找到实现

    Frida

    动态插桩引擎,特殊在于其用python写的,然后用JS来跑具体执行。该软件通常用在逆向手机软件上。
    https://github.com/andreafioraldi/frida-fuzzer
    https://github.com/AFLplusplus/AFLplusplus/tree/frida

    PIN & DYNAMORIO

    动态插桩引擎,能够在运行时获取基本块信息。
    会严重拖慢时间

    Dynamorio solutions:
    https://github.com/vanhauser-thc/afl-dynamorio
    https://github.com/mxmssh/drAFL
    https://github.com/googleprojectzero/winafl/ <= very good but windows only

    Pintool solutions:
    https://github.com/vanhauser-thc/afl-pin
    https://github.com/mothran/aflpin
    https://github.com/spinpx/afl_pin_mode <= only old Pintool version supported

    ENV

    为了避免出现ENV的笔误,Afl++中的一些工具可能会警告自己不用也不知道的环境变量,那时可以用AFL_IGNORE_UNKNOWN_ENVS 来避免这个问题

    AFL custom mutators

    该目录下一共有grammar mutator, honggfuzz, libfuzzer, libprotobuf-mutator-example, radamsa, rust, symcc这几个子目录。此外,还提到了superion这个项目。

    grammar mutator

    使用git submodule update --init来初始化子项目
    该项目是AFL++内部为了兼容高度结构化的测试样例而做的,其功能或者思想基本来自 F1 fuzzer and Nautilus

    该项目能够做以下操作:

    • Tree-based mutation: rules mutation, random mutation, random recursive mutation, splicing mutation
    • Tree-based trimming: subtree trimming, recursive trimming
    • An ANTLR4 shim for parsing fuzzing test cases during the runtime

    Usage

    static void usage(u8 *argv0, int more_help) {
    
      SAYF(
          "
    %s [ options ] -- /path/to/fuzzed_app [ ... ]
    
    "
    
          "Required parameters:
    "
          "  -i dir        - input directory with test cases
    "
          "  -o dir        - output directory for fuzzer findings
    
    "
    
          "Execution control settings:
    "
          "  -p schedule   - power schedules compute a seed's performance score:
    "
          "                  fast(default), explore, exploit, seek, rare, mmopt, "
          "coe, lin
    "
          "                  quad -- see docs/power_schedules.md
    "
          "  -f file       - location read by the fuzzed program (default: stdin "
          "or @@)
    "
          "  -t msec       - timeout for each run (auto-scaled, default %u ms). "
          "Add a '+'
    "
          "                  to auto-calculate the timeout, the value being the "
          "maximum.
    "
          "  -m megs       - memory limit for child process (%u MB, 0 = no limit "
          "[default])
    "
          "  -Q            - use binary-only instrumentation (QEMU mode)
    "
          "  -U            - use unicorn-based instrumentation (Unicorn mode)
    "
          "  -W            - use qemu-based instrumentation with Wine (Wine "
          "mode)
    
    "
    
          "Mutator settings:
    "
          "  -D            - enable deterministic fuzzing (once per queue entry)
    "
          "  -L minutes    - use MOpt(imize) mode and set the time limit for "
          "entering the
    "
          "                  pacemaker mode (minutes of no new paths). 0 = "
          "immediately,
    "
          "                  -1 = immediately and together with normal mutation).
    "
          "                  See docs/README.MOpt.md
    "
          "  -c program    - enable CmpLog by specifying a binary compiled for "
          "it.
    "
          "                  if using QEMU, just use -c 0.
    "
          "  -l cmplog_opts - CmpLog configuration values (e.g. "2AT"):
    "
          "                  1=small files (default), 2=larger files, 3=all "
          "files,
    "
          "                  A=arithmetic solving, T=transformational solving.
    
    "
          "Fuzzing behavior settings:
    "
          "  -Z            - sequential queue selection instead of weighted "
          "random
    "
          "  -N            - do not unlink the fuzzing input file (for devices "
          "etc.)
    "
          "  -n            - fuzz without instrumentation (non-instrumented mode)
    "
          "  -x dict_file  - fuzzer dictionary (see README.md, specify up to 4 "
          "times)
    
    "
    
          "Testing settings:
    "
          "  -s seed       - use a fixed seed for the RNG
    "
          "  -V seconds    - fuzz for a specified time then terminate
    "
          "  -E execs      - fuzz for an approx. no. of total executions then "
          "terminate
    "
          "                  Note: not precise and can have several more "
          "executions.
    
    "
    
          "Other stuff:
    "
          "  -M/-S id      - distributed mode (see docs/parallel_fuzzing.md)
    "
          "                  -M auto-sets -D, -Z (use -d to disable -D) and no "
          "trimming
    "
          "  -F path       - sync to a foreign fuzzer queue directory (requires "
          "-M, can
    "
          "                  be specified up to %u times)
    "
          "  -d            - skip deterministic fuzzing in -M mode
    "
          "  -T text       - text banner to show on the screen
    "
          "  -I command    - execute this command/script when a new crash is "
          "found
    "
          //"  -B bitmap.txt - mutate a specific test case, use the out/fuzz_bitmap
          //" "file
    "
          "  -C            - crash exploration mode (the peruvian rabbit thing)
    "
          "  -b cpu_id     - bind the fuzzing process to the specified CPU core "
          "(0-...)
    "
          "  -e ext        - file extension for the fuzz test input file (if "
          "needed)
    
    ",
          argv0, EXEC_TIMEOUT, MEM_LIMIT, FOREIGN_SYNCS_MAX);
    
      if (more_help > 1) {
    
    #if defined USE_COLOR && !defined ALWAYS_COLORED
      #define DYN_COLOR 
        "AFL_NO_COLOR or AFL_NO_COLOUR: switch colored console output off
    "
    #else
      #define DYN_COLOR
    #endif
    
        SAYF(
          "Environment variables used:
    "
          "LD_BIND_LAZY: do not set LD_BIND_NOW env var for target
    "
          "ASAN_OPTIONS: custom settings for ASAN
    "
          "              (must contain abort_on_error=1 and symbolize=0)
    "
          "MSAN_OPTIONS: custom settings for MSAN
    "
          "              (must contain exitcode="STRINGIFY(MSAN_ERROR)" and symbolize=0)
    "
          "AFL_AUTORESUME: resume fuzzing if directory specified by -o already exists
    "
          "AFL_BENCH_JUST_ONE: run the target just once
    "
          "AFL_BENCH_UNTIL_CRASH: exit soon when the first crashing input has been found
    "
          "AFL_CMPLOG_ONLY_NEW: do not run cmplog on initial testcases (good for resumes!)
    "
          "AFL_CRASH_EXITCODE: optional child exit code to be interpreted as crash
    "
          "AFL_CUSTOM_MUTATOR_LIBRARY: lib with afl_custom_fuzz() to mutate inputs
    "
          "AFL_CUSTOM_MUTATOR_ONLY: avoid AFL++'s internal mutators
    "
          "AFL_CYCLE_SCHEDULES: after completing a cycle, switch to a different -p schedule
    "
          "AFL_DEBUG: extra debugging output for Python mode trimming
    "
          "AFL_DEBUG_CHILD: do not suppress stdout/stderr from target
    "
          "AFL_DISABLE_TRIM: disable the trimming of test cases
    "
          "AFL_DUMB_FORKSRV: use fork server without feedback from target
    "
          "AFL_EXIT_WHEN_DONE: exit when all inputs are run and no new finds are found
    "
          "AFL_EXPAND_HAVOC_NOW: immediately enable expand havoc mode (default: after 60 minutes and a cycle without finds)
    "
          "AFL_FAST_CAL: limit the calibration stage to three cycles for speedup
    "
          "AFL_FORCE_UI: force showing the status screen (for virtual consoles)
    "
          "AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in milliseconds)
    "
          "AFL_HANG_TMOUT: override timeout value (in milliseconds)
    "
          "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: don't warn about core dump handlers
    "
          "AFL_IGNORE_UNKNOWN_ENVS: don't warn on unknown env vars
    "
          "AFL_IMPORT_FIRST: sync and import test cases from other fuzzer instances first
    "
          "AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, etc. (default: SIGKILL)
    "
          "AFL_MAP_SIZE: the shared memory size for that target. must be >= the size
    "
          "              the target was compiled for
    "
          "AFL_MAX_DET_EXTRAS: if more entries are in the dictionary list than this value
    "
          "                    then they are randomly selected instead all of them being
    "
          "                    used. Defaults to 200.
    "
          "AFL_NO_AFFINITY: do not check for an unused cpu core to use for fuzzing
    "
          "AFL_NO_ARITH: skip arithmetic mutations in deterministic stage
    "
          "AFL_NO_AUTODICT: do not load an offered auto dictionary compiled into a target
    "
          "AFL_NO_CPU_RED: avoid red color for showing very high cpu usage
    "
          "AFL_NO_FORKSRV: run target via execve instead of using the forkserver
    "
          "AFL_NO_SNAPSHOT: do not use the snapshot feature (if the snapshot lkm is loaded)
    "
          "AFL_NO_UI: switch status screen off
    "
    
          DYN_COLOR
    
          "AFL_PATH: path to AFL support binaries
    "
          "AFL_PYTHON_MODULE: mutate and trim inputs with the specified Python module
    "
          "AFL_QUIET: suppress forkserver status messages
    "
          "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target
    "
          "AFL_TARGET_ENV: pass extra environment variables to target
    "
          "AFL_SHUFFLE_QUEUE: reorder the input queue randomly on startup
    "
          "AFL_SKIP_BIN_CHECK: skip the check, if the target is an executable
    "
          "AFL_SKIP_CPUFREQ: do not warn about variable cpu clocking
    "
          "AFL_SKIP_CRASHES: during initial dry run do not terminate for crashing inputs
    "
          "AFL_STATSD: enables StatsD metrics collection
    "
          "AFL_STATSD_HOST: change default statsd host (default 127.0.0.1)
    "
          "AFL_STATSD_PORT: change default statsd port (default: 8125)
    "
          "AFL_STATSD_TAGS_FLAVOR: set statsd tags format (default: disable tags)
    "
          "                        Supported formats are: 'dogstatsd', 'librato',
    "
          "                        'signalfx' and 'influxdb'
    "
          "AFL_TESTCACHE_SIZE: use a cache for testcases, improves performance (in MB)
    "
          "AFL_TMPDIR: directory to use for input file generation (ramdisk recommended)
    "
          //"AFL_PERSISTENT: not supported anymore -> no effect, just a warning
    "
          //"AFL_DEFER_FORKSRV: not supported anymore -> no effect, just a warning
    "
          "
    "
        );
    
  • 相关阅读:
    数据库的逻辑结构与物理结构
    HTTP笔记整理(1)
    当我看懂这张图的时候很痛苦~~~
    软件测试面试分享(转)
    达梦(DM)数据库Linux部署安装
    进阶的小小测试~软件测试不得不知的基础知识
    软件测试分类
    浅说软件需求分析
    浅说《测试用例》----给测试新手的
    软件测试人员两极分化
  • 原文地址:https://www.cnblogs.com/xuesu/p/14646605.html
Copyright © 2011-2022 走看看