Exemple #1
0
    def run(self):
        self.log.info("Start the network oracle based on given MMSTD")

        # Create a new and clean memory
        memory = Memory()
        # memory = Memory(self.mmstd.getVocabulary().getVariables())
        memory.createMemory()
        # Create the abstraction layer for this connection
        abstractionLayer = AbstractionLayer(self.communicationChannel,
                                            self.mmstd.getVocabulary(), memory)

        # And we create an MMSTD visitor for this
        anID = str(uuid.uuid4())
        self.oracle = MMSTDVisitor(anID, "MMSTD-NetworkOracle", self.mmstd,
                                   self.isMaster, abstractionLayer)
        abstractionLayer = AbstractionLayer(self.communicationChannel,
                                            self.mmstd.getVocabulary(), memory)

        # And we create an MMSTD visitor for this
        anID = str(uuid.uuid4())
        self.oracle = MMSTDVisitor(anID, "MMSTD-NetworkOracle", self.mmstd,
                                   self.isMaster, abstractionLayer)
        self.oracle.start()

        while (self.oracle.isAlive()):
            time.sleep(0.01)

        self.log.warn("The network ORACLE has finished")
    def _specializeField(self, specializingPath=None):

        if specializingPath is None:
            specializingPath = SpecializingPath(memory=Memory())

        # we retrieve the field definition domain
        domain = self.field.domain

        # and check it exists
        if domain is None:
            raise Exception("No definition domain specified for field '{0}', cannnot parse the content against it.".format(self.field.name))

        # we create a first VariableParser and uses it to parse the domain
        variableSpecializer = VariableSpecializer(domain)
        resultSpecializingPaths = variableSpecializer.specialize(specializingPath)

        for resultSpecializingPath in resultSpecializingPaths:

            assignedData = bitarray('')
            if resultSpecializingPath.isDataAvailableForVariable(self.field.domain):
                assignedData = resultSpecializingPath.getDataAssignedToVariable(self.field.domain)
            else:
                resultSpecializingPath.addResult(self.field.domain, assignedData)

            self._logger.debug("FieldSpecializer Result: {0}".format(assignedData))
            resultSpecializingPath.addResultToField(self.field, assignedData)

        return resultSpecializingPaths
    def _specializeFieldWithChildren(self, specializingPath=None):

        if specializingPath is None:
            specializingPath = SpecializingPath(memory=Memory())

        resultPaths = [specializingPath]
        for child in self.field.fields:
            fs = FieldSpecializer(child, presets = self.presets)

            tmpResultPaths = []
            for path in resultPaths:
                tmpResultPaths.extend(fs.specialize(path))
            resultPaths = tmpResultPaths

        for resultPath in resultPaths:
            value = None
            for child in self.field.fields:
                childResult = resultPath.getDataAssignedToVariable(child.domain)
                if value is None:
                    value = childResult.copy()
                else:
                    value += childResult.copy()

            resultPath.addResult(self.field.domain, value)
            resultPath.addResultToField(self.field, value)

        return resultPaths
Exemple #4
0
 def __init__(self, channel, symbols):
     self.channel = channel
     self.symbols = symbols
     self.memory = Memory()
     self.specializer = MessageSpecializer(memory=self.memory)
     self.parser = MessageParser(memory=self.memory)
     self.flow_parser = FlowParser(memory=self.memory)
Exemple #5
0
    def run(self):
        self.log.info("Start the network oracle based on given MMSTD")

        # Create a new and clean memory
        memory = Memory()
        # memory = Memory(self.mmstd.getVocabulary().getVariables())
        memory.createMemory()
        # Create the abstraction layer for this connection
        abstractionLayer = AbstractionLayer(self.communicationChannel,
                                            self.mmstd.getVocabulary(), memory)

        # And we create an MMSTD visitor for this
        anID = str(uuid.uuid4())
        self.oracle = MMSTDVisitor(anID, "MMSTD-NetworkOracle", self.mmstd,
                                   self.isMaster, abstractionLayer)
        self.oracle.start()

        while (self.oracle.isAlive()):
            time.sleep(0.01)

        self.log.warn("The network ORACLE has finished")
    def specialize(self, specializingPath=None):
        """Execute the specialize operation"""

        if specializingPath is None:
            specializingPath = SpecializingPath(memory=Memory())

        self._logger.debug("Specialize field {0}".format(self.field.name))

        # does an arbitrary value is specified ?
        if self.arbitraryValue is not None:
            specializingPath.addResult(self.field.domain, self.arbitraryValue)
            specializingPath.addResultToField(self.field, self.arbitraryValue)
            return [specializingPath]

        # does current field has children
        if len(self.field.fields) > 0:
            return self._specializeFieldWithChildren(specializingPath)
        else:
            return self._specializeField(specializingPath)
Exemple #7
0
class MessageParser(object):
    """This class is used to produce the alignment of a message against a symbol
    specification. It can also be used to abstract a message against a symbol


    Below codes illustrates how to parse a message according to a single symbol.

    
    >>> from netzob.all import *
    >>> msg = RawMessage("hello world !")
    >>> msg1 = RawMessage("hello netzob !")
    >>> f0 = Field(name="F0", domain=ASCII(nbChars=(4,5)))
    >>> f1 = Field(name="F1", domain=ASCII(" "))
    >>> f2 = Field(name="F2", domain=Alt([ASCII("world"), ASCII("netzob")]))
    >>> f3 = Field(name="F3", domain=Agg([ASCII(" "), ASCII("!")]))
    >>> s = Symbol(name="S0", fields=[f0, f1, f2, f3])
    >>> mp = MessageParser()
    >>> print(mp.parseMessage(msg, s))
    [bitarray('0110100001100101011011000110110001101111'), bitarray('00100000'), bitarray('0111011101101111011100100110110001100100'), bitarray('0010000000100001')]
    >>> print(mp.parseMessage(msg1, s))
    [bitarray('0110100001100101011011000110110001101111'), bitarray('00100000'), bitarray('011011100110010101110100011110100110111101100010'), bitarray('0010000000100001')]


    >>> from netzob.all import *
    >>> from bitarray import bitarray
    >>> data = bitarray("0000110001101110011001010111010001111010011011110110001000000000")
    >>> msg = RawMessage(TypeConverter.convert(data, BitArray, Raw))
    >>> f1 = Field(name="F1", domain=BitArray(nbBits=8))
    >>> f2 = Field(name="F2", domain=ASCII(nbChars=(3,9)))
    >>> f3 = Field(name="F3", domain=BitArray(nbBits=3))
    >>> f4 = Field(name="F4", domain=BitArray(nbBits=5))
    >>> s = Symbol(name="S0", fields=[f1, f2, f3, f4])
    >>> mp = MessageParser()
    >>> print(mp.parseMessage(msg, s))
    [bitarray('00001100'), bitarray('011011100110010101110100011110100110111101100010'), bitarray('000'), bitarray('00000')]

    >>> from netzob.all import *
    >>> from bitarray import bitarray
    >>> b = bitarray('01101110011001010111010001111010011011110110001000111011000001100110100001100101011011000110110001101111')
    >>> r = TypeConverter.convert(b, BitArray, Raw)
    >>> msg = RawMessage(r)
    >>> f1 = Field(ASCII(nbChars=(6)), name="F1")
    >>> f2 = Field(";", name="F2")
    >>> f3 = Field(Size(f1), name="F3")
    >>> f4 = Field(ASCII("hello"), name="F4")
    >>> s = Symbol(fields=[f1, f2, f3, f4])
    >>> mp = MessageParser()
    >>> print(mp.parseMessage(msg, s))
    [bitarray('011011100110010101110100011110100110111101100010'), bitarray('00111011'), bitarray('00000110'), bitarray('0110100001100101011011000110110001101111')]

    >>> from netzob.all import *
    >>> from bitarray import bitarray
    >>> b = bitarray('0000011001101110011001010111010001111010011011110110001000111011')
    >>> r = TypeConverter.convert(b, BitArray, Raw)
    >>> msg = RawMessage(r)
    >>> f2 = Field(ASCII(nbChars=(1,20)), name="F2")
    >>> f3 = Field(";", name="F3")
    >>> f1 = Field(Size(f2), name="F1")
    >>> s = Symbol(fields=[f1, f2, f3])
    >>> mp = MessageParser()
    >>> print(mp.parseMessage(msg, s))
    [bitarray('00000110'), bitarray('011011100110010101110100011110100110111101100010'), bitarray('00111011')]

    # Let's verify the abstraction of intra-relationships

    >>> from netzob.all import *
    >>> b = "netzob > my name is netzob"
    >>> r = TypeConverter.convert(b, ASCII, Raw)
    >>> msg = RawMessage(r)
    >>> f1 = Field(ASCII(nbChars=(1,20)), name="F1")
    >>> f2 = Field(" > my name is ", name="F2")
    >>> f3 = Field(Value(f1), name="F3")
    >>> s = Symbol(fields=[f1, f2, f3])
    >>> mp = MessageParser()
    >>> print(mp.parseMessage(msg, s))
    [bitarray('011011100110010101110100011110100110111101100010'), bitarray('0010000000111110001000000110110101111001001000000110111001100001011011010110010100100000011010010111001100100000'), bitarray('011011100110010101110100011110100110111101100010')]

    # Let's test inter-symbol relationships

    >>> msg1 = RawMessage("my pseudo is: netzob!")
    >>> msg2 = RawMessage("welcome netzob")
    >>> msg3 = RawMessage("netzob > hello")

    >>> f11 = Field(domain=ASCII("my pseudo is: "), name="F11")
    >>> f12 = Field(domain=ASCII(nbChars=(3, 10)), name="F12")
    >>> f13 = Field(domain=ASCII("!"), name="F13")
    >>> s1 = Symbol(fields=[f11, f12, f13], name="PSEUDO")

    >>> f21 = Field(domain=ASCII("welcome "), name="F21")
    >>> f22 = Field(domain=Value(f12), name="F22")
    >>> s2 = Symbol(fields=[f21, f22], name="WELCOME")

    >>> f31 = Field(domain=Value(f12), name="F31")
    >>> f32 = Field(domain=ASCII(" > hello"), name="F32")
    >>> s3 = Symbol(fields=[f31, f32], name="HELLO")

    >>> mp = MessageParser()
    >>> print(mp.parseMessage(msg1, s1))
    [bitarray('0110110101111001001000000111000001110011011001010111010101100100011011110010000001101001011100110011101000100000'), bitarray('011011100110010101110100011110100110111101100010'), bitarray('00100001')]
    >>> print(mp.parseMessage(msg2, s2))
    [bitarray('0111011101100101011011000110001101101111011011010110010100100000'), bitarray('011011100110010101110100011110100110111101100010')]
    >>> print(mp.parseMessage(msg3, s3))
    [bitarray('011011100110010101110100011110100110111101100010'), bitarray('0010000000111110001000000110100001100101011011000110110001101111')]

    """
    def __init__(self, memory=None):
        if memory is None:
            self.memory = Memory()
        else:
            self.memory = memory

    @typeCheck(AbstractMessage, Symbol)
    def parseMessage(self, message, symbol):
        """This method parses the specified message against the specification of the provided symbol.
        It either succeed and returns the alignment of the message or fails and raises an Exception"""
        if symbol is None:
            raise Exception("Specified symbol is None")
        if message is None:
            raise Exception("Specified message is None")

        # self._logger.debug("Parse message '{0}' according to symbol {1}".format(message.id, symbol.name))
        # we only consider the message data
        dataToParse = message.data

        fields = symbol.getLeafFields()
        return next(self.parseRaw(dataToParse, fields))

    @typeCheck(object)
    def parseRaw(self, dataToParse, fields):
        """This method parses the specified raw against the specification of the provided symbol."""
        if dataToParse is None or len(dataToParse) <= 0:
            raise Exception("Specified data to parse is empty (or None)")
        if fields is None:
            raise Exception("Specified fields is None")
        if len(fields) == 0:
            raise Exception("No field specified")

        bitArrayToParse = TypeConverter.convert(dataToParse, Raw, BitArray)

        return self.parseBitarray(bitArrayToParse, fields)

    def parseBitarray(self,
                      bitArrayToParse,
                      fields,
                      must_consume_everything=True):
        """This method parses the specified bitarray according to the specification of
        the specified fields.

        It returns an iterator over all the valid parsing path that can be found.
        
        """

        self._logger.debug(
            "New parsing method executed on {}".format(bitArrayToParse))

        # building a new parsing path
        currentParsingPath = ParsingPath(bitArrayToParse.copy(),
                                         self.memory.duplicate())
        currentParsingPath.assignDataToField(bitArrayToParse.copy(), fields[0])

        # field iterator
        i_current_field = 0

        parsingResults = self._parseBitArrayWithField(
            currentParsingPath,
            fields,
            i_current_field,
            must_consume_everything=must_consume_everything)

        for parsingResult in parsingResults:
            result = []
            for field in fields:
                result.append(parsingResult.getDataAssignedToField(field))

            self.memory = parsingResult.memory

            yield result

        raise InvalidParsingPathException(
            "No parsing path returned while parsing '{}'".format(
                TypeConverter.convert(bitArrayToParse, BitArray, Raw)))

    def _parseBitArrayWithField(self,
                                parsingPath,
                                fields,
                                i_current_field,
                                must_consume_everything=True):
        self._logger.debug(
            "_parseBitArrayWithField executed for field {} with path : {}".
            format(i_current_field, parsingPath))
        currentField = fields[i_current_field]

        carnivorous_parsing = (i_current_field == len(fields) - 1)
        if must_consume_everything is False:
            carnivorous_parsing = False

        fp = FieldParser(currentField, carnivorous_parsing)
        value_before_parsing = parsingPath.getDataAssignedToField(
            currentField).copy()

        for newParsingPath in fp.parse(parsingPath):

            try:
                value_after_parsing = newParsingPath.getDataAssignedToField(
                    currentField)
                remainingValue = value_before_parsing[len(value_after_parsing
                                                          ):].copy()

                if i_current_field < len(fields) - 1:
                    newParsingPath.assignDataToField(
                        remainingValue, fields[i_current_field + 1])

                    if must_consume_everything is False:
                        generator = self._parseBitArrayWithField(
                            newParsingPath,
                            fields,
                            i_current_field + 1,
                            must_consume_everything=False)
                    else:
                        generator = self._parseBitArrayWithField(
                            newParsingPath, fields, i_current_field + 1)
                    try:
                        for x in generator:
                            yield x
                    except RuntimeError as e:
                        print(
                            "Parsing path error. Current Field num :",
                            i_current_field,
                            "Field value:",
                            value_after_parsing.tobytes().hex(),
                            "Remaining value:",
                            remainingValue.tobytes().hex(),
                        )
                        raise e

                elif not must_consume_everything and len(remainingValue) >= 0:
                    yield newParsingPath
                elif len(remainingValue) == 0:
                    # valid parsing path must consume everything
                    yield newParsingPath

            except InvalidParsingPathException:
                pass

        return
Exemple #8
0
 def __init__(self, memory=None):
     if memory is None:
         self.memory = Memory()
     else:
         self.memory = memory
Exemple #9
0
 def __init__(self, memory=None, presets=None):
     if memory is None:
         memory = Memory()
     self.memory = memory
     self.presets = presets
Exemple #10
0
 def reset(self):
     self._logger.debug("Reseting abstraction layer")
     self.memory = Memory()
     self.specializer = MessageSpecializer(memory=self.memory)
     self.parser = MessageParser(memory=self.memory)
     self.flow_parser = FlowParser(memory=self.memory)