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)
bytearray(tempMessageData), False) print("\tMessage #%d - Added %d new bytes %s" % (j, len(tempMessageData), message.direction)) continue # Either direction isn't the same or we're not combining packets message = Message() message.direction = newMessageDirection lastMessageDirection = newMessageDirection message.setMessageFrom(Message.Format.Raw, bytearray(tempMessageData), False) fuzzerData.messageCollection.addMessage(message) j += 1 print( "\tMessage #%d - Processed %d bytes %s" % (j, len(message.getOriginalMessage()), message.direction)) except AttributeError: # No payload, keep going (different from empty payload) continue except Exception as rdpcap_e: print(str(rdpcap_e)) print("Processing as c_array...") try: # Process c_arrays # This is processing the wireshark syntax looking like: # char peer0_0[] = { # 0x66, 0x64, 0x73, 0x61, 0x0a }; # char peer1_0[] = { # 0x61, 0x73, 0x64, 0x66, 0x0a }; # First is message from client to server, second is server to client # Format is peer0/1_messagenum
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")
if not askedToCombinePackets: if prompt("There are multiple packets from client to server or server to client back-to-back - combine payloads into single messages?"): isCombiningPackets = True askedToCombinePackets = True if isCombiningPackets: message.appendMessageFrom(Message.Format.Raw, bytearray(tempMessageData), False) print "\tMessage #%d - Added %d new bytes %s" % (j, len(tempMessageData), message.direction) continue # Either direction isn't the same or we're not combining packets message = Message() message.direction = newMessageDirection lastMessageDirection = newMessageDirection message.setMessageFrom(Message.Format.Raw, bytearray(tempMessageData), False) fuzzerData.messageCollection.addMessage(message) j += 1 print "\tMessage #%d - Processed %d bytes %s" % (j, len(message.getOriginalMessage()), message.direction) except AttributeError: # No payload, keep going (different from empty payload) continue except Exception as rdpcap_e: print str(rdpcap_e) print "Processing as c_array..." try: # Process c_arrays # This is processing the wireshark syntax looking like: # char peer0_0[] = { # 0x66, 0x64, 0x73, 0x61, 0x0a }; # char peer1_0[] = { # 0x61, 0x73, 0x64, 0x66, 0x0a }; # First is message from client to server, second is server to client # Format is peer0/1_messagenum