def main(): allchars = bytearray('datadatadata unprintable chars:') for i in range (0, 256): allchars += chr(i) print("Testing serialization and deserialization...") serialized = Message.serializeByteArray(allchars) deserialized = Message.deserializeByteArray(serialized) print("Serialized: {0}".format(serialized)) print("Before: {0}".format(str(allchars))) print(" After: {0}".format(str(deserialized))) print("Test: {0}".format("pass" if allchars == deserialized else "fail"))
def sendPacket(connection, addr, outPacketData): connection.settimeout(fuzzerData.receiveTimeout) if connection.type == socket.SOCK_STREAM: connection.send(outPacketData) else: connection.sendto(outPacketData, addr) print "\tSent %d byte packet" % (len(outPacketData)) if DEBUG_MODE: print "\tSent: %s" % (outPacketData) print "\tRaw Bytes: %s" % (Message.serializeByteArray(outPacketData))
def sendPacket(self, connection, addr, outPacketData): connection.settimeout(self.fuzzerData.receiveTimeout) if connection.type == socket.SOCK_STREAM: connection.send(outPacketData) elif connection.type == socket.SOCK_RAW: #for L2raw clumsden start connection.send( outPacketData ) # clumsden, ran into trouble with this later and needed sendto(outPacketData,addr)...what it was orginally? else: connection.sendto(outPacketData, addr) print "\tSent %d byte packet" % (len(outPacketData)) if DEBUG_MODE: print "\tSent: %s" % (outPacketData) print "\tRaw Bytes: %s" % ( Message.serializeByteArray(outPacketData))
############# Process input files if not os.path.isfile(inputFilePath): print("Cannot read input %s" % (inputFilePath)) exit() STATE_BETWEEN_MESSAGES = 0 STATE_READING_MESSAGE = 2 STATE_COMBINING_PACKETS = 3 data = [] defaultPort = None with open(inputFilePath, 'r') as inputFile: # This is a little naive, but it works # These two get recreated frequently message = Message() tempMessageData = "" # Track what we're looking for state = STATE_BETWEEN_MESSAGES # Allow combining packets in same direction back-to-back into one message askedToCombinePackets = False isCombiningPackets = False lastMessageDirection = -1 print("Processing %s..." % (inputFilePath)) try: # Process as Pcap preferentially clientPort = None serverPort = None
def readFromFD(self, fileDescriptor, quiet=False): messageNum = 0 # This is used to track multiline messages lastMessage = None # Build up comments in this string until we're ready to push them out to the dictionary # Basically, we build lines and lines of comments, then when a command is encountered, # push them into the dictionary using that command as a key # Thus, when we go to write them back out, we can print them all before a given key self._readComments = "" for line in fileDescriptor: # Record comments on read so we can play them back on write if applicable if line.startswith("#") or line == "\n": self._readComments += line # Skip all further processing for this line continue line = line.replace("\n", "") # Skip comments and whitespace if not line.startswith("#") and not line == "" and not line.isspace(): args = line.split(" ") # Populate FuzzerData obj with any settings we can parse out try: if args[0] == "processor_dir": self.processorDirectory = args[1] self._pushComments("processor_dir") elif args[0] == "failureThreshold": self.failureThreshold = int(args[1]) self._pushComments("failureThreshold") elif args[0] == "failureTimeout": self.failureTimeout = int(args[1]) self._pushComments("failureTimeout") elif args[0] == "proto": self.proto = args[1] self._pushComments("proto") elif args[0] == "port": self.port = int(args[1]) self._pushComments("port") elif args[0] == "sourcePort": self.sourcePort = int(args[1]) self._pushComments("sourcePort") elif args[0] == "sourceIP": self.sourceIP = args[1] self._pushComments("sourceIP") elif args[0] == "shouldPerformTestRun": # Use 0 or 1 for setting if args[1] == "0": self.shouldPerformTestRun = False elif args[1] == "1": self.shouldPerformTestRun = True else: raise RuntimeError("shouldPerformTestRun must be 0 or 1") self._pushComments("shouldPerformTestRun") elif args[0] == "receiveTimeout": self.receiveTimeout = float(args[1]) self._pushComments("receiveTimeout") elif args[0] == "messagesToFuzz": print("WARNING: It looks like you're using a legacy .fuzzer file with messagesToFuzz set. This is now deprecated, so please update to the new format") self.messagesToFuzz = validateNumberRange(args[1], flattenList=True) # Slight kludge: store comments above messagesToFuzz with the first message. *shrug* # Comment saving is best effort anyway, right? self._pushComments("message0") elif args[0] == "unfuzzedBytes": print("ERROR: It looks like you're using a legacy .fuzzer file with unfuzzedBytes set. This has been replaced by the new multi-line format. Please update your .fuzzer file.") sys.exit(-1) elif args[0] == "inbound" or args[0] == "outbound": message = Message() message.setFromSerialized(line) self.messageCollection.addMessage(message) # Legacy code to handle old messagesToFuzz format if messageNum in self.messagesToFuzz: message.isFuzzed = True if not quiet: print "\tMessage #{0}: {1} bytes {2}".format(messageNum, len(message.getOriginalMessage()), message.direction) self._pushComments("message{0}".format(messageNum)) messageNum += 1 lastMessage = message # "sub" means this is a subcomponent elif args[0] == "sub": if not 'message' in locals(): print "\tERROR: 'sub' line declared before any 'message' lines, throwing subcomponent out: {0}".format(line) else: message.appendFromSerialized(line) if not quiet: print "\t\tSubcomponent: {1} additional bytes".format(messageNum, len(message.subcomponents[-1].message)) elif line.lstrip()[0] == "'" and 'message' in locals(): # If the line begins with ' and a message line has been found, # assume that this is additional message data # (Different from a subcomponent because it can't have additional data # tacked on) message.appendFromSerialized(line.lstrip(), createNewSubcomponent=False) else: if not quiet: print "Unknown setting in .fuzzer file: {0}".format(args[0]) # Slap any messages between "message" and "sub", etc (ascii same way) above message # It's way too annoying to print these out properly, as they get # automagically outserialized by the Message object # Plus they may change... eh, forget it, user can fix up themselves if they want self._appendComments("message{0}".format(messageNum-1)) except Exception as e: print "Invalid line: {0}".format(line) raise e # Catch any comments below the last line self._pushComments("endcomments")
def testString(inputValue): # Test the serialization function itself try: print( "\n{}Testing direct serialization and deserialization...{}".format( Color.BOLD, Color.END)) serialized = Message.serializeByteArray(inputValue) deserialized = Message.deserializeByteArray(serialized) print("\tSerialized: {0}".format(serialized)) print("\tBefore: {0}".format(str(inputValue))) print("\t After: {0}".format(str(deserialized))) except Exception as e: print("Caught exception running test: {}".format(str(e))) deserialized = "" printResult("Direct Serialization Test", inputValue == deserialized) # Also go a step further and test the inbound/outbound etc parsing try: print( "\n{}Testing full serialization with inbound/outbound lines...{}". format(Color.BOLD, Color.END)) message = Message() message.direction = Message.Direction.Outbound message.setMessageFrom(Message.Format.Raw, bytearray(inputValue), False) serialized = message.getSerialized() message.setFromSerialized(serialized) deserialized = message.getOriginalMessage() print("\tSerialized: {0}".format(serialized)) print("\tBefore: {0}".format(str(inputValue))) print("\t After: {0}".format(str(deserialized))) except Exception as e: print("Caught exception running test: {}".format(str(e))) deserialized = "" printResult("Full Serialization Test", inputValue == deserialized)