def graph_connect (dbg, buff_addr, size, realloc=False):
    global count, graph
    count += 1

    eip = dbg.context.Eip

    allocator = pgraph.node(eip)
    allocated = pgraph.node(buff_addr)

    allocator.label = "%08x" % eip
    allocated.label = "%d" % size
    allocated.size  = size

    allocator.color = 0xFFAC59

    if realloc:
        allocated.color = 0x46FF46
    else:
        allocated.color = 0x59ACFF

    graph.add_node(allocator)
    graph.add_node(allocated)

    edge = pgraph.edge(allocator.id, allocated.id)
    edge.label = "%d" % count

    graph.add_edge(edge)
Beispiel #2
0
def graph_connect(dbg, buff_addr, size, realloc=False):
    global count, graph
    count += 1

    eip = dbg.context.Eip

    allocator = pgraph.node(eip)
    allocated = pgraph.node(buff_addr)

    allocator.label = "%08x" % eip
    allocated.label = "%d" % size
    allocated.size = size

    allocator.color = 0xFFAC59

    if realloc:
        allocated.color = 0x46FF46
    else:
        allocated.color = 0x59ACFF

    graph.add_node(allocator)
    graph.add_node(allocated)

    edge = pgraph.edge(allocator.id, allocated.id)
    edge.label = "%d" % count

    graph.add_edge(edge)
Beispiel #3
0
    def __init__(
                  self,
                  test_case_dir=os.getcwd(),
                  session_filename=None,
                  skip=0,
                  sleep_time=1.0,
                  log_level=logging.INFO,
                  logfile=None,
                  logfile_level=logging.DEBUG,
                  proto="tcp",
                  bind=None,
                  restart_interval=0,
                  timeout=5.0,
                  web_port=26000,
                  crash_threshold=3,
                  restart_sleep_time=300
                ):

        '''
        Extends pgraph.graph and provides a container for architecting protocol dialogs.

        @type  test_case_dir:      String
        @kwarg test_case_dir:      (Optional, def=os.getcwd()) Path to directory where data sent to server is stored

        @type  session_filename:   String
        @kwarg session_filename:   (Optional, def=None) Filename to serialize persistant data to
        @type  skip:               Integer
        @kwarg skip:               (Optional, def=0) Number of test cases to skip
        @type  sleep_time:         Float
        @kwarg sleep_time:         (Optional, def=1.0) Time to sleep in between tests
        @type  log_level:          Integer
        @kwarg log_level:          (Optional, def=logger.INFO) Set the log level
        @type  logfile:            String
        @kwarg logfile:            (Optional, def=None) Name of log file
        @type  logfile_level:      Integer
        @kwarg logfile_level:      (Optional, def=logger.INFO) Set the log level for the logfile
        @type  proto:              String
        @kwarg proto:              (Optional, def="tcp") Communication protocol ("tcp", "udp", "ssl")
        @type  bind:               Tuple (host, port)
        @kwarg bind:               (Optional, def=random) Socket bind address and port
        @type  timeout:            Float
        @kwarg timeout:            (Optional, def=5.0) Seconds to wait for a send/recv prior to timing out
        @type  restart_interval:   Integer
        @kwarg restart_interval    (Optional, def=0) Restart the target after n test cases, disable by setting to 0
        @type  crash_threshold:    Integer
        @kwarg crash_threshold     (Optional, def=3) Maximum number of crashes allowed before a node is exhaust
        @type  restart_sleep_time: Integer
        @kwarg restart_sleep_time: Optional, def=300) Time in seconds to sleep when target can't be restarted
        @type  web_port:	   Integer
        @kwarg web_port:           (Optional, def=26000) Port for monitoring fuzzing campaign via a web browser	
	'''

        # Ensure the log path is a directory.
        if not os.path.isdir(test_case_dir):
            sys.stderr.write('"' + test_case_dir + '" is not a directory, aborting\n')
            sys.exit()


        # run the parent classes initialization routine first.
        pgraph.graph.__init__(self)

        self.test_case_dir       = test_case_dir
        self.session_filename    = session_filename
        self.skip                = skip
        self.sleep_time          = sleep_time
        self.proto               = proto.lower()
        self.bind                = bind
        self.ssl                 = False
        self.restart_interval    = restart_interval
        self.timeout             = timeout
        self.web_port            = web_port
        self.crash_threshold     = crash_threshold
        self.restart_sleep_time  = restart_sleep_time
        self.test_number         = 1
        self.test_case_file      = None

        # Initialize logger
        self.logger = logging.getLogger("Sulley_logger")
        self.logger.setLevel(log_level)
        formatter = logging.Formatter('[%(asctime)s] [%(levelname)s] -> %(message)s')

        if logfile != None:
            filehandler = logging.FileHandler(logfile)
            filehandler.setLevel(logfile_level)
            filehandler.setFormatter(formatter)
            self.logger.addHandler(filehandler)

        consolehandler = logging.StreamHandler()
        consolehandler.setFormatter(formatter)
        consolehandler.setLevel(log_level)
        self.logger.addHandler(consolehandler)

        self.total_num_mutations = 0
        self.total_mutant_index  = 0
        self.fuzz_node           = None
        self.targets             = []
        self.netmon_results      = {}
        self.procmon_results     = {}
        self.protmon_results     = {}
        self.pause_flag          = False
        self.crashing_primitives = {}

        if self.proto == "tcp":
            self.proto = socket.SOCK_STREAM

        elif self.proto == "ssl":
            self.proto = socket.SOCK_STREAM
            self.ssl   = True

        elif self.proto == "udp":
            self.proto = socket.SOCK_DGRAM

        else:
            raise sex.SullyRuntimeError("INVALID PROTOCOL SPECIFIED: %s" % self.proto)

        # import settings if they exist.
        self.import_file()

        # create a root node. we do this because we need to start fuzzing from a single point and the user may want
        # to specify a number of initial requests.
        self.root       = pgraph.node()
        self.root.name  = "__ROOT_NODE__"
        self.root.label = self.root.name
        self.last_recv  = None

        self.add_node(self.root)
Beispiel #4
0
            if test_id == crash.extra:
                print crashbin.crash_synopsis(crash)
                sys.exit(0)

#
# display an overview of all recorded crashes.
#

if graph_name:
    graph = pgraph.graph()

for bin, crashes in crashbin.bins.iteritems():
    synopsis = crashbin.crash_synopsis(crashes[0]).split("\n")[0]

    if graph:
        crash_node = pgraph.node(crashes[0].exception_address)
        crash_node.count = len(crashes)
        crash_node.label = "[%d] %s.%08x" % (
            crash_node.count, crashes[0].exception_module, crash_node.id)
        graph.add_node(crash_node)

    print "[%d] %s" % (len(crashes), synopsis)
    print "\t",

    for crash in crashes:
        if graph:
            last = crash_node.id
            for entry in crash.stack_unwind:
                address = long(entry.split(":")[1], 16)
                n = graph.find_node("id", address)
Beispiel #5
0
    def __init__(self,
                 session_filename=None,
                 skip=0,
                 sleep_time=1.0,
                 log_level=30,
                 logfile=None,
                 logfile_level=10,
                 proto="tcp",
                 bind=None,
                 restart_interval=0,
                 timeout=5.0,
                 web_port=26000,
                 crash_threshold=3,
                 restart_sleep_time=300):
        '''
        Extends pgraph.graph and provides a container for architecting protocol dialogs.

        @type  session_filename:   String
        @kwarg session_filename:   (Optional, def=None) Filename to serialize persistant data to
        @type  skip:               Integer
        @kwarg skip:               (Optional, def=0) Number of test cases to skip
        @type  sleep_time:         Float
        @kwarg sleep_time:         (Optional, def=1.0) Time to sleep in between tests
        @type  log_level:          Integer
        @kwarg log_level:          (Optional, def=30) Set the log level (CRITICAL : 50 / ERROR : 40 / WARNING : 30 / INFO : 20 / DEBUG : 10)
        @type  logfile:            String
        @kwarg logfile:            (Optional, def=None) Name of log file
        @type  logfile_level:      Integer
        @kwarg logfile_level:      (Optional, def=10) Log level for log file, default is debug
        @type  proto:              String
        @kwarg proto:              (Optional, def="tcp") Communication protocol ("tcp", "udp", "ssl")
        @type  bind:               Tuple (host, port)
        @kwarg bind:               (Optional, def=random) Socket bind address and port
        @type  timeout:            Float
        @kwarg timeout:            (Optional, def=5.0) Seconds to wait for a send/recv prior to timing out
        @type  restart_interval:   Integer
        @kwarg restart_interval    (Optional, def=0) Restart the target after n test cases, disable by setting to 0
        @type  crash_threshold:    Integer
        @kwarg crash_threshold     (Optional, def=3) Maximum number of crashes allowed before a node is exhaust
        @type  restart_sleep_time: Integer
        @kwarg restart_sleep_time: Optional, def=300) Time in seconds to sleep when target can't be restarted
        '''

        # run the parent classes initialization routine first.
        pgraph.graph.__init__(self)

        self.session_filename = session_filename
        self.skip = skip
        self.sleep_time = sleep_time
        self.proto = proto.lower()
        self.bind = bind
        self.ssl = False
        self.restart_interval = restart_interval
        self.timeout = timeout
        self.web_port = web_port
        self.crash_threshold = crash_threshold
        self.restart_sleep_time = restart_sleep_time

        # Initialize logger
        self.logger = logging.getLogger("Sulley_logger")
        self.logger.setLevel(logging.DEBUG)
        formatter = logging.Formatter(
            '[%(asctime)s] [%(levelname)s] -> %(message)s')

        if logfile != None:
            filehandler = logging.FileHandler(logfile)
            filehandler.setLevel(logfile_level)
            filehandler.setFormatter(formatter)
            self.logger.addHandler(filehandler)

        consolehandler = logging.StreamHandler()
        consolehandler.setFormatter(formatter)
        consolehandler.setLevel(log_level)
        self.logger.addHandler(consolehandler)

        self.total_num_mutations = 0
        self.total_mutant_index = 0
        self.fuzz_node = None
        self.targets = []
        self.netmon_results = {}
        self.procmon_results = {}
        self.protmon_results = {}
        self.pause_flag = False
        self.crashing_primitives = {}

        if self.proto == "tcp":
            self.proto = socket.SOCK_STREAM

        elif self.proto == "ssl":
            self.proto = socket.SOCK_STREAM
            self.ssl = True

        elif self.proto == "udp":
            self.proto = socket.SOCK_DGRAM

        else:
            raise sex.error("INVALID PROTOCOL SPECIFIED: %s" % self.proto)

        # import settings if they exist.
        self.import_file()

        # create a root node. we do this because we need to start fuzzing from a single point and the user may want
        # to specify a number of initial requests.
        self.root = pgraph.node()
        self.root.name = "__ROOT_NODE__"
        self.root.label = self.root.name
        self.last_recv = None

        self.add_node(self.root)
Beispiel #6
0
    def __init__ (self, session_filename=None, audit_folder=None,skip=0, sleep_time=.2, log_level=2, proto="tcp", restart_interval=0, timeout=5.0, web_port=26001, crash_threshold=3, trans_in_q=None):
        '''
        Extends pgraph.graph and provides a container for architecting protocol dialogs.

        @type  session_filename: String
        @kwarg session_filename: (Optional, def=None) Filename to serialize persistant data to
        @type  skip:             Integer
        @kwarg skip:             (Optional, def=0) Number of test cases to skip
        @type  sleep_time:       Float
        @kwarg sleep_time:       (Optional, def=1.0) Time to sleep in between tests
        @type  log_level:        Integer
        @kwarg log_level:        (Optional, def=2) Set the log level, higher number == more log messages
        @type  proto:            String
        @kwarg proto:            (Optional, def="tcp") Communication protocol
        @type  timeout:          Float
        @kwarg timeout:          (Optional, def=5.0) Seconds to wait for a send/recv prior to timing out
        @type  restart_interval: Integer
        @kwarg restart_interval  (Optional, def=0) Restart the target after n test cases, disable by setting to 0
        @type  crash_threshold:  Integer
        @kwarg crash_threshold   (Optional, def=3) Maximum number of crashes allowed before a node is exhaust
        '''

        # run the parent classes initialization routine first.
        pgraph.graph.__init__(self)

        self.session_filename    = session_filename
        self.audit_folder        = audit_folder
        self.skip                = skip
        self.sleep_time          = sleep_time
        self.log_level           = log_level
        self.proto               = proto
        self.restart_interval    = restart_interval
        self.timeout             = timeout
        self.web_port            = web_port
        self.crash_threshold     = crash_threshold
        self.trans_in_q          = trans_in_q

        self.total_num_mutations = 0
        self.total_mutant_index  = 0
        self.crashes_detected    = 0
        self.fuzz_node           = None
        self.targets             = []
        self.netmon_results      = {}
        self.procmon_results     = {}
        self.pause_flag          = False
        self.running_flag        = True
        self.crashing_primitives = {}

        if self.proto == "tcp":
            self.proto = socket.SOCK_STREAM
        elif self.proto == "udp":
            self.proto = socket.SOCK_DGRAM
        else:
            raise sex.error("INVALID PROTOCOL SPECIFIED: %s" % self.proto)

        # import settings if they exist.
        self.import_file()
        
        # create a root node. we do this because we need to start fuzzing from a single point and the user may want
        # to specify a number of initial requests.
        self.root       = pgraph.node()
        self.root.name  = "__ROOT_NODE__"
        self.root.label = self.root.name
        self.last_recv  = None

        self.add_node(self.root)
Beispiel #7
0
    def __init__ (self, session_filename=None, skip=0, sleep_time=1.0, log_level=30, logfile=None, logfile_level=10, proto="tcp", iface="eth0", af="ipv4", bind=None, restart_interval=0, timeout=5.0, web_port=26000, crash_threshold=3, restart_sleep_time=300, start_webserver=False):
        '''
        Extends pgraph.graph and provides a container for architecting protocol dialogs.

        @type  session_filename:   String
        @kwarg session_filename:   (Optional, def=None) Filename to serialize persistant data to
        @type  skip:               Integer
        @kwarg skip:               (Optional, def=0) Number of test cases to skip
        @type  sleep_time:         Float
        @kwarg sleep_time:         (Optional, def=1.0) Time to sleep in between tests
        @type  log_level:          Integer
        @kwarg log_level:          (Optional, def=30) Set the log level (CRITICAL : 50 / ERROR : 40 / WARNING : 30 / INFO : 20 / DEBUG : 10)
        @type  logfile:            String
        @kwarg logfile:            (Optional, def=None) Name of log file
        @type  logfile_level:      Integer
        @kwarg logfile_level:      (Optional, def=10) Log level for log file, default is debug
        @type  proto:              String
        @kwarg proto:              (Optional, def="tcp") Communication protocol ("tcp", "udp", "ssl")
        @type  iface:              String
        @kwarg iface:              (Optional, def="eth0") Network interface for level2 fuzzing
        @type  af:                 String
        @kwarg af:                 (Optional, def="ipv4") Type of IP connection (accepted : ipv4 or ipv6)
        @type  bind:               Tuple (host, port)
        @kwarg bind:               (Optional, def=random) Socket bind address and port
        @type  timeout:            Float
        @kwarg timeout:            (Optional, def=5.0) Seconds to wait for a send/recv prior to timing out
        @type  restart_interval:   Integer
        @kwarg restart_interval    (Optional, def=0) Restart the target after n test cases, disable by setting to 0
        @type  crash_threshold:    Integer
        @kwarg crash_threshold     (Optional, def=3) Maximum number of crashes allowed before a node is exhaust
        @type  restart_sleep_time: Integer
        @kwarg restart_sleep_time: Optional, def=300) Time in seconds to sleep when target can't be restarted
        @type  start_webserver:    Boolean
        @kwarg start_webserver:    (Optional, def=True) Start webserver
        '''

        # run the parent classes initialization routine first.
        pgraph.graph.__init__(self)

        self.session_filename    = session_filename
        self.skip                = skip
        self.sleep_time          = sleep_time
        self.proto               = proto.lower()
        self.bind                = bind
        self.ssl                 = False
        self.restart_interval    = restart_interval
        self.timeout             = timeout
        self.web_port            = web_port
        self.crash_threshold     = crash_threshold
        self.restart_sleep_time  = restart_sleep_time

        # Network informations
        self.layer2              = False
        self.iface               = iface
        self.afname              = af
        self.connect_befor_send  = True
        self.wait_on_recv        = True


        # Initialize logger
        self.logger = logging.getLogger("Sulley_logger")
        self.logger.setLevel(logging.DEBUG)
        formatter = logging.Formatter('[%(asctime)s] [%(levelname)s] -> %(message)s')

        if logfile != None:
            filehandler = logging.FileHandler(logfile)
            filehandler.setLevel(logfile_level)
            filehandler.setFormatter(formatter)
            self.logger.addHandler(filehandler)

        consolehandler = logging.StreamHandler()
        consolehandler.setFormatter(formatter)
        consolehandler.setLevel(log_level)
        self.logger.addHandler(consolehandler)


        self.start_webserver     = start_webserver

        self.total_num_mutations = 0
        self.total_mutant_index  = 0
        self.fuzz_node           = None
        self.targets             = []
        self.netmon_results      = {}
        self.procmon_results     = {}
        self.protmon_results     = {}
        self.pause_flag          = False
        self.crashing_primitives = {}

        if self.proto == "tcp":
            self.proto = socket.SOCK_STREAM

        elif self.proto == "ssl":
            self.proto = socket.SOCK_STREAM
            self.ssl   = True

        elif self.proto == "udp":
            self.proto = socket.SOCK_DGRAM
            self.connect_befor_send = False

        elif self.proto == "layer2":
            self.layer2 = True
            self.connect_befor_send = False

        else:
            raise sex.error("INVALID PROTOCOL SPECIFIED: %s" % self.proto)

        if self.afname == "ipv4":
            self.af = socket.AF_INET
        elif self.afname == "ipv6":
            self.af = socket.AF_INET6
        else:
            raise sex.error("INVALID ADDRESS FAMILY SPECIFIED: %s" % self.afname)

        # import settings if they exist.
        self.import_file()

        # create a root node. we do this because we need to start fuzzing from a single point and the user may want
        # to specify a number of initial requests.
        self.root       = pgraph.node()
        self.root.name  = "__ROOT_NODE__"
        self.root.label = self.root.name
        self.last_recv  = None

        self.add_node(self.root)
Beispiel #8
0
            if test_number == crash.extra:
                print crashbin.crash_synopsis(crash)
                sys.exit(0)

#
# display an overview of all recorded crashes.
#

if graph_name:
    graph = pgraph.graph()

for bin, crashes in crashbin.bins.iteritems():
    synopsis = crashbin.crash_synopsis(crashes[0]).split("\n")[0]

    if graph:
        crash_node       = pgraph.node(crashes[0].exception_address)
        crash_node.count = len(crashes)
        crash_node.label = "[%d] %s.%08x" % (crash_node.count, crashes[0].exception_module, crash_node.id)
        graph.add_node(crash_node)

    print "[%d] %s" % (len(crashes), synopsis)
    print "\t",

    for crash in crashes:
        if graph:
            last = crash_node.id
            for entry in crash.stack_unwind:
                address = long(entry.split(":")[1], 16)
                n = graph.find_node("id", address)

                if not n:
Beispiel #9
0
class session(pgraph.graph):

    # -----------------------------------------------------------------------------------
    #
    # -----------------------------------------------------------------------------------

    def __init__(self, config, root_dir, job_dir, session_id, job_data):
        pgraph.graph.__init__(self)

        syslog.openlog(logoption=syslog.LOG_PID, facility=syslog.LOG_DAEMON)

        self.job_data = job_data

        settings = self.job_data["session"]
        transport = self.job_data["target"]["transport"]
        conditions = self.job_data["target"]["conditions"]

        self.session_id = session_id
        self.directory = job_dir
        self.job_data = job_data
        self.root_dir = root_dir
        self.config = config
        self.database = db.DatabaseHandler(self.config, self.root_dir,
                                           self.session_id)
        self.target = None
        self.media = transport['media'].lower()
        self.transport_media = None
        self.proto = transport['protocol'].lower()
        self.conditions = conditions
        self.agent = None
        self.agent_settings = None

        self.session_filename = self.session_id + ".session"
        self.skip = 0
        self.sleep_time = 1.0
        self.bind = None
        self.restart_interval = 0
        self.timeout = 5.0
        self.crash_threshold = 3
        self.restart_sleep_time = 300

        self.pre_send = None
        self.post_send = None

        # State reason holds information about why the job is in a given
        # state. For example, a job can be in a paused state because the
        # user requested the pause, or, because of an error, e.g.: no
        # connection to the agent, or the target has crashed.
        # Similarly with the running state: it can be because a user
        # requested a job or because the scheduler started a job.
        # (scheduler is not yet available, but planned)

        self.state_reason = ""

        if settings.get('skip') != None:
            self.skip = settings['skip']
        if settings.get('sleep_time') != None:
            self.sleep_time = settings['sleep_time']
        if settings.get('bind') != None:
            self.bind = settings['bind']
        if settings.get('restart_interval') != None:
            self.restart_interval = settings['restart_interval']
        if settings.get('timeout') != None:
            self.timeout = settings['timeout']
        if settings.get('crash_threshold') != None:
            self.crash_threshold = settings['crash_threshold']
        if settings.get('restart_sleep_time') != None:
            self.restart_sleep_time = settings['restart_sleep_time']

        self.total_num_mutations = 0
        self.total_mutant_index = 0
        self.fuzz_node = None
        self.pause_flag = False
        self.stop_flag = False
        self.finished_flag = False
        self.crashing_primitives = {}
        self.crash_count = 0
        self.warning_count = 0
        self.previous_sent = None
        self.current_sent = None

        try:
            self.transport_media = getattr(media, self.media)(self.bind,
                                                              self.timeout)
        except Exception, e:
            raise Exception("invalid media specified")
            sys.exit(1)

        if self.proto not in self.transport_media.media_protocols():
            raise Exception("protocol not supported by media")
            sys.exit(2)

        self.transport_media.media_protocol(self.proto)
        self.proto = self.transport_media.media_protocol()

        # import settings if they exist.
        self.import_file()

        # create a root node. we do this because we need to start fuzzing from a single
        # point and the user may want to specify a number of initial requests.
        self.root = pgraph.node()
        self.root.name = "__ROOT_NODE__"
        self.root.label = self.root.name
        self.last_recv = None

        self.add_node(self.root)
Beispiel #10
0
class session(pgraph.graph):

    # -----------------------------------------------------------------------------------
    #
    # -----------------------------------------------------------------------------------

    def __init__(self, config, root, session_id, settings, transport,
                 conditions, job):
        pgraph.graph.__init__(self)

        self.session_id = session_id
        self.job_data = job
        self.root_dir = root
        self.config = config
        self.database = db.DatabaseHandler(self.config, self.root_dir)
        self.media = transport['media'].lower()
        self.transport_media = None
        self.proto = transport['protocol'].lower()
        self.conditions = conditions
        self.agent = None
        self.agent_settings = None

        self.skip = 0
        self.sleep_time = 1.0
        self.bind = None
        self.restart_interval = 0
        self.timeout = 5.0

        self.pre_send = None
        self.post_send = None

        if settings.get('skip') != None:
            self.skip = settings['skip']
        if settings.get('sleep_time') != None:
            self.sleep_time = settings['sleep_time']
        if settings.get('bind') != None:
            self.bind = settings['bind']
        if settings.get('restart_interval') != None:
            self.restart_interval = settings['restart_interval']
        if settings.get('timeout') != None:
            self.timeout = settings['timeout']

        self.total_num_mutations = 0
        self.total_mutant_index = 0
        self.fuzz_node = None
        self.pause_flag = False
        self.stop_flag = False
        self.finished_flag = False
        self.crashing_primitives = {}
        self.crash_count = 0
        self.warning_count = 0
        self.previous_sent = None
        self.current_sent = None

        try:
            self.transport_media = getattr(media, self.media)(self.bind,
                                                              self.timeout)
        except Exception, e:
            self.database.log("error",
                              "invalid media specified for job: %s" %\
                              self.session_id)
            sys.exit(1)

        if self.proto not in self.transport_media.media_protocols():
            self.database.log("error",
                              "protocol not supported by media for job: %s" %\
                              self.session_id)
            sys.exit(2)

        self.transport_media.media_protocol(self.proto)
        self.proto = self.transport_media.media_protocol()

        # import settings if they exist.
        self.load_session()

        # create a root node. we do this because we need to start fuzzing from a single
        # point and the user may want to specify a number of initial requests.
        self.root = pgraph.node()
        self.root.name = "__ROOT_NODE__"
        self.root.label = self.root.name
        self.last_recv = None

        self.add_node(self.root)
    def __init__(self,
                 session_filename=None,
                 audit_folder=None,
                 skip=0,
                 sleep_time=.2,
                 log_level=2,
                 proto="tcp",
                 restart_interval=0,
                 timeout=5.0,
                 web_port=26001,
                 crash_threshold=3,
                 trans_in_q=None):
        '''
        Extends pgraph.graph and provides a container for architecting protocol dialogs.

        @type  session_filename: String
        @kwarg session_filename: (Optional, def=None) Filename to serialize persistant data to
        @type  skip:             Integer
        @kwarg skip:             (Optional, def=0) Number of test cases to skip
        @type  sleep_time:       Float
        @kwarg sleep_time:       (Optional, def=1.0) Time to sleep in between tests
        @type  log_level:        Integer
        @kwarg log_level:        (Optional, def=2) Set the log level, higher number == more log messages
        @type  proto:            String
        @kwarg proto:            (Optional, def="tcp") Communication protocol
        @type  timeout:          Float
        @kwarg timeout:          (Optional, def=5.0) Seconds to wait for a send/recv prior to timing out
        @type  restart_interval: Integer
        @kwarg restart_interval  (Optional, def=0) Restart the target after n test cases, disable by setting to 0
        @type  crash_threshold:  Integer
        @kwarg crash_threshold   (Optional, def=3) Maximum number of crashes allowed before a node is exhaust
        '''

        # run the parent classes initialization routine first.
        pgraph.graph.__init__(self)

        self.session_filename = session_filename
        self.audit_folder = audit_folder
        self.skip = skip
        self.sleep_time = sleep_time
        self.log_level = log_level
        self.proto = proto
        self.restart_interval = restart_interval
        self.timeout = timeout
        self.web_port = web_port
        self.crash_threshold = crash_threshold
        self.trans_in_q = trans_in_q

        self.total_num_mutations = 0
        self.total_mutant_index = 0
        self.crashes_detected = 0
        self.fuzz_node = None
        self.targets = []
        self.netmon_results = {}
        self.procmon_results = {}
        self.pause_flag = False
        self.running_flag = True
        self.crashing_primitives = {}

        if self.proto == "tcp":
            self.proto = socket.SOCK_STREAM
        elif self.proto == "udp":
            self.proto = socket.SOCK_DGRAM
        else:
            raise sex.error("INVALID PROTOCOL SPECIFIED: %s" % self.proto)

        # import settings if they exist.
        self.import_file()

        # create a root node. we do this because we need to start fuzzing from a single point and the user may want
        # to specify a number of initial requests.
        self.root = pgraph.node()
        self.root.name = "__ROOT_NODE__"
        self.root.label = self.root.name
        self.last_recv = None

        self.add_node(self.root)