コード例 #1
0
ファイル: oracle.py プロジェクト: webshell520/FuzzBunch
 def audit_bypass_menu(self, disable_auditing=True):
     menu = ops.menu.Menu()
     if disable_auditing:
         print ''
         dsz.ui.Echo(
             "If you'd like to disable auditing or enable PASSFREELY select one of the options below. Otherwise continue by pressing 0:",
             True)
         menu.add_option("Run 'audit -disable all'",
                         callback=audit_disable_with_verify)
         menu.add_option(
             'Run PASSFREELY (oracle -memcheck && oracle -open)',
             callback=self.check_and_run_passfreely,
             disable_auditing=True)
     else:
         print ''
         dsz.ui.Echo(
             "If you'd like to reenable auditing or remove PASSFREELY select one of the options below. Otherwise continue by pressing 0:",
             True)
         menu.add_option('Re-enable auditing (prettych && stop <id>)',
                         callback=reenable_auditing)
         menu.add_option(
             'Run PASSFREELY (oracle -close && oracle -memcheck)',
             callback=self.check_and_run_passfreely,
             disable_auditing=False)
     menu.execute(exit='Continue On...', menuloop=False)
     if ((not disable_auditing) and self.passfreely_is_on):
         print ''
         dsz.ui.Echo(
             "PASSFREELY is still running in memory! You'd better know what you're doing!",
             dsz.WARNING)
         print ''
         dsz.ui.Pause(
             "If you hit 'Continue On' in error, go run oracle -close and oracle -memcheck in another terminal.",
             dsz.WARNING)
コード例 #2
0
def query_menu(db_module, handle_id):
    menu = ops.menu.Menu()
    menu.set_heading('Database Query Menu')
    menu.add_toggle_option(SETTING_CSV,
                           section='Settings',
                           state='False',
                           enabled='True',
                           disabled='False')
    menu.add_int_option(SETTING_MAX_SIZE,
                        section='Settings',
                        state=64000,
                        default=64000)
    menu.add_option('Run a standard query plan',
                    section='Query Commands',
                    callback=read_args_callback,
                    db_module=db_module,
                    menu=menu,
                    function=db_module.canned_plan_menu,
                    handle_id=handle_id)
    menu.add_option('Read the top 10 rows from every table',
                    section='Query Commands',
                    callback=read_args_callback,
                    db_module=db_module,
                    menu=menu,
                    function=db_module.top_ten_query,
                    handle_id=handle_id)
    menu.add_option('Run a folder of queries',
                    section='Query Commands',
                    callback=read_args_callback,
                    db_module=db_module,
                    menu=menu,
                    function=db_module.prompt_for_query_folder,
                    handle_id=handle_id)
    menu.execute(exit='Disconnect')
    return True
コード例 #3
0
ファイル: database.py プロジェクト: M31MOTH/fuzzbunch
def query_menu(db_module, handle_id):
    menu = ops.menu.Menu()
    menu.set_heading('Database Query Menu')
    menu.add_toggle_option(SETTING_CSV, section='Settings', state='False', enabled='True', disabled='False')
    menu.add_int_option(SETTING_MAX_SIZE, section='Settings', state=64000, default=64000)
    menu.add_option('Run a standard query plan', section='Query Commands', callback=read_args_callback, db_module=db_module, menu=menu, function=db_module.canned_plan_menu, handle_id=handle_id)
    menu.add_option('Read the top 10 rows from every table', section='Query Commands', callback=read_args_callback, db_module=db_module, menu=menu, function=db_module.top_ten_query, handle_id=handle_id)
    menu.add_option('Run a folder of queries', section='Query Commands', callback=read_args_callback, db_module=db_module, menu=menu, function=db_module.prompt_for_query_folder, handle_id=handle_id)
    menu.execute(exit='Disconnect')
    return True
コード例 #4
0
ファイル: sql_server.py プロジェクト: M31MOTH/fuzzbunch
 def canned_plan_menu(self, handle_id):
     menu = ops.menu.Menu()
     menu.set_heading('SQL Server Canned Query Plans')
     plan_path = os.path.join(os.path.dirname(__file__), '..', '..', 'Data', 'database_plans', 'SQL Server')
     plan_path = os.path.normpath(plan_path)
     for folder in os.listdir(plan_path):
         query_folder = os.path.join(plan_path, folder)
         if (not os.path.isdir(query_folder)):
             continue
         menu.add_option(folder, callback=sql_utils.run_folder_of_queries, handle_id=handle_id, query_folder=query_folder, csv_output=self.csv_output, max_col_size=self.max_col_size)
     menu.add_option('Sharepoint', callback=self.sharepoint_queries, handle_id=handle_id)
     menu.execute(exit='Back')
コード例 #5
0
 def canned_plan_menu(self, handle_id):
     menu = ops.menu.Menu()
     menu.set_heading(('%s Canned Query Plans' % self.NAME))
     plan_path = os.path.join(os.path.dirname(__file__), '..', '..', 'Data', 'database_plans', self.NAME)
     plan_path = os.path.normpath(plan_path)
     if (not os.path.isdir(plan_path)):
         print ''
         dsz.ui.Echo(('No directory of database plans found at: %s' % plan_path), dsz.ERROR)
         return
     for folder in os.listdir(plan_path):
         query_folder = os.path.join(plan_path, folder)
         if (not os.path.isdir(query_folder)):
             continue
         menu.add_option(folder, callback=sql_utils.run_folder_of_queries, handle_id=handle_id, query_folder=query_folder, csv_output=self.csv_output, max_col_size=self.max_col_size)
     menu.execute(exit='Back')
コード例 #6
0
ファイル: __init__.py プロジェクト: webshell520/FuzzBunch
 def __menu(self):
     menu = ops.menu.Menu()
     menu.set_heading('Select Tasking')
     tasks = {}
     menu.add_option('Use this configuration')
     for e in self.element:
         display = e.get('name')
         if (display is None):
             display = e.get('marker')
         if (display is None):
             display = ('"%s": {"attribs": %s, "text": %s}' % (e.tag, e.attrib, repr(e.text)))
         menudisplay = display
         count = 0
         while (menudisplay in tasks):
             count += 1
             menudisplay = (display + (' #%d' % count))
         tasks[menudisplay] = e
         menu.add_toggle_option(menudisplay, section='Tasks', state='Enabled')
     result = menu.execute(exiton=[1], exit='Exit and SKIP ALL tasks')
     if (result['selection'] == 0):
         return False
     for i in result['all_states']['Tasks']:
         if (result['all_states']['Tasks'][i] == '<DISABLED>'):
             self.element.remove(tasks[i])
     return True
コード例 #7
0
ファイル: sql_server.py プロジェクト: M31MOTH/fuzzbunch
 def connection_string_wizard(self):
     print ''
     if (not self.working_instance):
         self.store_sql_server_settings()
     if (not self.available_databases):
         self.available_databases = get_database_file_list()
         if (not self.available_databases):
             print ''
             dsz.ui.Echo("Didn't get list of databases from file system.\n", dsz.WARNING)
     menu = ops.menu.Menu()
     heading = 'Change the options below to configure your connection string.\n\nDriver and Instance are required.\n\nEverything else is optional and should be changed if you have trouble connecting. \n\nInstance should be prepended with .\\ unless using the named pipe. Sharepoint servers almost always use .\\localhost as the Instance value.'
     menu.set_heading(heading)
     menu.add_str_option(INSTANCE, state=('.\\%s' % self.working_instance))
     menu.add_option(DRIVER, state=UNSET, callback=sql_utils.select_driver_menu, menu=menu)
     menu.add_str_option(TRUSTED_CONNECTION, state='Yes', default='Yes')
     menu.add_option(DATABASE, '', callback=select_database_menu, available_databases=self.available_databases, menu=menu)
     menu.add_str_option(DB_FILE, '')
     while True:
         result = menu.execute(exit='Connect...')
         state = result['all_states']['']
         if (not any([value for value in state.values() if (value == UNSET)])):
             break
         else:
             print ''
             dsz.ui.Echo('You must set all required values!', dsz.ERROR)
     con_string = ('Driver={%s};Server={%s}' % (state[DRIVER], state[INSTANCE]))
     if state.has_key(DATABASE):
         con_string += (';Database={%s}' % state[DATABASE])
     if state.has_key(DB_FILE):
         con_string += (';AttachDbFilename={%s}' % state[DB_FILE])
     if (state.has_key(TRUSTED_CONNECTION) and (state[TRUSTED_CONNECTION].lower() == 'yes')):
         con_string += (';Trusted_Connection={%s}' % state[TRUSTED_CONNECTION])
     return con_string
コード例 #8
0
ファイル: oracle.py プロジェクト: webshell520/FuzzBunch
 def connection_string_wizard(self):
     print ''
     menu = ops.menu.Menu()
     heading = 'Change the options below to configure your connection string.\n\nDriver, Username and Password are required.\n\nEverything else is optional and should be changed if you have trouble connecting.'
     menu.set_heading(heading)
     menu.add_option(DRIVER,
                     state=sql_utils.UNSET,
                     callback=sql_utils.select_driver_menu,
                     menu=menu)
     menu.add_str_option(USERNAME, sql_utils.UNSET, default='sys')
     menu.add_str_option(PASSWORD, sql_utils.UNSET, default='sys as sysdba')
     menu.add_str_option(SID, '')
     menu.add_ip_option(HOST, '')
     menu.add_int_option(PORT, 0, default=1521)
     while True:
         result = menu.execute(exit='Connect...')
         state = defaultdict((lambda: ''))
         state.update(result['all_states'][''])
         if (not any([
                 value
                 for value in state.values() if (value == sql_utils.UNSET)
         ])):
             break
         else:
             print ''
             dsz.ui.Echo('You must set all required values!', dsz.ERROR)
     con_string = create_connection_string(state[DRIVER], state[USERNAME],
                                           state[PASSWORD], state[SID],
                                           state[HOST], state[PORT])
     return con_string
コード例 #9
0
ファイル: oracle.py プロジェクト: M31MOTH/fuzzbunch
 def audit_bypass_menu(self, disable_auditing=True):
     menu = ops.menu.Menu()
     if disable_auditing:
         print ''
         dsz.ui.Echo("If you'd like to disable auditing or enable PASSFREELY select one of the options below. Otherwise continue by pressing 0:", True)
         menu.add_option("Run 'audit -disable all'", callback=audit_disable_with_verify)
         menu.add_option('Run PASSFREELY (oracle -memcheck && oracle -open)', callback=self.check_and_run_passfreely, disable_auditing=True)
     else:
         print ''
         dsz.ui.Echo("If you'd like to reenable auditing or remove PASSFREELY select one of the options below. Otherwise continue by pressing 0:", True)
         menu.add_option('Re-enable auditing (prettych && stop <id>)', callback=reenable_auditing)
         menu.add_option('Run PASSFREELY (oracle -close && oracle -memcheck)', callback=self.check_and_run_passfreely, disable_auditing=False)
     menu.execute(exit='Continue On...', menuloop=False)
     if ((not disable_auditing) and self.passfreely_is_on):
         print ''
         dsz.ui.Echo("PASSFREELY is still running in memory! You'd better know what you're doing!", dsz.WARNING)
         print ''
         dsz.ui.Pause("If you hit 'Continue On' in error, go run oracle -close and oracle -memcheck in another terminal.", dsz.WARNING)
コード例 #10
0
ファイル: sql_server.py プロジェクト: webshell520/FuzzBunch
 def canned_plan_menu(self, handle_id):
     menu = ops.menu.Menu()
     menu.set_heading('SQL Server Canned Query Plans')
     plan_path = os.path.join(os.path.dirname(__file__), '..', '..', 'Data',
                              'database_plans', 'SQL Server')
     plan_path = os.path.normpath(plan_path)
     for folder in os.listdir(plan_path):
         query_folder = os.path.join(plan_path, folder)
         if (not os.path.isdir(query_folder)):
             continue
         menu.add_option(folder,
                         callback=sql_utils.run_folder_of_queries,
                         handle_id=handle_id,
                         query_folder=query_folder,
                         csv_output=self.csv_output,
                         max_col_size=self.max_col_size)
     menu.add_option('Sharepoint',
                     callback=self.sharepoint_queries,
                     handle_id=handle_id)
     menu.execute(exit='Back')
コード例 #11
0
ファイル: sql_server.py プロジェクト: webshell520/FuzzBunch
 def connection_string_wizard(self):
     print ''
     if (not self.working_instance):
         self.store_sql_server_settings()
     if (not self.available_databases):
         self.available_databases = get_database_file_list()
         if (not self.available_databases):
             print ''
             dsz.ui.Echo("Didn't get list of databases from file system.\n",
                         dsz.WARNING)
     menu = ops.menu.Menu()
     heading = 'Change the options below to configure your connection string.\n\nDriver and Instance are required.\n\nEverything else is optional and should be changed if you have trouble connecting. \n\nInstance should be prepended with .\\ unless using the named pipe. Sharepoint servers almost always use .\\localhost as the Instance value.'
     menu.set_heading(heading)
     menu.add_str_option(INSTANCE, state=('.\\%s' % self.working_instance))
     menu.add_option(DRIVER,
                     state=UNSET,
                     callback=sql_utils.select_driver_menu,
                     menu=menu)
     menu.add_str_option(TRUSTED_CONNECTION, state='Yes', default='Yes')
     menu.add_option(DATABASE,
                     '',
                     callback=select_database_menu,
                     available_databases=self.available_databases,
                     menu=menu)
     menu.add_str_option(DB_FILE, '')
     while True:
         result = menu.execute(exit='Connect...')
         state = result['all_states']['']
         if (not any(
             [value for value in state.values() if (value == UNSET)])):
             break
         else:
             print ''
             dsz.ui.Echo('You must set all required values!', dsz.ERROR)
     con_string = ('Driver={%s};Server={%s}' %
                   (state[DRIVER], state[INSTANCE]))
     if state.has_key(DATABASE):
         con_string += (';Database={%s}' % state[DATABASE])
     if state.has_key(DB_FILE):
         con_string += (';AttachDbFilename={%s}' % state[DB_FILE])
     if (state.has_key(TRUSTED_CONNECTION)
             and (state[TRUSTED_CONNECTION].lower() == 'yes')):
         con_string += (';Trusted_Connection={%s}' %
                        state[TRUSTED_CONNECTION])
     return con_string
コード例 #12
0
def main():
    modules = load_plugins(os.path.join(os.path.dirname(__file__), 'plugins'))
    module_map = dict([(module.MENU_TEXT, module.main) for module in modules])
    heading = 'Overseer Survey Options'
    menu = ops.menu.Menu()
    menu.set_heading(heading)
    for module in modules:
        menu.add_toggle_option(module.MENU_TEXT, state='Enabled')
    result_set = menu.execute(exit='Run Plugins...')['all_states']['']
    for (text, enabled) in result_set.items():
        if (not (enabled == 'Enabled')):
            continue
        try:
            print '\n'
            dsz.ui.Echo(('-' * 80), dsz.GOOD)
            module_map[text]()
        except:
            dsz.ui.Echo(('\nError running command: %s' % item[0]), dsz.ERROR)
    print '\n'
    dsz.ui.Echo(('-' * 80), dsz.GOOD)
    dsz.ui.Echo('All tasks have been queued or run.\n\nGo check your log files for the information!', dsz.GOOD)
コード例 #13
0
ファイル: oracle.py プロジェクト: M31MOTH/fuzzbunch
 def connection_string_wizard(self):
     print ''
     menu = ops.menu.Menu()
     heading = 'Change the options below to configure your connection string.\n\nDriver, Username and Password are required.\n\nEverything else is optional and should be changed if you have trouble connecting.'
     menu.set_heading(heading)
     menu.add_option(DRIVER, state=sql_utils.UNSET, callback=sql_utils.select_driver_menu, menu=menu)
     menu.add_str_option(USERNAME, sql_utils.UNSET, default='sys')
     menu.add_str_option(PASSWORD, sql_utils.UNSET, default='sys as sysdba')
     menu.add_str_option(SID, '')
     menu.add_ip_option(HOST, '')
     menu.add_int_option(PORT, 0, default=1521)
     while True:
         result = menu.execute(exit='Connect...')
         state = defaultdict((lambda : ''))
         state.update(result['all_states'][''])
         if (not any([value for value in state.values() if (value == sql_utils.UNSET)])):
             break
         else:
             print ''
             dsz.ui.Echo('You must set all required values!', dsz.ERROR)
     con_string = create_connection_string(state[DRIVER], state[USERNAME], state[PASSWORD], state[SID], state[HOST], state[PORT])
     return con_string
コード例 #14
0
def getTarget(cpaddr=None, forcenew=False, forceproj=None):
    if (cpaddr is None):
        cpaddr = dsz.script.Env['target_address']
    targ_id = (ops.env.get('OPS_TARGET_ID', addr=cpaddr) if
               (not forcenew) else None)
    if (targ_id is not None):
        proj = Project(ops.env.get('OPS_PROJECTNAME', addr=cpaddr))
        with proj.pdb as pdb:
            curs = pdb.execute('SELECT * FROM targets WHERE target_id = ?',
                               (targ_id, ))
            targrow = curs.fetchone()
            if (targrow is not None):
                return Target(proj, dbrow=targrow)
            else:
                raise Exception(
                    'Have a target ID, but data not in database, something is wrong'
                )
    else:
        ifconfig_cmd = ops.cmd.getDszCommand('ifconfig')
        ifconfig_cmd.dszdst = cpaddr
        ifconfig_result = ifconfig_cmd.execute()
        hostname = ifconfig_result.fixeddataitem.hostname
        macs = []
        for iface in ifconfig_result.interfaceitem:
            if ((iface.address != '') and (iface.type.upper() != 'LOCAL')
                    and (not iface.type.upper().startswith('TUNNEL'))):
                macs.append(iface.address.lower())
        crypto_guid_cmd = ops.cmd.getDszCommand(
            'registryquery',
            hive='L',
            key='software\\microsoft\\cryptography',
            value='MachineGuid',
            wow64=(ops.env.get('_OS_64BIT').upper() == 'TRUE'))
        crypto_guid_cmd.dszdst = cpaddr
        crypto_guid_result = crypto_guid_cmd.execute()
        if (crypto_guid_cmd.success and (len(crypto_guid_result.key) > 0)
                and (len(crypto_guid_result.key[0].value) > 0)):
            crypto_guid = crypto_guid_result.key[0].value[0].value
        else:
            crypto_guid = None
        implant_id = ops.env.get('_PC_ID', addr=cpaddr)
        mycandidates = (matchTarget(implant_id=implant_id,
                                    crypto_guid=crypto_guid,
                                    hostname=hostname,
                                    macs=macs) if (not forcenew) else None)
        mytarg = None
        if (len(mycandidates) == 0):
            mytarg = None
        elif (len(
                filter((lambda x:
                        (x['confidence'] >= CONFIDENCE_MATCH_THRESHOLD)),
                       mycandidates)) == 1):
            mytarg = mycandidates[0]['target']
        else:
            print(
                'Showing you what we know so you can make a good decision in the menu below'
            )
            try:
                print((u'crypto_guid: %s' % crypto_guid))
                print((u'hostname: %s' % hostname))
                print((u'macs: %s' % macs))
                print((u'implant_id: %s' % implant_id))
            except:
                print(
                    'Well, I wanted to show you, but some kind of funky encoding issue has destroyed me'
                )
            menu = ops.menu.Menu()
            menu.set_heading(
                'Below match threshold or multiple matches. You must choose. Choose wisely.'
            )
            for cand in mycandidates:
                menu.add_option(
                    ('(Confidence: %s) %s / %s / PC ID %s / %s / MACS: %s' %
                     (cand['confidence'], cand['target'].project.name,
                      cand['target'].hostname, cand['target'].implant_id,
                      cand['target'].crypto_guid, cand['target'].macs)))
            result = menu.execute(
                menuloop=False, exit='None of these - create a new target db')
            if (result['selection'] == 0):
                mytarg = None
            else:
                mytarg = mycandidates[(result['selection'] - 1)]['target']
        if (mytarg is None):
            if (forceproj is not None):
                projname = forceproj
            else:
                projnames = getAllProjectNames()
                if (len(projnames) == 1):
                    projname = projnames[0]
                else:
                    ops.warn(
                        'This looks like a new target, and I have no idea where to put it.'
                    )
                    menu = ops.menu.Menu()
                    for i in projnames:
                        menu.add_option(i)
                    result = menu.execute(menuloop=False,
                                          exit='Input project name manually')
                    if (result['selection'] == 0):
                        sure = False
                        while (not sure):
                            projname = dsz.ui.GetString('Enter project name: ')
                            print(('You entered: %s' % projname))
                            sure = dsz.ui.Prompt(
                                'Are you absolutely sure this is correct?')
                    else:
                        projname = projnames[(result['selection'] - 1)]
            projectpath = os.path.join(ops.BASELOGDIR, projname, 'targetdbs')
            if (not os.path.exists(projectpath)):
                os.makedirs(projectpath)
            proj = Project(projname.lower())
            mytarg = proj.add_target(implant_id=implant_id,
                                     crypto_guid=crypto_guid,
                                     hostname=hostname,
                                     macs=macs)
        ops.env.set('OPS_TARGET_ID', mytarg.target_id, addr=cpaddr)
        if (mytarg.project != Project()):
            ops.env.set('OPS_PROJECTNAME', mytarg.project.name, addr=cpaddr)
        mytarg.implant_id = implant_id
        mytarg.crypto_guid = crypto_guid
        mytarg.hostname = hostname
        mytarg.macs = macs
        mytarg.save(mytarg.project.pdb)
        tdb = ops.db.get_tdb(mytarg.target_id)
        tdb.save_ops_object(ifconfig_result, tag=IFCONFIG_TAG)
        tdb.truncate_cache_size_bytag(tag=IFCONFIG_TAG, maxsize=MAX_CACHE_SIZE)
        return mytarg
コード例 #15
0
ファイル: copypc.py プロジェクト: 1nd0/Shadowbrokers_Embedded
                   isrunning=True, goodwords=['pc2.2_upgrade']))
 cpaddrs = []
 for i in installers:
     cpaddrs.append(
         dsz.cmd.data.Get('commandmetadata::destination', dsz.TYPE_STRING,
                          i)[0])
 if (len(cpaddrs) != 1):
     ops.warn(
         'Could not determine target CP address for OS information because there are multiple installers running.'
     )
     ops.warn('Please select a target:')
     menu = ops.menu.Menu()
     menu.add_option('Manual CP entry')
     for i in cpaddrs:
         menu.add_option(i, section='pc_install/upgrade detected')
     result = menu.execute(menuloop=False)
     if (result['selection'] == 1):
         cpaddr = dsz.ui.GetString('Enter CP address')
     elif (result['selection'] == 0):
         print('Aborted.')
         sys.exit((-1))
     else:
         cpaddr = result['option']
 elif (len(cpaddrs) < 1):
     pass
 else:
     cpaddr = cpaddrs[0]
 if (options.project is None):
     options.project = ops.env.get('OPS_PROJECTNAME', addr=cpaddr)
     if (options.project is None):
         options.project = ops.PROJECT
コード例 #16
0
ファイル: copypc.py プロジェクト: M31MOTH/fuzzbunch
     elif (oldid != options.userID):
         ops.info('Updated cached user ID in LP environment OPS_USERID.')
 if options.oldPayDir:
     options.payDir = options.oldPayDir
 installers = (((ops.cmd.get_filtered_command_list(isrunning=True, goodwords=['pc_install']) + ops.cmd.get_filtered_command_list(isrunning=True, goodwords=['pc2.2_install'])) + ops.cmd.get_filtered_command_list(isrunning=True, goodwords=['pc_upgrade'])) + ops.cmd.get_filtered_command_list(isrunning=True, goodwords=['pc2.2_upgrade']))
 cpaddrs = []
 for i in installers:
     cpaddrs.append(dsz.cmd.data.Get('commandmetadata::destination', dsz.TYPE_STRING, i)[0])
 if (len(cpaddrs) != 1):
     ops.warn('Could not determine target CP address for OS information because there are multiple installers running.')
     ops.warn('Please select a target:')
     menu = ops.menu.Menu()
     menu.add_option('Manual CP entry')
     for i in cpaddrs:
         menu.add_option(i, section='pc_install/upgrade detected')
     result = menu.execute(menuloop=False)
     if (result['selection'] == 1):
         cpaddr = dsz.ui.GetString('Enter CP address')
     elif (result['selection'] == 0):
         print('Aborted.')
         sys.exit((-1))
     else:
         cpaddr = result['option']
 elif (len(cpaddrs) < 1):
     pass
 else:
     cpaddr = cpaddrs[0]
 if (options.project is None):
     options.project = ops.env.get('OPS_PROJECTNAME', addr=cpaddr)
     if (options.project is None):
         options.project = ops.PROJECT
コード例 #17
0
ファイル: __init__.py プロジェクト: M31MOTH/fuzzbunch
def getTarget(cpaddr=None, forcenew=False, forceproj=None):
    if (cpaddr is None):
        cpaddr = dsz.script.Env['target_address']
    targ_id = (ops.env.get('OPS_TARGET_ID', addr=cpaddr) if (not forcenew) else None)
    if (targ_id is not None):
        proj = Project(ops.env.get('OPS_PROJECTNAME', addr=cpaddr))
        with proj.pdb as pdb:
            curs = pdb.execute('SELECT * FROM targets WHERE target_id = ?', (targ_id,))
            targrow = curs.fetchone()
            if (targrow is not None):
                return Target(proj, dbrow=targrow)
            else:
                raise Exception('Have a target ID, but data not in database, something is wrong')
    else:
        ifconfig_cmd = ops.cmd.getDszCommand('ifconfig')
        ifconfig_cmd.dszdst = cpaddr
        ifconfig_result = ifconfig_cmd.execute()
        hostname = ifconfig_result.fixeddataitem.hostname
        macs = []
        for iface in ifconfig_result.interfaceitem:
            if ((iface.address != '') and (iface.type.upper() != 'LOCAL') and (not iface.type.upper().startswith('TUNNEL'))):
                macs.append(iface.address.lower())
        crypto_guid_cmd = ops.cmd.getDszCommand('registryquery', hive='L', key='software\\microsoft\\cryptography', value='MachineGuid', wow64=(ops.env.get('_OS_64BIT').upper() == 'TRUE'))
        crypto_guid_cmd.dszdst = cpaddr
        crypto_guid_result = crypto_guid_cmd.execute()
        if (crypto_guid_cmd.success and (len(crypto_guid_result.key) > 0) and (len(crypto_guid_result.key[0].value) > 0)):
            crypto_guid = crypto_guid_result.key[0].value[0].value
        else:
            crypto_guid = None
        implant_id = ops.env.get('_PC_ID', addr=cpaddr)
        mycandidates = (matchTarget(implant_id=implant_id, crypto_guid=crypto_guid, hostname=hostname, macs=macs) if (not forcenew) else None)
        mytarg = None
        if (len(mycandidates) == 0):
            mytarg = None
        elif (len(filter((lambda x: (x['confidence'] >= CONFIDENCE_MATCH_THRESHOLD)), mycandidates)) == 1):
            mytarg = mycandidates[0]['target']
        else:
            print('Showing you what we know so you can make a good decision in the menu below')
            try:
                print((u'crypto_guid: %s' % crypto_guid))
                print((u'hostname: %s' % hostname))
                print((u'macs: %s' % macs))
                print((u'implant_id: %s' % implant_id))
            except:
                print('Well, I wanted to show you, but some kind of funky encoding issue has destroyed me')
            menu = ops.menu.Menu()
            menu.set_heading('Below match threshold or multiple matches. You must choose. Choose wisely.')
            for cand in mycandidates:
                menu.add_option(('(Confidence: %s) %s / %s / PC ID %s / %s / MACS: %s' % (cand['confidence'], cand['target'].project.name, cand['target'].hostname, cand['target'].implant_id, cand['target'].crypto_guid, cand['target'].macs)))
            result = menu.execute(menuloop=False, exit='None of these - create a new target db')
            if (result['selection'] == 0):
                mytarg = None
            else:
                mytarg = mycandidates[(result['selection'] - 1)]['target']
        if (mytarg is None):
            if (forceproj is not None):
                projname = forceproj
            else:
                projnames = getAllProjectNames()
                if (len(projnames) == 1):
                    projname = projnames[0]
                else:
                    ops.warn('This looks like a new target, and I have no idea where to put it.')
                    menu = ops.menu.Menu()
                    for i in projnames:
                        menu.add_option(i)
                    result = menu.execute(menuloop=False, exit='Input project name manually')
                    if (result['selection'] == 0):
                        sure = False
                        while (not sure):
                            projname = dsz.ui.GetString('Enter project name: ')
                            print(('You entered: %s' % projname))
                            sure = dsz.ui.Prompt('Are you absolutely sure this is correct?')
                    else:
                        projname = projnames[(result['selection'] - 1)]
            projectpath = os.path.join(ops.BASELOGDIR, projname, 'targetdbs')
            if (not os.path.exists(projectpath)):
                os.makedirs(projectpath)
            proj = Project(projname.lower())
            mytarg = proj.add_target(implant_id=implant_id, crypto_guid=crypto_guid, hostname=hostname, macs=macs)
        ops.env.set('OPS_TARGET_ID', mytarg.target_id, addr=cpaddr)
        if (mytarg.project != Project()):
            ops.env.set('OPS_PROJECTNAME', mytarg.project.name, addr=cpaddr)
        mytarg.implant_id = implant_id
        mytarg.crypto_guid = crypto_guid
        mytarg.hostname = hostname
        mytarg.macs = macs
        mytarg.save(mytarg.project.pdb)
        tdb = ops.db.get_tdb(mytarg.target_id)
        tdb.save_ops_object(ifconfig_result, tag=IFCONFIG_TAG)
        tdb.truncate_cache_size_bytag(tag=IFCONFIG_TAG, maxsize=MAX_CACHE_SIZE)
        return mytarg