def parse_ScriptingAdditions(headers, output): ScriptingAdditions = multiglob(inputdir, [ 'System/Library/ScriptingAdditions/*.osax', 'Library/ScriptingAdditions/*.osax', 'System/Library/ScriptingAdditions/.*.osax', 'Library/ScriptingAdditions/.*.osax' ]) for i in ScriptingAdditions: record = OrderedDict((h, '') for h in headers) metadata = stats2(i, oMACB=True) record.update(metadata) record['src_file'] = i record['src_name'] = "scripting_additions" record['code_signatures'] = str(get_codesignatures(i, ncs)) output.write_entry(record.values())
def parse_loginitems(headers, output): user_loginitems_plist = multiglob( inputdir, ['Users/*/Library/Preferences/com.apple.loginitems.plist']) for i in user_loginitems_plist: record = OrderedDict((h, '') for h in headers) metadata = stats2(i, oMACB=True) record.update(metadata) record['src_file'] = i record['src_name'] = "login_items" try: p = plistlib.readPlist(i) except: try: p = read_bplist(i) except: log.debug('Could not read plist {0}: {1}'.format( i, [traceback.format_exc()])) p = 'ERROR' if p != 'ERROR': items = p[0]['SessionItems']['CustomListItems'] for i in items: record['prog_name'] = i['Name'] if 'Alias' in i: try: alias_bin = i['Alias'] except: alias_bin = 'ERROR' if alias_bin != 'ERROR': c = [i.encode('hex') for i in alias_bin] for i in range(len(c)): l = int(c[i], 16) if l < len(c) and l > 2: test = os.path.join(inputdir, (''.join( c[i + 1:i + l + 1])).decode('hex')) try: if not os.path.exists(test): continue else: record['program'] = test cs_check_path = os.path.join( inputdir, test.lstrip('/')) record['code_signatures'] = str( get_codesignatures( cs_check_path, ncs)) except: continue record['program'] = 'ERROR' record['code_signatures'] = 'ERROR' elif 'Bookmark' in i: try: bookmark_bin = i['Bookmark'] except: bookmark_bin = 'ERROR' if bookmark_bin != 'ERROR': program = [i.encode('hex') for i in bookmark_bin] data = Bookmark.from_bytes( ''.join(program).decode('hex')) d = data.get(0xf081, default=None) d = ast.literal_eval(str(d).replace('Data', '')) if d is not None: prog = d.split(';')[-1].replace('\x00', '') record['program'] = prog cs_check_path = os.path.join( inputdir, prog.lstrip('/')) record['code_signatures'] = str( get_codesignatures(cs_check_path, ncs)) output.write_entry(record.values()) else: errors = { k: 'ERROR-CNR-PLIST' for k, v in record.items() if v == '' } record.update(errors)
def parse_LaunchAgentsDaemons(headers, output): LaunchAgents = multiglob(inputdir, [ 'System/Library/LaunchAgents/*.plist', 'Library/LaunchAgents/*.plist', 'Users/*/Library/LaunchAgents/*.plist', 'System/Library/LaunchAgents/.*.plist', 'Library/LaunchAgents/.*.plist', 'Users/*/Library/LaunchAgents/.*.plist' ]) LaunchDaemons = multiglob(inputdir, [ 'System/Library/LaunchDaemons/*.plist', 'Library/LaunchDaemons/*.plist', 'System/Library/LaunchDaemons/.*.plist', 'Library/LaunchDaemons/.*.plist' ]) for i in LaunchDaemons + LaunchAgents: record = OrderedDict((h, '') for h in headers) metadata = stats2(i, oMACB=True) record.update(metadata) record['src_file'] = i record['src_name'] = "launch_items" try: p = plistlib.readPlist(i) except: try: p = read_bplist(i) except: log.debug('Could not read plist {0}: {1}'.format( i, [traceback.format_exc()])) p = 'ERROR' if p != 'ERROR': if type(p) is list and len(p) > 0: p = p[0] # Try to get Label from each plist. try: record['prog_name'] = p['Label'] except KeyError: log.debug("Cannot extract 'Label' from plist: {0}".format(i)) record['prog_name'] = 'ERROR' # Try to get ProgramArguments if present, or Program, from each plist. try: prog_args = p['ProgramArguments'] program = p['ProgramArguments'][0] record['program'] = program if len(prog_args) > 1: record['args'] = ' '.join(p['ProgramArguments'][1:]) except (KeyError, IndexError), e: try: program = p['Program'] record['program'] = program except: log.debug( "Cannot extract 'Program' or 'ProgramArguments' from plist: {0}" .format(i)) program = None record['program'] = 'ERROR' record['args'] = 'ERROR' except Exception, e: log.debug('Could not parse plist {0}: {1}'.format( i, [traceback.format_exc()])) program = None # If program is ID'd, run additional checks. if program: cs_check_path = os.path.join(inputdir, program.lstrip('/')) record['code_signatures'] = str( get_codesignatures(cs_check_path, ncs)) hashset = get_hashes(program) record['sha256'] = hashset['sha256'] record['md5'] = hashset['md5']
if not quiet: if debug: sys.stdout.write( 'dirlist : INFO Wrote %d lines in %s | FileName: %s \033[K\r' % (counter, datetime.now(pytz.UTC) - startTime, name)) else: sys.stdout.write( 'dirlist : INFO Wrote %d lines in %s \r' % (counter, datetime.now(pytz.UTC) - startTime)) sys.stdout.flush() # get timestamps and metadata for each file record = OrderedDict((h, '') for h in headers) stat_data = stats2(os.path.join(root, name)) record.update(stat_data) # directory is bundle that ends with either of the three extensions, check its code signatures if no_code_signatures is False and name.endswith( check_signatures_bundles) and not name.startswith( '.'): #meaning DO process code signatures record['code_signatures'] = str( get_codesignatures(os.path.join(root, name))) output.write_entry(record.values()) filePool.close() filePool.join() if not quiet: sys.stdout.write('\n') sys.stdout.flush()