> For the complete documentation index, see [llms.txt](https://aashraymt.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://aashraymt.gitbook.io/docs/vulnerability-research/fuzzing-1001/exercise-1.md).

# Exercise 1

[github.com/alex-maleno/Fuzzing-Module](http://github.com/alex-maleno/Fuzzing-Module)

## 1. Environment Preparation

### Installing Podman (Ubuntu 20.10+)

If Podman is not already installed, update your package list and install it.

```bash
sudo apt-get update sudo apt-get -y install podman
```

Verify the installation by checking the version:

```bash
podman --version
```

<figure><img src="/files/FQ8NQVxU4KS2rqiR81Gz" alt=""><figcaption></figcaption></figure>

### Cloning Repositories

Ensure `git` is installed, then clone both the AFL++ repository and the target exercise repository.

```bash
# Clone AFL++ git clone https://github.com/AFLplusplus/AFLplusplus # Clone the target Fuzzing-Module repository mkdir -p ~/Documents/ost2/ cd ~/Documents/ost2/ git clone https://github.com/alex-maleno/Fuzzing-Module.git
```

## 2. Container Initialization

Using a container simplifies the setup process, though bare-metal execution is recommended for maximum performance in real-world fuzzing scenarios.

<figure><img src="/files/iB3yZZ0EqZbEQKGnZOCj" alt=""><figcaption></figcaption></figure>

{% stepper %}
{% step %}

### Pull the AFL++ Image

```bash
podman pull docker.io/aflplusplus/aflplusplus
```

{% hint style="info" %}
You can use `podman images` to list and verify the pulled image.
{% endhint %}
{% endstep %}

{% step %}

### Mount the Target and Run the Container

```bash
podman run --rm -it -v $(pwd)/Fuzzing-Module/exercise1:/target <IMAGE ID>
```

**Command Breakdown:**

* `-rm`: Automatically removes the container after it exits.
* `i`: Keeps STDIN open even if not attached.
* `t`: Allocates a pseudo-TTY for the container.
* `v`: Binds a volume into the container (mounting the exercise folder to `/target`).
  {% endstep %}
  {% endstepper %}

<figure><img src="/files/FGssALpkKeydnLFuoHQK" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/vNP3NjrNDmNJklrD0kTt" alt=""><figcaption></figcaption></figure>

## 3. Target Compilation with AFL++ Tooling

Inside the container, navigate to the target directory and set up the build environment to use AFL++'s modified Clang compilers. This injects the necessary instrumentation hooks into the binary.

{% stepper %}
{% step %}

### Create the Build Directory

```bash
cd /target/ mkdir build cd build
```

{% endstep %}

{% step %}

### Configure CMake

```bash
CC=/AFLplusplus/afl-clang-fast CXX=/AFLplusplus/afl-clang-fast++ cmake ..
```

This overrides the default compilers, instructing CMake to generate build files using `afl-clang-fast`.

<figure><img src="/files/b9ba0hoYlK07sFIIZkG2" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

### Compile the Target

```bash
make
```

This generates an instrumented executable named `simple_crash` (as defined in the `CMakeLists.txt`).

<figure><img src="/files/f7imJWcP5l8TBRLUAj5a" alt=""><figcaption></figcaption></figure>
{% endstep %}
{% endstepper %}

## 4. Fuzzing Execution

{% stepper %}
{% step %}

### Generate an Initial Seed Corpus

Create a random initial corpus of test cases for the fuzzer to mutate.

<figure><img src="/files/M1M7hBj7HUNXJuaVKBA1" alt=""><figcaption></figcaption></figure>

```bash
cd /target/build/ mkdir seeds cd seeds for i in {0..4}; do dd if=/dev/urandom of=seed_$i bs=64 count=10; done
```

{% endstep %}

{% step %}

### Run AFL++

Execute the fuzzer against the compiled target.

```bash
/AFLplusplus/afl-fuzz -i /target/build/seeds/ -o /target/out -m none -- /target/build/simple_crash
```

**Command Breakdown:**

* `i`: Input directory containing the seed test cases.
* `o`: Output directory for fuzzer findings.
* `m none`: Disables memory limits for the child process.
  {% endstep %}

{% step %}

### Stop the Fuzzer

Press `Ctrl+C` to terminate the process. A good indicator to stop is when no new crashes occur after a period of time, such as once you have reached 3 saved crashes for this exercise.

<figure><img src="/files/ZYs889Dqggsi0SB9ReQ4" alt=""><figcaption></figcaption></figure>
{% endstep %}
{% endstepper %}

## 5. Result Analysis

Once the fuzzing session is stopped, all findings are stored in the output directory (`/target/out`).

<figure><img src="/files/wFGVqjBWtcORnsQMzucS" alt=""><figcaption></figcaption></figure>

### Output Directory Structure

* `out/default/crashes/`: Contains crash files identified by AFL++. Each file represents an input that caused a potential vulnerability/bug, such as `id:000000,src:000000,op:havoc,rep:4`.
* `out/default/hangs/`: Contains files that caused timeouts, useful for identifying performance issues or infinite loops.
* `out/default/queue/`: Contains the "synthesized corpus" (test cases that exercised unique execution paths).

{% hint style="info" %}
**Triage Tip:** Use `xxd <crash file>` to view a hexadecimal dump of the crash file for enhanced readability.
{% endhint %}

## 6. Crash Triage and Debugging (VS Code + GDB)

Because AFL++ injects instrumentation instructions during fuzzing, debugging requires a clean build with standard debug symbols (`-g`).

{% stepper %}
{% step %}

### Exit the Container

Type `exit` or press `Ctrl+D` to return to your host machine.
{% endstep %}

{% step %}

### Compile with Debug Symbols

Navigate to the exercise folder on your host and recompile using standard `g++`.

{% hint style="info" %}
Install `g++` via `sudo apt install -y g++` if necessary.
{% endhint %}

```bash
cd ~/Documents/ost2/Fuzzing-Module/exercise1 g++ -g simple_crash.cpp -o simple_crash_debug
```

{% endstep %}

{% step %}

### Configure VS Code for Debugging

Open the project folder in VS Code:

```bash
code ~/Documents/ost2/Fuzzing-Module/exercise1
```

Navigate to **Run -> Add Configuration -> C/C++: (gdb) Launch**. Replace the contents of the generated `launch.json` with the following configuration, ensuring the paths match your environment:

<figure><img src="/files/D4jLJ593vyzcd0FLB8LS" alt=""><figcaption></figcaption></figure>

```json
{ "version": "0.2.0", "configurations": [ { "name": "(gdb) Launch", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/simple_crash_debug", "args": [ "<", "${workspaceFolder}/out/default/crashes/id:000000,sig:06,src:000016,time:203,execs:181,op:havoc,rep:3" ], "stopAtEntry": false, "cwd": "${fileDirname}", "environment": [], "externalConsole": false, "MIMode": "gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true }, { "description": "Set Disassembly Flavor to Intel", "text": "-gdb-set disassembly-flavor intel", "ignoreFailures": true } ] } ] }
```

{% hint style="info" %}
Update the target crash file name in the `"args"` array to match a specific crash file generated on your machine.
{% endhint %}
{% endstep %}

{% step %}

### Start Debugging

Open `simple_crash.cpp` and press `F5` (or **Run -> Start Debugging**) to run the program against the crash file in GDB.

<figure><img src="/files/Rpo5fb5WSwr9x3r4Rp99" alt=""><figcaption></figcaption></figure>

We can now see where the crash occurred within the code and the payload.&#x20;
{% endstep %}
{% endstepper %}
