This blog post will demonstrate how you can leverage Python to create a custom fuzzer script. When performing exploit research and development it is very useful to leverage a scripting language to send in varying amounts of input to try to cause an application to crash. Python can be very useful to spinning up a quick script to repeatedly connect to a service and send in varying amounts of input.
The first thing to understand is how the application handles user input. Once we have an idea of the type of input to send to the service, we can begin varying levels of input to the service. The basic idea is we connect to a service, send the buffer, increase the buffer, and then attempt it again. We can achieve this with a “while” loop and loop until we hit an exception with “while True”.
Here is our basic starter script/Pseudocode:
<import modules> # most likely will be socket, sys, but if its a web service you might import httplib, urllib, etc. # Set up remote IP/Port variables # Invoke the script: ./script.py <RHOST> <RPORT> RHOST = sys.argv RPORT = sys.argv # Define your buffer string that will be incremented until a potential crash buffer = 'x41'*50 # Create a loop that will connect to the service and send the buffer: while True: try: # send buffer # increment buffer by 50 buffer = buffer + 'x41'*50 except: print "Buffer Length: "+len(buffer) print "Can't connect to service...check debugger for potential crash"
The above script can be adopted to several different types of services. You can build up your script based on the type service you’d like to fuzz. Below is an example of a Python script to fuzz an FTP server based on the “USER” command.
# Import the required modulees the script will leverage # This lets us use the functions in the modules instead of writing the code from scratch import sys, socket from time import sleep # set first argument given at CLI to 'target' variable target = sys.argv # create string of 50 A's 'x41' buff = 'x41'*50 # loop through sending in a buffer with an increasing length by 50 A's while True: # The "try - except" catches the programs error and takes our defined action try: # Make a connection to target system on TCP/21 s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.settimeout(2) s.connect((target,21)) s.recv(1024) print "Sending buffer with length: "+str(len(buff)) # Send in string 'USER' + the string 'buff' s.send("USER "+buff+"rn") s.close() sleep(1) # Increase the buff string by 50 A's and then the loop continues buff = buff + 'x41'*50 except: # If we fail to connect to the server, we assume its crashed and print the statement below print "[+] Crash occured with buffer length: "+str(len(buff)-50) sys.exit()
This demonstrated some basic proof of concept fuzzer script, keep in mind that depending on the application sending in ‘x41’ wont crash the service. In some instances you need to send in different types of characters to generate a crash. A more advanced fuzzing tool is Spike, this will send in differently amounts and types of characters to try to crash the service. Practice making a Python fuzzer that makes an HTTP request to a service instead of an FTP server.