profuzz_core/lib.rs
1//!
2//! `profuzz` is a generic approach to easily create a fast and easy-to use network protocol fuzzer for custom targets.
3//!
4//! `profuzz` aims to be used mainly in the embedded world, where most of the time it is not easy to create a
5//! running harness on a Linux-based system because of hardware dependencies, the source code is not available,
6//! or it requires hardware attacks to dump the firmware. Dumping the firmware, reverse engineering, and then
7//! fuzzing potential targets is time intensive. In these cases `profuzz` can be used to find "low-hanging"
8//! fruits by fuzzing either the network stack itself or custom binary protocols.
9//!
10//! To use the `profuzz_core` you have to implement the following traits:
11//! - `Healthcheck`: Used to verifiy to correct working of the target
12//! - `Transport`: Used to send and receive messages to the target
13//! - `Mutate`: Used to mutate the corpus files
14//! - `ResetHandler`: Used to reset the target in case it did crash
15//!
16//! You can find common implementation ready to use in the [profuzz_common](https://github.com/otsmr/profuzz/blob/main/profuzz_common) crate.
17//!
18//! The following code shows the basic setup required to create a network stack fuzzer. It uses a TCP server on
19//! the target to detect a crash and sends the packets directly on eth0.
20//!
21//! `profuzz_core` can be configured and started either in headless mode or using `start_cli` allowing the user
22//! to configure the different options using CLI.
23//!
24//! In case you want to use `profuzz` in headless mode, please have a look into the cli.rs to see
25//! how to set the fuzzing engine up directly.
26//!
27//! The full example can be found in the [example](https://github.com/otsmr/profuzz/tree/main/example) folder.
28//!
29//! ```rs
30//! #[tokio::main]
31//! async fn main() {
32//! // Defining the Transport layer, in this case a raw linux socket.
33//! let transport = RawSocketTransport::new("eth0");
34//!
35//! // Defining the Healthcheck to detect a crash
36//! let healthcheck = TcpHealthcheck::new(
37//! "lo0",
38//! TcpPacket {
39//! eth_src: MacAddr::from_str("32:a4:e7:9a:c7:99").unwrap(),
40//! eth_dst: MacAddr::from_str("32:a4:e7:9a:c7:8a").unwrap(),
41//! vlan_id: None,
42//! ipv4_src: Ipv4Addr::from([127, 0, 0, 2]),
43//! ipv4_dst: Ipv4Addr::from([127, 0, 0, 1]),
44//! dport: 1337,
45//! sport: 1330,
46//! },
47//! )
48//! .unwrap();
49//!
50//! // Setting up the protocol fuzzer with the different implementations
51//! let fuzzer = ProFuzzBuilder::new(transport, healthcheck, DummyResetHandler());
52//!
53//! // Starting the CLI including a TUI, and defining the `Mutable` implementation struct that
54//! // implements the mutation of the corpus files
55//! if let Err(err) = fuzzer.start_cli::<EtherMutatorOwned>().await {
56//! eprintln!("{err}");
57//! }
58//! }
59//! ```
60//!
61
62#![deny(missing_docs)]
63#![deny(unsafe_code, clippy::unwrap_used)]
64#![warn(clippy::pedantic)]
65
66/// Contains all `traits` that have to be defined to use `profuzz_core`. There are common
67/// implementations in the `profuzz_common` crate that could be used.
68pub mod traits;
69
70/// Contains the fuzzing engine and the TUI which can also be used in a headless mode.
71pub mod fuzz;
72
73/// Manage the logger. This can be used to initialize the `tracing_subscriber` in case
74/// `profuzz_core` is used in headless mode.
75pub mod log;
76
77/// Output directory of the fuzzer
78pub mod output;
79
80/// Triage support for identifying the crash can be started via the cli or through the headless
81/// mode.
82pub mod triage;
83
84/// Contains all the different errors `profuzz_core` can return.
85pub mod error;
86
87/// Mutation engine which can be used to mutate numbers and bytes.
88pub mod mutator;
89
90/// Contains the `ProFuzzBuilder` to start `profuzz_core` in CLI mode.
91pub mod cli;
92
93mod dangerous_numbers;
94
95/// A internal collection of different types
96pub(crate) mod types;