Git Product home page Git Product logo

aflplusplus / libafl Goto Github PK

View Code? Open in Web Editor NEW
1.8K 1.8K 285.0 19.82 MB

Advanced Fuzzing Library - Slot your Fuzzer together in Rust! Scales across cores and machines. For Windows, Android, MacOS, Linux, no_std, ...

License: Other

Rust 73.34% C 7.30% Shell 0.44% C++ 18.03% Makefile 0.23% Dockerfile 0.10% Python 0.49% PowerShell 0.01% HTML 0.01% Assembly 0.06%
afl afl-fuzz aflplusplus binary-only coverage-guided frida fuzzing fuzzing-framework libafl rust

libafl's Introduction

American Fuzzy Lop plus plus (AFL++)

AFL++ logo

Release version: 4.20c

GitHub version: 4.21a

Repository: https://github.com/AFLplusplus/AFLplusplus

AFL++ is maintained by:

Originally developed by Michal "lcamtuf" Zalewski.

AFL++ is a superior fork to Google's AFL - more speed, more and better mutations, more and better instrumentation, custom module support, etc.

You are free to copy, modify, and distribute AFL++ with attribution under the terms of the Apache-2.0 License. See the LICENSE for details.

Getting started

Here is some information to get you started:

  • For an overview of the AFL++ documentation and a very helpful graphical guide, please visit docs/README.md.
  • To get you started with tutorials, go to docs/tutorials.md.
  • For releases, see the Releases tab and branches. The best branches to use are, however, stable or dev - depending on your risk appetite. Also take a look at the list of important changes in AFL++ and the list of features.
  • If you want to use AFL++ for your academic work, check the papers page on the website.
  • To cite our work, look at the Cite section.
  • For comparisons, use the fuzzbench aflplusplus setup, or use afl-clang-fast with AFL_LLVM_CMPLOG=1. You can find the aflplusplus default configuration on Google's fuzzbench.

Building and installing AFL++

To have AFL++ easily available with everything compiled, pull the image directly from the Docker Hub (available for both x86_64 and arm64):

docker pull aflplusplus/aflplusplus
docker run -ti -v /location/of/your/target:/src aflplusplus/aflplusplus

This image is automatically published when a push to the stable branch happens (see branches). If you use the command above, you will find your target source code in /src in the container.

Note: you can also pull aflplusplus/aflplusplus:dev which is the most current development state of AFL++.

To build AFL++ yourself - which we recommend - continue at docs/INSTALL.md.

Quick start: Fuzzing with AFL++

NOTE: Before you start, please read about the common sense risks of fuzzing.

This is a quick start for fuzzing targets with the source code available. To read about the process in detail, see docs/fuzzing_in_depth.md.

To learn about fuzzing other targets, see:

Step-by-step quick start:

  1. Compile the program or library to be fuzzed using afl-cc. A common way to do this would be:

    CC=/path/to/afl-cc CXX=/path/to/afl-c++ ./configure --disable-shared
    make clean all
    
  2. Get a small but valid input file that makes sense to the program. When fuzzing verbose syntax (SQL, HTTP, etc.), create a dictionary as described in dictionaries/README.md, too.

  3. If the program reads from stdin, run afl-fuzz like so:

    ./afl-fuzz -i seeds_dir -o output_dir -- \
    /path/to/tested/program [...program's cmdline...]
    

    To add a dictionary, add -x /path/to/dictionary.txt to afl-fuzz.

    If the program takes input from a file, you can put @@ in the program's command line; AFL++ will put an auto-generated file name in there for you.

  4. Investigate anything shown in red in the fuzzer UI by promptly consulting docs/afl-fuzz_approach.md#understanding-the-status-screen.

  5. You will find found crashes and hangs in the subdirectories crashes/ and hangs/ in the -o output_dir directory. You can replay the crashes by feeding them to the target, e.g. if your target is using stdin:

    cat output_dir/crashes/id:000000,* | /path/to/tested/program [...program's cmdline...]
    

    You can generate cores or use gdb directly to follow up the crashes.

  6. We cannot stress this enough - if you want to fuzz effectively, read the docs/fuzzing_in_depth.md document!

Contact

Questions? Concerns? Bug reports?

Branches

The following branches exist:

  • release: the latest release
  • stable/trunk: stable state of AFL++ - it is synced from dev from time to time when we are satisfied with its stability
  • dev: development state of AFL++ - bleeding edge and you might catch a checkout which does not compile or has a bug. We only accept PRs (pull requests) for the 'dev' branch!
  • (any other): experimental branches to work on specific features or testing new functionality or changes.

Help wanted

We have several ideas we would like to see in AFL++ to make it even better. However, we already work on so many things that we do not have the time for all the big ideas.

This can be your way to support and contribute to AFL++ - extend it to do something cool.

For everyone who wants to contribute (and send pull requests), please read our contributing guidelines before you submit.

Special thanks

Many of the improvements to the original AFL and AFL++ wouldn't be possible without feedback, bug reports, or patches from our contributors.

Thank you! (For people sending pull requests - please add yourself to this list :-)

List of contributors
  Jann Horn                             Hanno Boeck
  Felix Groebert                        Jakub Wilk
  Richard W. M. Jones                   Alexander Cherepanov
  Tom Ritter                            Hovik Manucharyan
  Sebastian Roschke                     Eberhard Mattes
  Padraig Brady                         Ben Laurie
  @dronesec                             Luca Barbato
  Tobias Ospelt                         Thomas Jarosch
  Martin Carpenter                      Mudge Zatko
  Joe Zbiciak                           Ryan Govostes
  Michael Rash                          William Robinet
  Jonathan Gray                         Filipe Cabecinhas
  Nico Weber                            Jodie Cunningham
  Andrew Griffiths                      Parker Thompson
  Jonathan Neuschaefer                  Tyler Nighswander
  Ben Nagy                              Samir Aguiar
  Aidan Thornton                        Aleksandar Nikolich
  Sam Hakim                             Laszlo Szekeres
  David A. Wheeler                      Turo Lamminen
  Andreas Stieger                       Richard Godbee
  Louis Dassy                           teor2345
  Alex Moneger                          Dmitry Vyukov
  Keegan McAllister                     Kostya Serebryany
  Richo Healey                          Martijn Bogaard
  rc0r                                  Jonathan Foote
  Christian Holler                      Dominique Pelle
  Jacek Wielemborek                     Leo Barnes
  Jeremy Barnes                         Jeff Trull
  Guillaume Endignoux                   ilovezfs
  Daniel Godas-Lopez                    Franjo Ivancic
  Austin Seipp                          Daniel Komaromy
  Daniel Binderman                      Jonathan Metzman
  Vegard Nossum                         Jan Kneschke
  Kurt Roeckx                           Marcel Boehme
  Van-Thuan Pham                        Abhik Roychoudhury
  Joshua J. Drake                       Toby Hutton
  Rene Freingruber                      Sergey Davidoff
  Sami Liedes                           Craig Young
  Andrzej Jackowski                     Daniel Hodson
  Nathan Voss                           Dominik Maier
  Andrea Biondo                         Vincent Le Garrec
  Khaled Yakdan                         Kuang-che Wu
  Josephine Calliotte                   Konrad Welc
  Thomas Rooijakkers                    David Carlier
  Ruben ten Hove                        Joey Jiao
  fuzzah                                @intrigus-lgtm
  Yaakov Saxon                          Sergej Schumilo

Cite

If you use AFL++ in scientific work, consider citing our paper presented at WOOT'20:

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.
BibTeX
@inproceedings {AFLplusplus-Woot20,
author = {Andrea Fioraldi and Dominik Maier and Heiko Ei{\ss}feldt and Marc Heuse},
title = {{AFL++}: Combining Incremental Steps of Fuzzing Research},
booktitle = {14th {USENIX} Workshop on Offensive Technologies ({WOOT} 20)},
year = {2020},
publisher = {{USENIX} Association},
month = aug,
}

libafl's People

Contributors

addisoncrump avatar andreafioraldi avatar devnexen avatar domenukk avatar epi052 avatar evanrichter avatar expend20 avatar fabianfreyer avatar julihoh avatar l4yton avatar langston-barrett avatar lenawanel avatar maxammann avatar mkravchik avatar mrmaxmeier avatar novafacing avatar omergreen avatar omreebenari avatar rbran avatar rmalmain avatar s1341 avatar saruman9 avatar spacewhite avatar syheliel avatar teumessianfox avatar tokatoka avatar toseven avatar vanhauser-thc avatar vringar avatar worksbutnottested 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

libafl's Issues

Implement frida-based cmplog

Implement cmplog using frida.

  • aarch64 instrumentation
    • cmp support
    • tbnz/tbz support
    • .s instruction support
    • switch detection and support
  • x86_64 instrumentation

frida-asan: add hooks for memcpy, memmove et al. to check shadow memory

At the moment, because we don't instrument libc, we don't catch cases where code in the target calls a libc function like memcpy with bad parameters which cause an OOB access.

In order to deal with this, we need to hook functions like memcpy, etc. and check the parameters against the shadow memory.

Configurations

ATM, in the NewTestcaseEvent the configuration is TODO.
@domenukk do you want to pick it up while I work on Stats and CmpLog?

Broker2Broker: Introduce Main Broker

When using Broker2Broker, there should be a Main Broker to which all other brokers connect.

This Main Broker should:

  • display stats for the entire cluster, including total number of clients, executions, exec/secs, and objectives.
  • for OnDiskCorpus, it should collect all the TestCases and objective outputs from all connected brokers.

This will make managing a multi-machine fuzzing campaign much easier.

Ideally, it should be possible to run a Main Broker without any clients of its own. It should also be possible to run Main Broker on a PC, while child-brokers and clients run on e.g. phones.

Backstrace Observer

For crash dedup, we can implement a backtrace observer.

As the backtrace must be at crash point, and the crash point differ for each type of executor, this is not trivial.

I was thinking about adding a on_crash and on_timeout methods to InProcessExecutor that take a closure each for the type |fuzzer, state, manager, observers, input| { .. }. Here an user can fill the BactraceObserver calling the Linux backtrace() for instance.

For the Forkserver we need a shared memory.

AFL never did this type of dedup, we should look at Honggfuzz instead.

InProcessForkExecutor

ATM these two Executors are missing:

  • ForkserverExecutor must be an AFL-like forkserver executor, I guess we can borrow code from Angora
  • InProcessForkExecutor is a version of InProcessExecutor that forks before calling the harness. In this case, LibAFL must be still embedded into the target and we avoid to control the target via pipe, but then we still need an harness and cannot fuzz binaries compile with afl-cc

Decouple the broker from LLMPEventManager

The broker don't need to be a manager. In this way, we can include Stats in the broker and avoid to have Stats in LLMPEventManager. This will also remove the need to have client_init_stats in Laucnher.

Implement a method to compute state metadata from an Observer

At the moment, a Feedback can process an Observer and produce just testcase metadata.

As Feedback it related to the Corpus evolution, and as part of State cannot handle State for borrowing reasons, I propose to add state metadata based on observers in the post_exec() method of Executor.

We should create the MetaCollectorExecutor trait that override post_exec and forward it to an underlying base implementation.

Something like

let executor = DictionaryCollectorExecutor::new(InProcessExecutor::new(...));

frida-asan: Un-inline report funclet

At the moment, we emit a 'report funclet' for every memory operation. This report funclet is used to save/restore registers and calls the handle_trap ASAN method.

This funclet does not need to be emitted on every load/store. Instead we should only write it out when we are too far to reach the previous instance via a direct branch.

Note that we cannot 'call' the un-inlined funclet, as that would create a stack frame which would destroy unwinding. Instead we need to save some non-LR register, put the 'return address' into it, and then branch to the funclet.

frida: Detect new threads

When running with frida stalker (for coverage/asan) we should detect and stalk any new threads spawned by the process.

  • Hook pthread_create/fork/clone and detect new stack/TLS and shadow/unpoison them
  • Stalk new thread started by the target

Implement AFL++ like testcase syncing

While we sync testcases with LLMP and this is a way better than what afl-fuzz does, we should still implement this to take testcases from different fuzzers such as AFL++ honggfuzz and libfuzzer

frida-asan: Allow ignoring of a particular ASAN error

It should be possible to specify a (list of) error(s) to be ignored/disregarded by frida-asan. These particular errors should not be reported and should not crash the target.

This will allow discovery of deeper errors that may be masked by the initial bug. In addition, it can allow us to ignore a particular bug that isn't useful in order to reduce reporting/triage noise.

Ideally it should be possible to specify the error exactly given some slice of error metadata. Initially, we can just implement this using module:offset syntax. We may want to use a config file at some point in the future.

frida: detect dynamically loaded modules

When running with frida stalker, we should detect any new modules loaded by the target, and possibly add them to the instrumented modules list so that they will be stalked and have their allocations ASANed.

  • Hook dlopen to detect new libraries and shadow/unpoison them
  • Add new libraries loaded by the target to the stalker whitelist

Find a mechanism to enforce Metadata dependencies

At the current state, we don't have any mechanism to enforce the presence of some testcase or state metadata apart from returning errors at runtime when one component that needs such metadata want to use it without success.

Can we enforce this earlier in the code, e.g. when the component is created? Or even at compile time maybe?

TimeFeedback combined with feedback_or! problematic edge case

The problem

It is possible that when using TimeFeedback together with an feedback_or!, execution time will not be stored to a Testcase after executing it.
Example of a problematic usage

    let feedback = feedback_or!(
                MaxMapFeedback::new_tracking(...),
                TimeFeedback::new_with_observer(...)
    );

Root Cause

The root cause to this is that when the first feedback returns true to is_interesting the second feedback's is_interesting is never called. In our case TimeFeedback takes the execution time from the TimeObserver while in is_interesting, so if it is not called self.exec_time will be None.

I can think of two possible fixes:

  1. change TimeFeedback to do the whole thing in append_metadata while making is_interesting empty.
  2. changing OrFeedback to call both is_interesting even if the first was true

frida-asan: (Optionally) restore process state instead of crashing

Instead of crashing the target after reporting an ASAN error, we should (optionally) restore the process state to that before the erroring test case, and then simply continue fuzzing.

This will allow us to avoid the high cost of signaling the target to kill it and respawning the fuzzer client.

We currently have full control of the heap, and know how to reset it. We just need to be able to reset the stack. This can be achieved by pivoting from the original fuzzer thread stack just before running the test case, and pivoting back on return/crash.

LLMP compression

Hi, I am interested in LLMP brotli compression and have been browsing codes related to LLMP lately.

Is LLMP brotli compression referring to compressing (and decompressing) events that are passed between a broker and clients?
so we want to compress large members of Event like Event::NewTestcase->observers_buf or Event::Log->message using brotli crate?

Android: Allow multiple SharedMap Servers on the same machine

Perhaps by specifying broker names/ports in an environment variable?

  • Core support in LlmpBroker
  • If running without the flag/environment variable, set it to the default for both the broker and client process, so that it can be assumed to exist.
  • The launcher should automate whatever mechanism is used, so just running the launcher twice should give you two brokers. Or perhaps with a command line argument?
  • AshmemService needs to use the broker name/port to make itself unique.

Object-achieving results should be accompanied by machine- and human-readable metadata

When objective-achieving results are saved, they should include all the metadata, mutator and observer data that is available related to this test-case.

Perhaps this can be achieved by storing a json/toml/yaml file next to the test-case input, with the same base name.

At a minimum the following information should be present:

  • the test-case's unique name
  • the date/time at which it was encountered/produced
  • the type of objective-achievement
  • the arguments/cmd-line which was used to generate the test-case
  • a cmd-line which can be used to reproduce the test-case
  • mutations that were applied to generate the test-case
  • the parent test-case which was mutated
  • observer output

Coverage Stats

Hi everyone! I am loving this project 🎉

Is it possible to print coverage stats?
And if not, is it a wanted feature or should the library users just implement it on their own?

I was thinking the best way to add support for coverage stats was to adding a field to ClientStats similar to introspection_stats but I am still learning the structure of LibAFL so I am not sure. What do you think?

frida-asan: Refactor to use Interceptor instead of got-hook

Refactor the frida-asan function hooking in order to use frida's Interceptor instead of the got-hook crate.

  • Add necessary functionality to frida-rs
  • Switch from the RangeMap used for the stalker whitelist to a frida ModuleMap
  • Move hooks to Interceptor.replace with whitelist checking

Composing Feedbacks into a conditional formula

At the moment, a fitness > 0 is enough to add a testcase to the corpus, and the fitness is computed aggregating with an addition all the return values of Feedback::is_interesting.

Now, what if I want to consider a testcase interesting if triggers new coverage AND is crashing?

We should find a good solution and reengineer the fitness calculation part.
As the fitness atm is not used, we can get rid of it IMO and change FeedbacksTuple to be a compile time structure to express a conditional formula. Ofc is_interesting should now return simply a boolean.

In pseudocode, we should enable something like this to find interesting crashing testcases that trigger new coverage or are quicker to execute:

let state = State::new(
  ...,
  feedback: feedback_and!(CrashFeedback::new(), feedback_or!(MapFeedback::new(...), TimeFeedback::new(...))),
  ...
);

tuple_OP can be implemented as FeedbackAggregator<AggregatorOperator, FeedbacksTuple> that is a Feedback itself and define an operation to aggregate the results of the underlying feedbacks in the tuple.

The above example will expand to:

FeedbackAggregator::<AndOperator, _>::new(tuple_list!(CrashFeedback::new(), FeedbackAggregator::<OrOperator, _>::new(tuple_list!(MapFeedback::new(...), TimeFeedback::new(...)))))

frida-asan: hook mmap in order to unpoison allocated memory

At the moment, if the target calls mmap to map memory or a file, we do not unpoison the returned memory, which will cause false ASAN errors and make the target fail to function as expected.

We need to hook mmap and unpoison the returned memory.

Objective deduplification

There should be support in either the core library or libafl_targets for objective deduplification, which will allow us to produce 'unique' objectives.

The deduplification mechanism should be configurable, to allow for e.g. dedup using backtraces, crash address/offset and other metadata.

frida-asan: Add error analysis results to saved metadata

At the moment, we only save the raw AsanErrors in the metadata written to disk.

In the report_error method, we do a lot of analysis of the error. The results of that analysis should also be included in the output metadata, including:

  • original PC/IP
  • disassembly around error
  • type of error
  • allocation offset

Bug in mutation logic

let val =
INTERESTING_16[state.rand_mut().below(INTERESTING_8.len() as u64) as usize] as u16;

While refactoring mutation logic to use the new Rand::choose method I created, I came across this bug.

The error is that random indices over INTERESTING_8's length are being used to pick randomly from INTERESTING_16, which is longer. The latter items are never chosen! The bug is also present here for INTERESTING_32:

let val =
INTERESTING_32[state.rand_mut().below(INTERESTING_8.len() as u64) as usize] as u32;

My new Rand api choose solves this issue by determining length for the caller, based on the thing we're choosing from. A PR is almost ready for that, I'm hoping to push to a branch in the next few hours!

Also in the PR, I will be including some helper macros that cut down on the repetition of implementing very similar mutations, for example {Byte,Word,Dword,Qword}AddMutator

Timeout for LLMP Clients

LLMP, short for LowLevel Message Passing, has the concept of multiple clients, which are all connected to one broker.
The broker broadcasts each new message it receives from a client (over an individual shared) to all other clients via one ...shared... shared map.
So far, LLMP Clients never get unregistered.
It would be good to keep track of the last time a client sent a message, and unregister them accordingly.
This could be done in the once method of the broker (which is called in a loop in the broker)

pub fn once<F>(&mut self, on_new_msg: &mut F) -> Result<(), Error>

On top, we may want to support a good-bye/unregister message from clients when they know they are done. This could be called inside a Drop crate automatically.

Use log fascade

I think LibAFL could benefit from a generic logger as there are quite some messages which are sent to stdout.
env_logger allows to configure logging externally and uses macros for the actual calls. This is similar to println!.

I do not have experience with Rust, but enjoyed to work with env_logger. I suppose this is the default in the Rust community atm.

What do you think? Does it make sense to switch to this?
Or do we plan to avoid all logging and have a slick tui like AFL++?

frida-asan: Crash the target at the actual error instruction

frida-asan should crash the target at the actual error instruction location instead of panicking from the error reporting function.

This can probably be most easily achieved by:

  1. mprotecting the page being accessed to remove read/write permissions.
  2. Jumping back to the error instruction with restored state by (ab)using either longjmp or sigreturn.

This will make triaging bugs much easier, as they will die e.g. when run under gdb at the actual 'fault' location.

Frida should instrument any threads spawned by the target

Currently the frida coverage (and upcoming ASAN) only instrument the main thread of the target (i.e. the thread on which the harness is called).

We need to hook pthread_create (and possibly fork/clone) and attach the stalker to any new threads that the target spawns.

Reproducer: A tool/feature to enable easy reproduction of objectives

Once the launcher is a little more mature, another thing that would be awesome to add to it is a 'reproducer' mode, which takes a given objective-achieving corpus member (or a set of them?) and re-runs them under some combination of the original and additional harnesses/sanitizers/etc. conditions, allowing easy reproduction of the test cases. This is especially important with frida-asan, as the target binary itself no longer has the built-in ASAN instrumentation.

Perhaps we should also assign a unique string or tag (some random hash/twister) to each objective achieving test case, so that they can be easily identified. This is something lacking in afl++. The filenames it produces are not unique, and it's easy to loose track of them.

Thoughts?

Test cases stored to disk should have globally unique file names

Currently, we use names of the form id_{} to name test cases stored to disk using an OnDiskCorpus.

We should change this behavior so that we have globally unique test case names. This can be achieved by combining some minimal metadata (such as timestamp, last mutator) with a hash of the test case input data.

Google Summer of Code

Welcome Students :)

This is libAFL, our new fuzzing library. It's not public just yet, but will be opened up soon!
Take a look around in the code base, look at the (todos)[./TODOS.md] and issues if you already feel like coding, feel free to post any questions in this issue or open your own issues.

In case anybody wants to open a PR, talk to @andreafioraldi or me.

Proposed projects

In this issue, I proposed several projects based on libafl (like libafl_frida) that we would be glad to include here.
As LibAFL is newly born there is a lot of work on the lib itself and we mostly work only on it, so we are seeking help for these projects.

  • Start rewriting AFL++'s afl-fuzz in Rust as a frontend of LibAFL. We aim to be compatible with the current C implementation. The core logic is already in LibAFL, but the rewriting is a not trivial software engineering task.

    • Outcome: the implementation, even if not with feature parity with AFL++
    • Skills: Rust, C, system programming, software engineering
    • Difficulty: medium
    • Possible mentors: @vanhauser-thc @andreafioraldi @domenukk
    • Length: 350 hours
  • Extend Forkserver (#111) to work on windows including https://github.com/sslab-gatech/winnie/tree/master/forklib from Winnie in libafl_targets

    • Outcome: the implementation and a set of working examples combined with SanCov and libafl_frida
    • Skills: Rust, C, system programming, win32 development
    • Difficulty: medium
    • Possible mentors: @domenukk @andreafioraldi @tokatoka
    • Length: 175 hours
  • Frida ASan and CmpLog for Windows and other architectures (arm, arm64, x86, x86_64). Most of the code can be ported from C (https://github.com/AFLplusplus/AFLplusplus/tree/stable/frida_mode) to Rust.

    • Outcome: the implementation and a set of working examples
    • Skills: Rust, C, assembly, system programming, win32 development
    • Difficulty: medium
    • Possible mentors: @tokatoka @domenukk
    • Length: 175 hours
  • Injectable libafl_frida into running targets + Javascript API support for libafl_frida and libafl_sugar. The work may involve patches and contributions to the Frida's Rust bindings https://github.com/frida/frida-rust

    • Outcome: the implementation and a set of working examples
    • Skills: Rust, C, assembly, system programming, win32 development
    • Difficulty: medium
    • Possible mentors: @andreafioraldi @tokatoka
    • Length: 175 hours
  • Implement syscall emulation for filesystem and network in libafl_qemu. The student must implement something similar to preeny to hook the network API and an emulator filesystem that can be snapshot-restored always hooking the syscall in libafl_qemu user mode

    • Outcome: the implementation and a set of working examples
    • Skills: Rust, C, system programming
    • Difficulty: medium
    • Possible mentors: @andreafioraldi @domenukk @rmalmain
    • Length: 175 hours
  • Implement the Pangolin mutator (https://wcventure.github.io/FuzzingPaper/Paper/SP20_PANGOLIN.pdf) on top of the existing concolic execution API

    • Outcome: the implementation and a set of working examples
    • Skills: Rust, C++, experience in symbolic execution
    • Difficulty: medium
    • Possible mentors: @domenukk @vanhauser-thc @addisoncrump
    • Length: 175 hours
  • LibAFL Workers / RemoteWorkerLauncherStage + RemoteWorkerCollectorStage. The details are in #293

    • Outcome: the implementation and a set of working examples
    • Skills: Rust
    • Difficulty: medium
    • Possible mentors: @domenukk @tokatoka @addisoncrump
    • Length: 175 hours
  • Implement AFLGo Implement the AFLGo directed fuzzer https://github.com/aflgo/aflgo

  • Create a libafl qemu based clone of afl-qemu-trace to be used in AFL++

    • Outcome: a feature equivalent clone of afl-qemu-trace with all the supported env vars
    • Skills: Rust, C
    • Difficulty: medium
    • Possible mentors: @andreafioraldi @rmalmain @vanhauser-thc
    • Length: 175 hours
  • Adapt kAFL / Nyx to LibAFL QEMU. For now, LibAFL QEMU supports emulation for both user-mode and system-mode. We would like to fully integrate hypervisor-based fuzzing to LibAFL QEMU, with an up-to-date kernel module and integration with the current implementation (snapshotting, etc.).

    • Outcome: the implementation, even if not with feature parity with AFL++
    • Skills: Rust, C, system programming, software engineering, linux kernel
    • Difficulty: medium
    • Possible mentors: @rmalmain
    • Length: 350 hours

Then, if you want to implement any of the recent fuzzing techniques (https://wcventure.github.io/FuzzingPaper/ can be useful) feel free to ping us in order to know if we are already implementing the technique that you are interested in or not.

Move Time Feedback to std::time::Instant

Rust's stdlib has std::time::Instant for monotonically increasing time diffs.

let start = Instant::now();
// ...
let dur = start.elapsed(); // Doesn't panic on instants produced with Instant::now()

That'd require the std flag for TimeObserver though. (The current implementation doesn't do anything on no_std atm..)

Originally posted by @Mrmaxmeier in #141 (comment)

We should probably use Instant here.
The no_std parts right now won't work, in any case.
The no_std targets either need to use hardware counters, or will not work

Update windows.rs

Our windows.rs is 0.4 and now it is at 0.10, they have broken the API but we should update it for 0.4

Add fuzzers to CI, more CI targets

Currently, we do not have CI set up for all fuzzers in ./fuzzers.
All of them should be built (and maybe even tested for a short while) as part of a GitHub action.
Also, we would love to have CI for Android and potentially MacOS.

Launcher

Right now, we have to start each node individually.
We should offer an optional Launcher, that
a) spawns a broker
b) forks or spawns n clients
c) silences the client's outputs
c) binds each client to a cpu core
d) fuzzes.

For fork (on unix), we can use this method

pub unsafe fn fork() -> Result<ForkResult, Error> {

For windows, we need to restart ourselves in a
pub fn startable_self() -> Result<Command, Error> {

Adding mutator stats method

Hi,

I'm thinking of adding mutator stats mothod to mutators.
as mentioned here https://github.com/AFLplusplus/LibAFL/blob/main/libafl/src/mutators/mod.rs#L12

My current idea is to add a fn mutate_with_log to Mutator trait, which mutates the input but also records what kinds of mutations have been applied during the mutation.

So, for example, for ScheduledMutator, I'd like to add a function like
fn scheduled_mutate_with_log(&self, state: &mut S, input: &mut I, _stage_idx: i32) -> Result<Vec<MutationType>, Error>
and here we record the mutation before calling the actual mutation function (self.mutation_by_idx(idx)(state, input)?)

and then we pass the log to state.evaluate_input
(as in https://github.com/AFLplusplus/LibAFL/blob/main/libafl/src/stages/mutational.rs#L60)

and finally the mutation log is packed into something like Event::NewTestcase so that they would be handled by the broker later.
(as in https://github.com/AFLplusplus/LibAFL/blob/main/libafl/src/state/mod.rs#L523)

Does this seem to be a good idea?

frida-asan: add `asan-cores` option

Add an asan-cores option to LIBAFL_FRIDA_OPTIONS, which allows specifying which cores should run in ASAN mode. Cores not in this list should run without.

Handling/Warning for OOM

Hey I just played a little bit with this library and tried to fuzz libcue.

After some time the client just spamms this message over and over:

thread 'main' panicked at 'Allocated new message without calling send() inbetween. ret: 0x7f01465ad030, page: 0x7f01465ad000, complete_msg_size: 48, size_used: 1736144, last_msg: 0x0', /home/max/projects/fuzzing/LibAFL/libafl/src/bolts/llmp.rs:745:13
stack backtrace:
   0: rust_begin_unwind
             at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:493:5
   1: std::panicking::begin_panic_fmt
             at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:435:5
   2: libafl::bolts::llmp::LlmpSender<SH>::alloc_next_if_space
             at /home/max/projects/fuzzing/LibAFL/libafl/src/bolts/llmp.rs:745:13
   3: libafl::bolts::llmp::LlmpSender<SH>::alloc_next
             at /home/max/projects/fuzzing/LibAFL/libafl/src/bolts/llmp.rs:823:37
   4: libafl::bolts::llmp::LlmpSender<SH>::send_buf
             at /home/max/projects/fuzzing/LibAFL/libafl/src/bolts/llmp.rs:866:23
   5: libafl::bolts::llmp::LlmpClient<SH>::send_buf
             at /home/max/projects/fuzzing/LibAFL/libafl/src/bolts/llmp.rs:1765:9
   6: libafl::bolts::llmp::LlmpConnection<SH>::send_buf
             at /home/max/projects/fuzzing/LibAFL/libafl/src/bolts/llmp.rs:439:52
   7: <libafl::events::llmp::LlmpEventManager<I,S,SH,ST> as libafl::events::EventManager<I,S>>::fire
             at /home/max/projects/fuzzing/LibAFL/libafl/src/events/llmp.rs:375:9
   8: <libafl::events::llmp::LlmpRestartingEventManager<I,S,SH,ST> as libafl::events::EventManager<I,S>>::fire
             at /home/max/projects/fuzzing/LibAFL/libafl/src/events/llmp.rs:468:9
   9: libafl::state::State<C,FT,libafl::inputs::bytes::BytesInput,OFT,R,SC>::load_initial_inputs
             at /home/max/projects/fuzzing/LibAFL/libafl/src/state/mod.rs:611:9
  10: libfuzzer_libcue::fuzz
             at ./src/fuzzer.rs:164:9
  11: libfuzzer_libcue::main
             at ./src/fuzzer.rs:65:5
  12: core::ops::function::FnOnce::call_once
             at /home/max/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
[libafl/src/events/llmp.rs:553] "Spawning next client (id {})" = "Spawning next client (id {})"
[libafl/src/events/llmp.rs:553] ctr = 1337
We're a client, let's fuzz :)
First run. Let's set it all up
We're a client, let's fuzz :)
Loading file "./corpus/test.cue" ...

My fuzzer is identical to that of the libpng example. Only the build and harness script is different. If you need the code then I can upload it somewhere as ZIP as forking is disabled and I can not create branches.

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.