Public Member Functions | |
def | __init__ |
Constructor. | |
def | __del__ |
Destructor. | |
def | identifyIterationFinishMethod |
Identifies how should be end of iteration indicated. | |
def | initialize |
Does some additional initialization. | |
def | initAction |
Contains Peach Action initialization. | |
def | getNumOfSpecificAction |
Counts number of actions in the state with the same value as the given action. | |
def | getNumOfCloseActions |
Counts number of close actions. | |
def | handleDataModelElement |
Performs final translation of an element into a Peach structure. | |
def | decodeHexValuesAndFixPosition |
Decodes hexadecimal values and fixes position. | |
def | buildDataModel |
Requests data analysis and creates Peach Data Model. | |
def | applyHeuristics |
Applies additional heuristics on the elements in the Data Model. | |
def | findMutableElement |
Identifies if there is any mutable element in the Data Model. | |
def | processDataModel |
Identifies and sets mutable elements in fuzzed data. | |
def | getFuzzedData |
Perfrom mutation on data in the Data Model and get result value of the Data Model as single string. | |
def | storeFuzzingValues |
Stores fuzzing values for logging purposes. | |
def | reachedInputOutputActionsLimit |
Tests if numbers of input and output actions have reached recorded numbers of input and output actions. | |
def | runAction |
Runs single action during the process of fuzzing. | |
def | runTcpState |
Runs TCP proxy in a fuzzing mode. | |
def | runUdpState |
Runs UDP proxy in a fuzzing mode. | |
def | runState |
Starts proxy in a fuzzing mode. | |
def | raiseIterationFinishWhenClosed |
Checks if iteration should be terminated based on connection close. | |
def | recordAction |
Records single action during the process of recording. | |
def | recordSimpleAction |
Records simple action during the process of recording. | |
def | connectToServer |
Tries to connect to the target multiple times. | |
def | recordTcpState |
Runs TCP proxy in a recording mode. | |
def | recordUdpState |
Runs UDP proxy in a recording mode. | |
def | recordState |
Starts proxy in a recording mode. | |
def | processRecordedData |
Aggregates mutiple data models into single one. | |
def | isNumericalString |
Tests if the input element is a Numerical String. | |
def | outputDataModelBlock |
Writes Data Model block into configuration file. | |
def | outputRecordedData |
Creates configuration file based on recorded data. | |
def | applyDefaultRules |
def | compareModelsIsomorphism |
Compares template tree structure (number of children for every node) of the current data to a data model. | |
def | compareModelsNames |
Compares element names (assigned according to the protocol by the dissector) of the current data to a data model. | |
def | compareModelsTypes |
Compares element value types of the current data to a data model. | |
def | compareModelsValues |
Compares element values of the current data to a data model. | |
def | maxModelsValues |
Indicates maximum number of elements eglible for value comparison in current data. | |
def | compareModelsLengths |
Compares string element lengths of the current data to a data model. | |
def | maxModelsLengths |
Indicates maximum number of elements eglible for length comparison in current data. | |
def | compareDataModels |
Compares diffrent aspects of template tree structure of the current data to a data model. | |
def | findMatchingAction |
Interface to find the best match for the current data from the set of recorded data models. | |
def | compareTerminationActions |
Compares diffrent aspects of template tree structure of two given actions against given match ratio. | |
def | applyTemplateSettings |
Applies mutable flags to elements of current data based on matched data model. | |
def | guiCommunicator |
Extension for GUI Communication thread. | |
Public Attributes | |
recordIteration | |
Iterations counter for recording. | |
recordedStates | |
Array of recorded iterations. | |
tokenizer | |
Instance of string tokenizer. | |
relationFinder | |
Instace of relations finder. | |
debugDissect | |
Stores information whether dissection debug output should be enabled. | |
noFuzzing | |
Can be used to disable fuzzing completely. | |
mfile | |
Initialize dissection process. | |
seq_server | |
Client and server sequence numbers. | |
seq_client | |
We calculate new client sequence number. | |
isInitialized | |
We will require additional initialization. | |
connectionAttempts | |
iterationNumber | |
Iterations counter for fuzzing. | |
guiCommunicatorSocket | |
Socket used for communication with GUI. | |
iterationFinishMethod | |
How shall be the end of the iteration identified. | |
totalInputActionsCount | |
Numbers of recorded output and input iterations. | |
totalOutputActionsCount | |
inputActionsCounter | |
Counters for output and input iterations. | |
outputActionsCounter | |
Increase output actions counter. | |
hotseed | |
Seed for random mutation strategy. | |
addressToSendIterNum | |
Where should we send number of current iteration. | |
currentData | |
Little helping variables used for filling in missing data from Data analysis. | |
lastPosition | |
Dots make trouble, we will substitude all dots in elements name with underscore. | |
hotSleep | |
Indications from GUI Communicator. | |
detectedFault | |
Send iteration number to GUI. | |
nextAction | |
Try to match following data model in order of last known match. | |
seedCounter | |
If we have a seed for random mutation strategy, then store its values. | |
result | |
The direction of flowing data matters. |
Contains central logic of HotFuzz application. Logic includes TCP/UDP proxy, recording/fuzzing, Data matching, interaction with Data analysis, final translation from Wireshark structures to Peach structures, configuration file export, part of GUI Communicator
def Peach::Engine::ppaction::PpAction::__del__ | ( | self | ) |
Destructor.
def Peach::Engine::ppaction::PpAction::__init__ | ( | self | ) |
Constructor.
Contains initialization of variables and initialization of dissection process
def Peach::Engine::ppaction::PpAction::applyDefaultRules | ( | self, | ||
action, | ||||
data | ||||
) |
def Peach::Engine::ppaction::PpAction::applyHeuristics | ( | self, | ||
myDataModel | ||||
) |
Applies additional heuristics on the elements in the Data Model.
myDataModel | Input Data Model |
def Peach::Engine::ppaction::PpAction::applyTemplateSettings | ( | self, | ||
dataNode, | ||||
templateNode | ||||
) |
Applies mutable flags to elements of current data based on matched data model.
dataNode | Root node of the current data template tree | |
templateNode | Root node of the data model template tree |
def Peach::Engine::ppaction::PpAction::buildDataModel | ( | self, | ||
action, | ||||
stateEngine, | ||||
data | ||||
) |
def Peach::Engine::ppaction::PpAction::compareDataModels | ( | self, | ||
dataNode, | ||||
templateNode | ||||
) |
Compares diffrent aspects of template tree structure of the current data to a data model.
dataNode | Root node of the current data template tree | |
templateNode | Root node of the data model template tree |
def Peach::Engine::ppaction::PpAction::compareModelsIsomorphism | ( | self, | ||
dataNode, | ||||
templateNode | ||||
) |
Compares template tree structure (number of children for every node) of the current data to a data model.
dataNode | Root node of the current data template tree | |
templateNode | Root node of the data model template tree |
def Peach::Engine::ppaction::PpAction::compareModelsLengths | ( | self, | ||
dataNode, | ||||
templateNode | ||||
) |
Compares string element lengths of the current data to a data model.
dataNode | Root node of the current data template tree | |
templateNode | Root node of the data model template tree |
def Peach::Engine::ppaction::PpAction::compareModelsNames | ( | self, | ||
dataNode, | ||||
templateNode | ||||
) |
Compares element names (assigned according to the protocol by the dissector) of the current data to a data model.
dataNode | Root node of the current data template tree | |
templateNode | Root node of the data model template tree |
def Peach::Engine::ppaction::PpAction::compareModelsTypes | ( | self, | ||
dataNode, | ||||
templateNode | ||||
) |
Compares element value types of the current data to a data model.
dataNode | Root node of the current data template tree | |
templateNode | Root node of the data model template tree |
def Peach::Engine::ppaction::PpAction::compareModelsValues | ( | self, | ||
dataNode, | ||||
templateNode | ||||
) |
Compares element values of the current data to a data model.
dataNode | Root node of the current data template tree | |
templateNode | Root node of the data model template tree |
def Peach::Engine::ppaction::PpAction::compareTerminationActions | ( | self, | ||
firstAction, | ||||
secondAction, | ||||
matchRatio | ||||
) |
Compares diffrent aspects of template tree structure of two given actions against given match ratio.
firstAction | Action structure of one of compared actions | |
secondAction | Action structure of second of compared actions | |
matchRatio | - Ratio of matched elements compared to total elements which actions should reach in order for function to be true |
def Peach::Engine::ppaction::PpAction::connectToServer | ( | self, | ||
stateEngine | ||||
) |
Tries to connect to the target multiple times.
stateEngine | Package that stores most of our Peach structures |
def Peach::Engine::ppaction::PpAction::decodeHexValuesAndFixPosition | ( | self, | ||
dataModelElement, | ||||
positionFix | ||||
) |
Decodes hexadecimal values and fixes position.
Method does simultaneously two things:
dataModelElement | Input element | |
positionFix | Position fix |
def Peach::Engine::ppaction::PpAction::findMatchingAction | ( | self, | ||
currentAction, | ||||
templateActions | ||||
) |
Interface to find the best match for the current data from the set of recorded data models.
currentAction | Action structure of current data | |
templateActions | Action structures from set of recorded data models |
def Peach::Engine::ppaction::PpAction::findMutableElement | ( | self, | ||
dataModel | ||||
) |
Identifies if there is any mutable element in the Data Model.
Recursivelly tests if there is any mutable element in the Data Model. If not, then it makes no sence to perform fuzzing on this Data Model
dataModel | Input Data Model |
def Peach::Engine::ppaction::PpAction::getFuzzedData | ( | self, | ||
action, | ||||
mutator | ||||
) |
Perfrom mutation on data in the Data Model and get result value of the Data Model as single string.
action | Action to which the desired Data Model belongs to | |
mutator | Mutation strategy that performs the mutation |
def Peach::Engine::ppaction::PpAction::getNumOfCloseActions | ( | self, | ||
myState | ||||
) |
Counts number of close actions.
myState | Package containing all actions |
def Peach::Engine::ppaction::PpAction::getNumOfSpecificAction | ( | self, | ||
action, | ||||
state | ||||
) |
def Peach::Engine::ppaction::PpAction::guiCommunicator | ( | self, | ||
stateEngine | ||||
) |
def Peach::Engine::ppaction::PpAction::handleDataModelElement | ( | self, | ||
dataModelElement, | ||||
elementParent | ||||
) |
def Peach::Engine::ppaction::PpAction::identifyIterationFinishMethod | ( | self, | ||
myState | ||||
) |
Identifies how should be end of iteration indicated.
myState | Package containing all actions |
def Peach::Engine::ppaction::PpAction::initAction | ( | self, | ||
action, | ||||
mutator | ||||
) |
Contains Peach Action initialization.
def Peach::Engine::ppaction::PpAction::initialize | ( | self, | ||
stateEngine | ||||
) |
Does some additional initialization.
Does some additional initialization, which can not be done right at the beginning, when there is not enough information
stateEngine | Package that stores most of our Peach structures |
def Peach::Engine::ppaction::PpAction::isNumericalString | ( | self, | ||
element | ||||
) |
Tests if the input element is a Numerical String.
element | Input Element |
def Peach::Engine::ppaction::PpAction::maxModelsLengths | ( | self, | ||
dataNode, | ||||
templateNode | ||||
) |
Indicates maximum number of elements eglible for length comparison in current data.
dataNode | Root node of the current data template tree | |
templateNode | Root node of the data model template tree |
def Peach::Engine::ppaction::PpAction::maxModelsValues | ( | self, | ||
dataNode, | ||||
templateNode | ||||
) |
Indicates maximum number of elements eglible for value comparison in current data.
dataNode | Root node of the current data template tree | |
templateNode | Root node of the data model template tree |
def Peach::Engine::ppaction::PpAction::outputDataModelBlock | ( | self, | ||
writer, | ||||
block | ||||
) |
Writes Data Model block into configuration file.
writer | Writer used for writing into configuration file | |
block | Input block |
def Peach::Engine::ppaction::PpAction::outputRecordedData | ( | self, | ||
stateEngine | ||||
) |
Creates configuration file based on recorded data.
stateEngine | Package that stores most of our Peach structures |
def Peach::Engine::ppaction::PpAction::processDataModel | ( | self, | ||
stateEngine, | ||||
action | ||||
) |
Identifies and sets mutable elements in fuzzed data.
Identifies and sets mutable elements in data that are being forwarded through proxy during fuzzing process
stateEngine | State object in which previously recorded data models are stored | |
action | Action object representing current data |
def Peach::Engine::ppaction::PpAction::processRecordedData | ( | self | ) |
Aggregates mutiple data models into single one.
Merges and eliminates duplicities in data models produced in multiple test cases of recording process
def Peach::Engine::ppaction::PpAction::raiseIterationFinishWhenClosed | ( | self, | ||
serverClosedConnection, | ||||
clientClosedConnection, | ||||
numOfCloseActions | ||||
) |
Checks if iteration should be terminated based on connection close.
Needs some refactorization
def Peach::Engine::ppaction::PpAction::reachedInputOutputActionsLimit | ( | self | ) |
Tests if numbers of input and output actions have reached recorded numbers of input and output actions.
Used only when method Finish By Action Count is used as a termination method for iterations
def Peach::Engine::ppaction::PpAction::recordAction | ( | self, | ||
stateEngine, | ||||
data, | ||||
actionType | ||||
) |
Records single action during the process of recording.
stateEngine | Package that stores most of our Peach structures | |
data | Data to be analyzed and sent in this action | |
actionType | Type of action (output/input) |
def Peach::Engine::ppaction::PpAction::recordSimpleAction | ( | self, | ||
actionType | ||||
) |
Records simple action during the process of recording.
Records simple action without a Data Model. Used for close action
actionType | Type of action (output/input) |
def Peach::Engine::ppaction::PpAction::recordState | ( | self, | ||
stateEngine, | ||||
mutator | ||||
) |
Starts proxy in a recording mode.
stateEngine | Package that stores most of our Peach structures | |
mutator | Mutation strategy |
def Peach::Engine::ppaction::PpAction::recordTcpState | ( | self, | ||
stateEngine, | ||||
mutator | ||||
) |
Runs TCP proxy in a recording mode.
Performs TCP communication and recording
stateEngine | Package that stores most of our Peach structures | |
mutator | Mutation strategy |
def Peach::Engine::ppaction::PpAction::recordUdpState | ( | self, | ||
stateEngine, | ||||
mutator | ||||
) |
Runs UDP proxy in a recording mode.
Performs UDP communication and recording
stateEngine | Package that stores most of our Peach structures | |
mutator | Mutation strategy |
def Peach::Engine::ppaction::PpAction::runAction | ( | self, | ||
stateEngine, | ||||
mutator, | ||||
data, | ||||
actionType, | ||||
targetSocket | ||||
) |
Runs single action during the process of fuzzing.
stateEngine | Package that stores most of our Peach structures | |
mutator | Mutation strategy that performs the mutation | |
data | Data to be analyzed and sent in this action | |
actionType | Type of action (output/input) | |
targetSocket | Socket to be used for sending data |
def Peach::Engine::ppaction::PpAction::runState | ( | self, | ||
stateEngine, | ||||
mutator | ||||
) |
Starts proxy in a fuzzing mode.
stateEngine | Package that stores most of our Peach structures | |
mutator | Mutation strategy that performs the mutation |
def Peach::Engine::ppaction::PpAction::runTcpState | ( | self, | ||
stateEngine, | ||||
mutator | ||||
) |
Runs TCP proxy in a fuzzing mode.
Performs TCP communication and fuzzing
stateEngine | Package that stores most of our Peach structures | |
mutator | Mutation strategy that performs the mutation |
def Peach::Engine::ppaction::PpAction::runUdpState | ( | self, | ||
stateEngine, | ||||
mutator | ||||
) |
Runs UDP proxy in a fuzzing mode.
Performs UDP communication and fuzzing
stateEngine | Package that stores most of our Peach structures | |
mutator | Mutation strategy that performs the mutation |
def Peach::Engine::ppaction::PpAction::storeFuzzingValues | ( | self, | ||
stateEngine, | ||||
action | ||||
) |
Stores fuzzing values for logging purposes.
stateEngine | Package that stores most of our Peach structures | |
action | Input Action |
Where should we send number of current iteration.
Little helping variables used for filling in missing data from Data analysis.
Data comming from Wireshark are sometimes split into mutliple large blocks.
We need the elements in the blocks to have position relative to that block. For this purpose we will use positionFix variable First position fix is related to protocol headers. We are not interested in them, so we start counting our positions at the end of them Now go through all our large blocks (usually there is only one) Some blocks are returned from Wireshark as a result of previous segmentation. We are not interested into these blocks Decode hex values and fix positions We store whole value of this block globaly, so we can easilly identify data missing in the structure
Stores information whether dissection debug output should be enabled.
Send iteration number to GUI.
Socket used for communication with GUI.
Seed for random mutation strategy.
Indications from GUI Communicator.
Counters for output and input iterations.
Create fresh Peach Action.
If we are performing no fuzzing, then just forward the data.
Create fresh Peach Action Request Data analysis and build a Data Model for this Action from the data that we have Request Data matching. Returned value is used to identify whether this is the last action in this iteration Test whether it makes sence to fuzz this action Initialize this Action If we are fuzzing this action Perform fuzzing and get fuzzed data that are supposed to be sent Otherwise use original data Increase input actions counter
Request Data analysis and build a Data Model for this Action from the data that we have Store recorded action
We will require additional initialization.
Indicate that this method was already runned.
How shall be the end of the iteration identified.
Set proxy timeout to initial timeout.
Change the working directory for the application to the root directory of this application.
Identify how will be the end of an iteration indicated
Bind client listening socket Initialize client socket status Initialize server socket status Request PublisherCall on Client Agent Run while you should or you still have something to send Initialize list of sockets for reading If communication is completely Idle, append client listening socket to the input list If client socket is opened for reading and server has not just closed connection, append client socket to the input list If server socket is opened for reading and client has not just closed connection, append server socket to the input list Initialize list of sockets for writing If client socket is opened for writing and we have some information to send via this socket, append the socket to the output list If server socket is opened for writing and we have some information to send via this socket, append the socket to the output list We first try to read as much data as is possible in very short time If no data arrived to any socket, then we switch to sending If we have nothing to send, then switch back to reading If we received connection on client listening socket If server socket is closed for writing, then connect to the server Try to connect to the server multiple times If we failed to connect, then something wrong is going on and we just skip this iteration Successfuly connected If we are successfuly connected, then accept connection from the client If we received data on the client socket Get data form the socket Store data for server Client closed connection Close connection to client for reading Propagate close connection to the server There was some error in communication Close connection to client Propagate close connection to the server If we received data on the server socket Get data form the socket Store data for client Close connection to server for reading Propagate close connection to the client There was some error in communication Close connection to server Propagate close connection to the client If we are ready to send something to the client If we have any data to send Run this action If this action terminates the iteration, then we can stop the iteration NeedMoreDataException was not thrown, so obviously there were enough data Data analysis require more data Either way we have processed our data If we need to propagate close connection instead Close connection to client for write We have successfuly propagated close connection to the client If we are ready to send something to the server If we have any data to send Run this action If this action terminates the iteration, then we can stop the iteration NeedMoreDataException was not thrown, so obviously there were enough data Data analysis require more data Either way we have processed our data If we need to propagate close connection instead Close connection to server for write We have successfuly propagated close connection to the server Otherwise has communication timed out If the communication timed out and we are still processing some data, then something wrong happened Check if iteration was ended in a controlled way
Bind client UDP socket Initialize server UDP socket As UDP is much more simple then TCP, we will use following variables instead of SocketStatus Request PublisherCall on Client Agent Run while you should or you still have something to send We have no restrictions about reading Initialize list of sockets for writing If we have something to send via this socket, append the socket to the output list If we have something to send via this socket, append the socket to the output list We first try to read as much data as is possible in very short time If no data arrived to any socket, then we switch to sending If we have nothing to send, then switch back to reading If we received data on the client socket Some data have arrived this iteration Get data form the socket Store source address Store data for server This should never happen in UDP There was some error with the socket If we received data on the server socket Get data form the socket Store data for client This should never happen in UDP There was some error with the socket If we are ready to send something to the client If we have any data to send (we should definitely have some) Run this action NeedMoreDataException was not thrown, so obviously there were enough data If this action terminates the iteration, then we can stop the iteration Data analysis require more data Either way we have processed our data If we are ready to send something to the server If we have any data to send (we should definitely have some) Run this action NeedMoreDataException was not thrown, so obviously there were enough data If this action terminates the iteration, then we can stop the iteration Data analysis require more data Either way we have processed our data Otherwise has communication timed out If the communication timed out and we are still processing some data, then something wrong happened Check if iteration was ended in a controlled way
Iterations counter for fuzzing.
New iteration is starting.
Dots make trouble, we will substitude all dots in elements name with underscore.
Save data to pcap file for debugging purposes.
Recursivelly handle all child elements of this block.
If we are dealing with a block Create new Peach block Set size attribute of the block Set position attribute indicating position of this block in the whole model Set our current position in the whole model to the beginning of the block
Otherwise we are dealing with simple element If position of this element in the whole block differs from our position, then Wireshark skipped some data and we need to fill them back in Fill missing data as a new token ## Set our current position in the whole model to the end of the element
Request data analysis Request packet dissection Request translation into python structures If result is none, then we probably need to provide Data analysis with more data Create fresh Peach template This Action will be the parent of the new template, meaning that the template will be a Data Model for this Action Reinitialize our tokenizer We start with position 0
Initialize dissection process.
Pcap file to store flowing communication for debugging purposes
Try to match following data model in order of last known match.
Compare current data with recorded data models.
Match found, set mutable flags and appropriate termination function
Consider only communication in the same direction Match of non data Actions Compute score of the data model in order (in respect with the current fata) If the score is the highest so far, save the model as the best match
Can be used to disable fuzzing completely.
Increase output actions counter.
Array of recorded iterations.
Check for empty recorded state.
Iterations counter for recording.
Instace of relations finder.
The direction of flowing data matters.
Data flowing from server to client We merge our data with protocol headers.
Data flowing from client to server We give merge our data with protocol headers. These protocol headers are created based on protocol family,source IP address, source port, destination IP address, destination port, client sequence number and server sequence number. We provide fake IP addresses as they are not really relevant. As a target port we provide protocol port, as user might choose for his target application diferent target port than standard protocol port. That would be very confusing for Wireshark
These protocol headers are created based on protocol family,destination IP address, destination port, source IP address, source port, server sequence number and client sequence number.
If we have a seed for random mutation strategy, then store its values.
Send iteration number do GUI and check for instructions.
Calculate seed for mutation strategy for this iteration
We calculate new client sequence number.
Client and server sequence numbers.
We calculate new server sequence number.
Instance of string tokenizer.
Numbers of recorded output and input iterations.
First we look for action with attribute terminateTestCase.
If we find one, then this is the action which indicates end of iteration Next we try to test if there is only one close action from server and if it is at the end of communication. If so, we will use it to idicate end of iteration. This will obviously work only for tcp communication. If none of previous methods is applicable for our case, we will simply count input and output actions