How Peach Fuzzer Works (Execution Flow)
- No guess work
- Mutates the researcher provided structured inputs systematically
- Maintains protocol validity while breaking logic assumptions
Setup Diagram

DockerFile
FROM ubuntu:18.04
ENV DEBIAN_FRONTEND=noninteractive
# Update and install tools in one layer to save space
RUN apt-get update && apt-get install -y \
python2.7 \
mono-runtime \
nano \
wget \
unzip \
&& rm -rf /var/lib/apt/lists/*
# Fix the python shortcut
RUN ln -sf /usr/bin/python2.7 /usr/bin/python
WORKDIR /work
CMD ["/bin/bash"]

docker run -it --name peach-workshop peachfuzzer /bin/bash

Lab 1 | Vulnerable TCP Service
- The Python script represents a intentionally vulnerable network service.
- Simulate a custom protocol using a length-prefixed message.
- Provide a realistic fuzzing target without crashing the OS
💣 Root Cause: The service trusts user-supplied length values
fuzz_lab1.py
import socket
HOST = "127.0.0.1"
PORT = 9001
def read_line(conn):
data = b""
while not data.endswith(b"\n"):
chunk = conn.recv(1)
if not chunk:
break
data += chunk
return data
def handle(conn):
try:
# Read ASCII length line safely
length_line = read_line(conn).strip()
declared_len = int(length_line)
# Read payload (up to declared length)
data = b""
while len(data) < declared_len:
chunk = conn.recv(declared_len - len(data))
if not chunk:
break
data += chunk
# Logic bug (intentional)
if len(data) != declared_len:
print("[!] Logic error triggered!")
print(f"Declared={declared_len}, Actual={len(data)}")
# Dangerous allocation (intentional)
buffer = bytearray(declared_len)
buffer[:len(data)] = data
conn.send(b"OK\n")
except Exception as e:
print(f"[!] Crash / exception: {e}")
finally:
conn.close()
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen(5)
print("[+] Listening on 127.0.0.1:9001")
while True:
conn, addr = s.accept()
handle(conn)- Unbounded length trust :
declared_lenhas no validation - Logic flaw: Program continues execution even when
len(data) != declared_len - Malformed length + payload can break protocol assumptions.
recv(1)inread_line()allows slow client to hold connection indefinitely.- Connections can remain open forever, exhausting file descriptors.
- Any local client can interact with the service.
📥 Download Peach Fuzzer
It's old and no longer maintained, so I am directly installing the binaries from sourceforget

cd /work
mkdir peach_fuzzer
cd peach_fuzzer
wget https://sourceforge.net/projects/peachfuzz/files/Peach/3.1/peach-3.1.124-linux-x86_64-release.zip/download

Verify it's working
peach_fuzzer/peach -h
Create the vulnerable server file and paste the code described above to simulate a test environment.


docker exec -it peach-workshop /bin/bash
What is .PIT file?
In this file, we instruct the peach fuzzer framework what to fuzz, how to fuzz and where to fuzz.

fuzz_logic1.pit
<Peach>
<DataModel name="LengthProtocol">
<Block name="Request">
<String name="Length" value="64" mutable="true" token="true">
<Hint name="CharSet" value="0123456789"/>
</String>
<String name="Delimiter" value="\n"/>
<Blob name="Payload" length="64" mutable="true"/>
</Block>
</DataModel>
<StateModel name="OneShot" initialState="Send">
<State name="Send">
<Action type="output">
<DataModel ref="LengthProtocol"/>
</Action>
</State>
</StateModel>
<Test name="Default">
<StateModel ref="OneShot"/>
<Publisher class="TcpClient">
<Param name="Host" value="127.0.0.1"/>
<Param name="Port" value="9001"/>
<Param name="Timeout" value="2000"/>
</Publisher>
</Test>
</Peach>Peach Fuzzer Execution
apt-get install -y mono-devel
peach_fuzzer/peach fuzz_logic1.pit


Every crash doesn't implies a valid vulnerability.
What a researcher does after collecting all crashes
Analyze the crash & identify the category of the crash root cause:
- Logic error
- Out-of-bounds read
- Out-of-bounds write
- Use-after-free
- Integer overflow
- Infinite loop / hang
- Resource exhaustion

Fuzzing + crash analysis = how you find bugs Exploit development = how you turn them into 0-days
It's just the beginning 🤘
