.. _session: Session ======= .. autoclass:: boofuzz.Session :members: :undoc-members: :private-members: :show-inheritance: Request-Graph visualisation options ----------------------------------- The following methods are available to render data, which can then be used to visualise the request structure. .. automethod:: boofuzz.Session.render_graph_gml .. automethod:: boofuzz.Session.render_graph_graphviz .. automethod:: boofuzz.Session.render_graph_udraw .. automethod:: boofuzz.Session.render_graph_udraw_update Backward link to the session ---------------------------- Originally in Boofuzz, the children elements of a :class:`Session` (e.g. :class:`Target`, :class:`Request`...) didn't have a way to get back to the session. This caused two problems : 1. In each primitive, we needed a way to know the current round type (e.g Library, Random Mutation, or Random Generation), and for the last two, to get a seed for the random. We found that the best way to standardized the process of choosing the round type and the seed accross all primitives of a session was to define those elements in a :class:`Session` object, thus the need to access it from each primitive. Considering that they already had access to their request, we decided to simply give access to the :class:`Request` of its session. Each of them can now access it using the :attr:`self.request.parent_session` attribute. The process of linking the request to the session is done in the :meth:`Session.connect` method. 2. In the target, we needed a way to inform the session of a socket timeout from one of the :class:`BaseSocketConnection` inherited classes. That was necessary to be able to skip the test case causing the timeout, not to stay stuck in it. We first add to give access to the Target with the :attr:`BaseSocketConnection.parent_target`, then to link the :class:`Target` object to it :class:`Session` object through the :attr:`Target.parent_session` attribute. This is done in the :class:`BaseConfig` class. Timeout calculation ------------------- In Fuzzungus, we wanted to be able to flag a timeout on a test case to identify delay variations of the target that could be a sign of a crash. To do that, we needed to calculate the timeout of each test case separatly. We added a new attributes to the :class:`Request` object : :attr:`timeout_check` : A boolean to be able to skip the timeout check on a specific request, for example for data nodes for which the timeout is not relevant. For timeout calculation, we used the TCP formula : .. math:: \begin{aligned} & srtt = (1 - g)(srtt) + g.M\\ & rttvar = (1 - h)(rttvar) + h|M - srtt|\\ & RTO = srtt + 4(rttvar) \end{aligned} See the `RFC 6298 - Computing TCP's Retransmission Timer `_ for more informations on the calculations. They are implemented in :class:`Request` through the :meth:`Request.calculate_rto` method. This method is called in :meth:`Session.transmit_all`, that calculates RTO the same way for fuzzed and normally transmited nodes. :meth:`Session.transmit_all` is another addition to Boofuzz, to avoid implementing the same action two times for the :meth:`Session._transmit_fuzz` and :meth:`Session._transmit_normal` methods. Fragmentation ------------- In some protocols, the length of some packets depends on the configuration of the communication. When the fragmentation must be done in the application layer, we have to define it in the :class:`Request` definition. For that, we have to define 2 attributes, :attr:`Request.fragmentation_length` and :attr:`Request.fragmentation`. :attr:`Request.fragmentation_length` is the packet's data size. :attr:`Request.fragmentation` is a function that must be defined by your own in the callback file that you import for the session. We implemented a TFTP fragmentation function in tftp_callback.py which increment the block's number properly and concatenate it with the maximum of data that it can. When a request with the attribute :attr:`Request.fragmentation` is fuzzed, the whole of the data are generated by first and then cut. Send and receive are looped while the fragmentation function yield something. Multiple Acks ------------- Multiple acks are used in case of an application has to send us data which are truncated, and we have to reply to each data block before fuzz the rest of the session. That case is handled by a callback function which has to be defined in the callback file that we import for the session, and it has to be connected. (refer to callbacks) An example of multiple acks is given for the TFTP protocols in the tftp_callback.py file. The callback function is connected after a read request. It receives the data, get the numblock, and send an ack with the right block.