Callbacks

Callbacks function are some function that depends on majority to which protocol do we fuzz. They are used to manage a communication with a server.

For example, a callback function can be used in FTP, to switch the port in the communication.

Firstly and due to the dependencies of the fuzzed protocol, these functions are declared in differents Class in the callback folder and inherit of the BaseCallback. They can be used at the beginning of a test case: pre_send() or after the fuzzed node (end of test case) : post_send(). They can also be called between 2 Requests by using the Request.connect(request1,request2,callback_function)().

How to define it ?

First, define the callback name Class:

class MyCallbackClass(BaseCallback):

then define your functions in that class

These functions have to follow the prototype:

def callback_exemple(self, target, fuzz_data_logger, session, *args, **kwargs):

How to use it ?

Firstly we have to add our callback module to boofuzz/__init__.py :

from .myfilename import MyCallbackClass

and add it to __all__

then, add it to boofuzz/__init__.py

from .callbacks import(MyCallbackClass)

then in __all__.

In the session definition, we define which Callback class that we are going to use:

callback_module = MyCallbackClass

Then, you can call it in the session definition with:

self.cb.callback_exemple

Example

I want to fuzz a TFTP server, I send first a write request on the port 69. The server is replying an ACK with an other port than the port 69 and then i have to send data on this specific port.

First i will define my callback function.

def control_to_data(self, target, fuzz_data_logger, session, *args, **kwargs):
    #First target is bind to the port 69 so let's use an other one
    session.target_to_use = 1
    #We get the connection attribute form the both targets (an UDP socket there)
    connection_target0 = session.targets[0].get_connection()
    connection_target1 = session.targets[1].get_connection()
    #And we force the second target to use the same port as the first one for sending
    connection_target1.use_same_port(connection_target0)
    #We now bind the second target to the port who has been used by the server
    connection_target1.port = connection_target0.get_udp_client_port()[1]
    #Finnaly, we open the connection
    session.targets[session.target_to_use].open()

Now, in my tftp_example.py, when I connect the write request to the data node, I specify this function.

connect(wrq,data,callback=self.cb.control_to_data)

Change Default value during a fuzzing session

In the case, you have to change a default value during a session depending of last reply you received, you can for example do that:

session.nodes[1].stack[2]._default_value=session.last_recv[4:6]

That fix the new default value of the 1st node, 2nd field to the value that we received last.