예제 #1
0
 def setEventDateTime(self, dt=None):
     if dt:
         self.Date = dt.strftime('%Y-%m-%d')
         self.Time = dt.strftime('%H:%M:%S')
         self._DT = dt
     else:
         printStatusMsg("Event Date & Time")
         
         default = self._DT.strftime('%Y-%m-%d %H:%M:%S')
         userDate = getUserInWithDef("Event Date/Time", default)
     
         try:
             if userDate != default:
                 self._DT = datetime.datetime.strptime(userDate, '%Y-%m-%d %H:%M:%S')
                 self.Date = self._DT.strftime('%Y-%m-%d')
                 self.Time = self._DT.strftime('%H:%M:%S')
                    
         except(ValueError):
             print("Error: Invalid input. Try again.")
             self.setEventDateTime()
             
     self.setAttribute('eventDT', self._DT.strftime('%Y-%m-%d %H:%M:%S'))
     self.setAttribute('eventEpoch', datetimeToEpoch(self._DT))
             
     self._localTZ = self._configs['cirta']['settings']['TIMEZONE']
     
     self._utcOffsetTimeDelta = pytz.timezone(self._localTZ).localize(datetime.datetime(self._DT.year, self._DT.month, self._DT.day)).utcoffset()
     self._absUTCOffsetTimeDelta = abs(self._utcOffsetTimeDelta)
예제 #2
0
def launchBackgroundedSources(playbook, event):

    log.info('msg="launching Backgrounded Sources"')

    for source in event._backgroundedDS:

        srcPlugin = playbook.getPlugin(source)
        try:
            printStatusMsg("%s Results" % srcPlugin.FORMAL_NAME)

            event.currentPlugin = source
            log.state('msg="execute" type="source" plugin="%s" stage="start" %s' % (source, event.getAttrs()))
            srcPlugin.execute(event)
            log.state('msg="execute" type="source" plugin="%s" stage="finish" %s' % (source, event.getAttrs()))
            event.currentPlugin = "cirta"
            printProvided(event, srcPlugin)

        except (KeyboardInterrupt):
            raise
        except:
            tb = traceback.format_exc()
            event._stackTraces.append(tb)
            print("\n" + colors.GREY + tb + colors.ENDC)
            log.error("Failure: Data Source Exception. Skipping...")
            log.debug('msg="fatal data source exception" source="%s"' % event.currentPlugin)
            pass
예제 #3
0
def launchSources(playbook, event, preAction=True):
    if preAction:
        log.info('msg="launching initializers" phase="pre-action prompt"')
    else:
        log.info('msg="launching initializers" phase="post-action prompt"')

    def initProvides(event, provides):
        for attr in provides:
            if not hasattr(event, attr):
                event.setAttribute(attr)

    if preAction:
        sources = playbook.PRE_SOURCES
    else:
        sources = playbook.POST_SOURCES

    for source in sources:
        srcPlugin = playbook.getPlugin(source)
        try:
            printStatusMsg("%s Results" % srcPlugin.FORMAL_NAME)
            if (
                playbook.adHoc
                or all([hasattr(event, attr) for attr in srcPlugin.REQUIRES])
                and all([getattr(event, attr) for attr in srcPlugin.REQUIRES])
            ):
                event.currentPlugin = source
                initProvides(event, srcPlugin.PROVIDES)
                log.state('msg="execute" type="source" plugin="%s" stage="start" %s' % (source, event.getAttrs()))
                srcPlugin.execute(event)
                log.state('msg="execute" type="source" plugin="%s" stage="finish" %s' % (source, event.getAttrs()))
                event.currentPlugin = "cirta"
                printProvided(event, srcPlugin)
            else:
                msg = colors.WARNING + "Missing required attributes:\n\n" + colors.ENDC
                for attr in srcPlugin.REQUIRES:
                    if hasattr(event, attr):
                        msg += "%s: %s\n" % (attr, getattr(event, attr))
                    else:
                        log.debug(
                            'msg="missing required attributes" source="%s" attribute="%s"' % (event.currentPlugin, attr)
                        )
                        msg += "%s\n" % (attr)
                log.debug(
                    'msg="skipping source" source="%s" reason="missing required attributes"' % (event.currentPlugin)
                )
                msg += colors.FAIL + "\nSkipping %s" % srcPlugin.FORMAL_NAME + colors.FAIL
                print(msg)

        except (KeyboardInterrupt):
            raise
        except:
            tb = traceback.format_exc()
            event._stackTraces.append(tb)
            print("\n" + colors.GREY + tb + colors.ENDC)
            log.error("Failure: Data Source Exception. Skipping...")
            log.debug('msg="fatal data source exception" source="%s"' % event.currentPlugin)
            pass
예제 #4
0
def verifyAttributes(event):
    for attr in [attr for attr in event._fifoAttrs.values() if attr.verify]:
        if attr.conflictsExist():
            printStatusMsg('Warning: %s Conflicts' % attr.name, 30, '-', color=colors.WARNING)
            print('\n'.join(["%s --> %s" %(x, y) for x, y in attr.valuesHistory if y is not None]))
            print('')
        if attr.value:
            event.setAttribute(attr.name, getUserInWithDef(attr.formalName, attr.value), force=True)
        elif attr.alwaysVerify:
            event.setAttribute(attr.name, getUserIn(attr.formalName, allowBlank=True), force=True)
예제 #5
0
def launchBackgroundedActions(playbook, event):
    log.info('msg="launching backgrounded actions"')
    for action in event._backgroundedActions:
        actionPlugin = playbook.getPlugin(action)
        printStatusMsg("%s Action" % actionPlugin.FORMAL_NAME)
        event.currentPlugin = action
        log.state('msg="execute" type="action" plugin="%s" stage="background_start" %s' % (action, event.getAttrs()))
        actionPlugin.execute(event)
        log.state('msg="execute" type="action" plugin="%s" stage="background_finish" %s' % (action, event.getAttrs()))
        event.currentPlugin = "cirta"
예제 #6
0
def printModeHeader(playbook, event):
    if playbook.adHoc:
        log.info('msg="cirta execution started" mode="ad-hoc"')
        event.adHoc = True
        printStatusMsg(" " * 14 + "Ad Hoc CIRTA execution", char=" ", length=50, color=colors.TITLE2)
    else:
        log.info('msg="cirta execution started" mode="playbook"')
        event.adHoc = False
        title = "%s CIRTA Playbook" % playbook.FORMAL_NAME
        padding = " " * ((50 - len(title)) / 2)
        printStatusMsg(padding + title, char=" ", length=50, color=colors.TITLE)
예제 #7
0
def checkExceptionalAttrs(event):
    exceptionalAttrs = [attr for attr in event._fifoAttrs.values() if hasattr(attr, 'exceptional') if attr.exceptional]

    if exceptionalAttrs:
        printStatusMsg('Exceptional Attribute', '-', 25)
        
        for attr in exceptionalAttrs:
            print('\n'.join(["%s.%s --> %s" %(x, attr.name, y) for x, y in attr.valuesHistory if y]))
            
        print('')
        while getUserIn('Do you acknowledge?') not in YES:
            True
예제 #8
0
def printProvided(event, source):
    if source.PROVIDES:
        printStatusMsg("Extracted Attributes", 22, "-", color=colors.HEADER2)
        for attr in source.PROVIDES:

            if hasattr(event, attr) and getattr(event, attr):
                print(
                    "%s: %s%s%s"
                    % (event._fifoAttrs[attr].formalName, colors.OKGREEN, getattr(event, attr), colors.ENDC)
                )
            else:
                print("%s: %s" % (event._fifoAttrs[attr].formalName, ""))
예제 #9
0
    def setOutPath(self, defFileName=None):
        
        def checkPath(filePath):
            proposedPath = getUserInWithDef('Path', filePath)
            existingFiles = glob.glob(proposedPath + '.*')
            
            if not existingFiles:
                return proposedPath
            else:
                try:
                    with open(existingFiles[0], 'a'):
                        log.warn('Warning: files with this base path exist. Proceeding will very likely overwrite a previous run.')
                        if getUserInWithDef('Proceed? (Yes/No)', 'No') in YES:
                            return proposedPath
                        else:
                            print('')
                            return checkPath(filePath)
                except(IOError):
                    log.warn('Warning: files with this base path exist. You are not able to overwrite, please modify and try again.')
                    return checkPath(filePath)
                
                            
        if hasattr(self, '_baseFilePath') and self._baseFilePath:
            return
        printStatusMsg("Output base file path")
        
        if defFileName:
            baseFilePath = "%s/%s" % (self._outDir, defFileName)
        else:
            baseFilePath = "%s/%s_%s" % (self._outDir, self._analystUsername, datetime.datetime.today().strftime("%H%M"))
        
        
        self.setAttribute('_baseFilePath', checkPath(baseFilePath))
        
        if self._outDir not in self._baseFilePath:
            self._outDir = os.path.dirname(os.path.abspath(self._baseFilePath))

        if not os.path.exists(os.path.join(self._outDir, 'bin')):
            os.makedirs(os.path.join(self._outDir, 'bin'))
            if self._outDirGroup:
                os.chown(self._outDir, -1, grp.getgrnam(self._outDirGroup).gr_gid)
                for root, dirs, files in os.walk(self._outDir):  
                    for momo in dirs:  
                        os.chown(os.path.join(root, momo), -1, grp.getgrnam(self._outDirGroup).gr_gid)
                    for momo in files:
                        os.chown(os.path.join(root, momo), -1, grp.getgrnam(self._outDirGroup).gr_gid)
                        
        with open(self._baseFilePath + '.id', 'w') as outFile:
            outFile.write(self.cirta_id + '\n')
예제 #10
0
def seedAttributes(event):
    printStatusMsg("Pre-Seed Attributes")

    while True:
        attrName = getUserMultiChoice(
            "Defined Attributes",
            "Attribute to seed",
            [x for x in sorted(event._configs["attributes"].keys()) if not x.startswith("_")],
            numCols=4,
            allowMultiple=False,
        )[0]
        event.setAttribute(attrName, value=getUserIn("Seed value for %s" % attrName), immutable=True)
        print("")
        if getUserIn("Seed more attributes?") not in YES:
            break
예제 #11
0
def execute(event):
    
    sp = Splunk(host=SPLUNK_SEARCH_HEAD, port=SPLUNK_SEARCH_HEAD_PORT, username=SPLUNK_SEARCH_HEAD_USERNAME, password=SPLUNK_SEARCH_HEAD_PASSWORD, scheme=SPLUNK_SEARCH_HEAD_SCHEME)
        
    query = '''search index=cirta level=INFO msg="quarantine hosts" | head 1 | table _time hosts'''

    print('\nChecking Splunk...'),
        
    results = sp.search(query)

    print('Done\n')
    
     
    if not results:
        log.warn("Unable to retrieve previous quarantine hosts from Splunk")
        exit()
    else:
        hosts = set([x.strip() for x in results[0]['hosts'].split(',')])

    toRemove = getUserMultiChoice("Quarantine Hosts", "Hosts to Unquarantine", hosts, 2)     
    
    remainingHosts = [host for host in hosts if host not in toRemove]
    
    print('')
    print(colors.BOLDON + "Hosts before:     " + colors.BOLDOFF + ' '.join(['"%s"' % x for x in hosts]))
    print(colors.BOLDON + "Hosts to remove:  " + colors.BOLDOFF + ' '.join(['"%s"' % x for x in toRemove]))
    print(colors.BOLDON + "Hosts after:      " + colors.BOLDOFF + ' '.join(['"%s"' % x for x in remainingHosts]))
       
    event.setAttribute('unquarantine_hosts', ' '.join(['"%s"' % x for x in remainingHosts]))
                            
    groupMods = '''config vdom
edit vd-inet
config firewall addrgrp
edit "grp-infosec-blacklist-hosts"
set member %s
next
end
end''' % (event.unquarantine_hosts)

    printStatusMsg('Final FW Change', 22, '>', color=colors.HEADER2)
    print groupMods
    printStatusMsg('Final FW Change', 22, '<', color=colors.HEADER2)
    
    
    if getUserIn('Commit final changes to quarantine state? (y/n)') in YES:
        #print '''msg="quarantine hosts" hosts="%s"''' % (','.join(event.quarantine_hosts.strip('"').split('" "')))
        log.info('''msg="quarantine hosts" hosts="%s"''' % (','.join(event.unquarantine_hosts.strip('"').split('" "'))))
        
예제 #12
0
def setPCAPRange(event):
    if event._DT and hasattr(event, '_pcapStart') and hasattr(event, '_pcapEnd'):
        return
    
    printStatusMsg("PCAP Date & Time Window")
    
    print('Configured Timezone: %s\n' % event._localTZ)
    
    if event.adHoc:
        tz = getUserInWithDef('Timezone (Local/UTC)', 'UTC')
    else:
        tz = getUserInWithDef('Timezone (Local/UTC)', 'Local')
        
    if not (tz.lower() == 'utc' or tz.lower() == 'local'):
        print(colors.FAIL + "Error: Invalid timezone, expected UTC or Local. Try again." + colors.ENDC)
        setPCAPRange(event)
        return
    
    utc = tz.lower() == 'utc'
    
    if utc:
        eventDT = event._DT - event._utcOffsetTimeDelta
        today = datetime.datetime.today() - event._utcOffsetTimeDelta
    else:
        eventDT = event._DT
        today = datetime.datetime.today() - event._utcOffsetTimeDelta
    
    try:
        event._pcapDT = datetime.datetime.strptime(getUserInWithDef("Date/Time of interest", eventDT.strftime("%Y-%m-%d %H:%M:%S")), '%Y-%m-%d %H:%M:%S')
        
        if utc:
            event._pcapStart = event._pcapDT - datetime.timedelta(minutes=int(getUserInWithDef("Minutes Before", confVars.defaultBefore)))
            event._pcapEnd = event._pcapDT + datetime.timedelta(minutes=int(getUserInWithDef("Minutes After", confVars.defaultAfter)))
            
        else:
            event._pcapStart = event._pcapDT - datetime.timedelta(minutes=int(getUserInWithDef("Minutes Before", confVars.defaultBefore))) - event._utcOffsetTimeDelta
            event._pcapEnd = event._pcapDT + datetime.timedelta(minutes=int(getUserInWithDef("Minutes After", confVars.defaultAfter))) - event._utcOffsetTimeDelta
    
        if event._pcapEnd > today:
            print(colors.WARNING + "\nI'm good, but not that good... I can't predict traffic\ninto the future, pulling pcaps up to now." + colors.ENDC)
            event._pcapEnd = today
    except(ValueError):
        print(colors.FAIL + "Error: Invalid input. Try again." + colors.ENDC)
        setPCAPRange(event)
        return
        
    print('\nPCAP range set from %s to %s' % (event._pcapStart, event._pcapEnd))
예제 #13
0
def playbookInput(event):
    inputHeader = '%s Query Options' % FORMAL_NAME
    
    if not confVars.userDN or not confVars.password:
        printStatusMsg(inputHeader)
    
    if not confVars.userDN:
        confVars.userDN = getUserIn('User Distinguished Name')
    
    if not confVars.password:
        confVars.password = getpass("Password: ")

    successful = False
    while not successful:
        successful = pydap.ldapConnect(confVars.ldapServer, confVars.userDN, confVars.password, confVars.baseDistinguishedName)
        
        if not successful:
            print('Invalid Credentials, ldap data sources will fail.')
            return        
예제 #14
0
 def runPrompt(self):
     if self.header:
         printStatusMsg(self.header)
         self.header = None
          
     if self.description:
         if self.multiline:
             print(self.description + '\n(Ctrl+D to end input)\n')
         else:
             print(self.description + '\n')
         
     if self.default:
         if self.multiline:
             raise EventSetAttributeError("Incompatible argument combination: default can't be used for multiline input mode.")
         self.setValue(getUserInWithDef(self.prompt, self.default))
     elif self.multiline:
         print(self.prompt)
         self.setValue(sys.stdin.read())
     else:
         self.setValue(getUserIn(self.prompt))
예제 #15
0
def execute(event):
    
    analysts = {}
    for analyst, email, txt in [x.split(',') for x in containmentAnalystsEmails.split('|')]:
        analysts[analyst] = {'email': email, 'txt': txt}
    
    perimeterBlock = getUserIn("Request Perimeter Block (Yes/No)") in YES
    event.setAttribute('perimeter_block', perimeterBlock)
    
    if perimeterBlock and (notifyContainmentAnalysts or event._analystUsername not in analysts):
        
        selectedAnalysts = getUserMultiChoice('Choose Containment Analysts', 'Analysts', analysts.keys(), numCols=1, default=['All'], allChoice=True)
                                
        subject = 'CIRTA Perimeter Block'
        msg = '''

CIRTA ID -- %s
Analyst -- %s
IP -- %s
Host -- %s
MAC-- %s''' % (event.cirta_id, event._analystUsername, event.ip_address, event.hostname, event.mac_address)

        smsFilePath = event._baseFilePath + '.sms'
        f = open(smsFilePath, 'w')
        f.write(subject + msg)
        f.close()
        subprocess.call(['nano', smsFilePath])
        f = open(smsFilePath, 'r')
        msg = f.read()
        f.close()
        
        printStatusMsg('Final Request', 22, '>', color=colors.HEADER2)
    
        print(msg)
        
        printStatusMsg('Final Request', 22, '<', color=colors.HEADER2)
    
        if getUserIn('Send Request (Yes/No)') in YES:
            m = MailServer(fromAddr=fromAddr, server=mailServerName)
            m.sendMail(subject + ' - %s' % event.cirta_id, msg, fromAddr, toAddr=[v['email'] for k,v in analysts.items() if k in selectedAnalysts])
            m.sendText(msg, fromAddr, toAddr=[v['txt'] for k,v in analysts.items() if k in selectedAnalysts])
예제 #16
0
def launchActionsNow(playbook, event):
    keepaliveWait()
    log.info('msg="prompt to launch actions"')
    msg = """Launching Playbook Actions now means the remaining Playbook Sources will be executed at the end.
Otherwise the remaining Playbook Sources will be executed, followed by the Playbook Actions at the end.

Actions to execute: %s%s%s
Remaining Playbook Sources: %s%s%s

""" % (
        colors.BOLDON,
        ", ".join(playbook.ACTIONS),
        colors.BOLDOFF,
        colors.BOLDON,
        ", ".join(playbook.POST_SOURCES),
        colors.BOLDOFF,
    )

    printStatusMsg("Launch Playbook Actions Now?")
    print(msg)

    return getUserIn("Launch Playbook Actions Now?") in YES
예제 #17
0
 def setDateRange(self):
     if self._DT and hasattr(self, '_startDate') and hasattr(self, '_endDate'):
         return
     
     printStatusMsg("Date & Surrounding Days")
 
     userDate = getUserInWithDef("Date of interest", self._DT.date().isoformat())
     
     try:
         if userDate != self._DT.date().isoformat():
             self._DT = datetime.datetime.strptime(userDate, '%Y-%m-%d')
         
         self._daysBefore = int(getUserInWithDef("Days Before", '0'))       
         self._daysAfter = int(getUserInWithDef("Days After", '0'))       
         self._startDate = self._DT - datetime.timedelta(days=self._daysBefore)
         self._endDate = self._DT + datetime.timedelta(days=self._daysAfter)
     
         if self._endDate > datetime.datetime.today():
             print("\nI'm good, but not that good... I can't predict system")
             print("behavior days into the future, pulling logs up to today.")
             self._endDate = datetime.datetime.today()
     except(ValueError):
         print("Error: Invalid input. Try again.")
         self.setDateRange()
예제 #18
0
def execute(event):
    if event._splunk.splunkEnabled:
        printStatusMsg('Splunk CIRTA App', length=20, char='-', color=colors.HEADER2)
        print(event._splunk.splunkCirtaAppURL)
        printStatusMsg('Splunk Incident Details', length=20, char='-', color=colors.HEADER2)
        print(event._splunk.splunkCirtaIncidentURL)
        printStatusMsg('Splunk Raw Search', length=20, char='-', color=colors.HEADER2)
        print(event._splunk.splunkCirtaSearchURL)
    else:
        print("Splunk not enabled.")
예제 #19
0
def execute(event):
    
    sp = Splunk(host=SPLUNK_SEARCH_HEAD, port=SPLUNK_SEARCH_HEAD_PORT, username=SPLUNK_SEARCH_HEAD_USERNAME, password=SPLUNK_SEARCH_HEAD_PASSWORD, scheme=SPLUNK_SEARCH_HEAD_SCHEME)
    
    def createFWObject():
        event.setAttribute('cirtaID', prompt='CIRTA ID', header='Quarantine', force=True)
            
        query = '''search index=cirta cirta_id=%s level=STATE | head 1 | fields - _raw | table *''' % (event.cirtaID)
    
        print('\nChecking Splunk...'),
            
        results = sp.search(query)
    
        print('Done\n')
        
        try:
            result = results.next()
        except(StopIteration):
            log.warn("Error: unable to pull CIRTA ID state from Splunk")
            exit()

        if result.get('hostname'):
            defaultName = 'cmpd-host-' + result.get('hostname')
        else:
            defaultName = 'cmpd-host-' + result.get('ip_address')
        
        event.setAttribute('fw_object_name', default=defaultName, prompt="Firewall Object Name", force=True)
        event.setAttribute('ip_address', default=result['ip_address'], prompt="IP to Quarantine", force=True)
        event.setAttribute('subnet_mask', default='255.255.255.255', prompt="Subnet Mask", force=True)
        
        msg = ''
        for qAttr in [x.strip() for x in quarantineAttrs.split(',') if x if x.strip()]:
            value = result.get(qAttr.lstrip('_'))
    
            if value:                
                event.setAttribute(qAttr, result.get(qAttr.lstrip('_')), force=True)
                msg += '%s -- %s\n' % (event._fifoAttrs[qAttr].formalName, event._fifoAttrs[qAttr].value)
     
        event._baseFilePath = result['baseFilePath']
        outfilePath = event._baseFilePath + '.eventd'
        
        with open(outfilePath, 'w') as outfile:
            outfile.write(msg)
            
        subprocess.call(['nano', outfilePath])
        
        with open(outfilePath, 'r') as infile:
            msg = infile.read()
    
        firewallObject = '''config vdom
edit vd-inet
config firewall address
edit "%s"
set comment "%s"
set color 13
set subnet %s %s
next
end
end''' % (event.fw_object_name, msg.replace('"', '').rstrip(), event.ip_address, event.subnet_mask)
    
        printStatusMsg('Firewall Object(s)', 22, '>', color=colors.HEADER2)
        
        print firewallObject

        printStatusMsg('Firewall Object(s)', 22, '<', color=colors.HEADER2)
        
        return event.fw_object_name, firewallObject
    
    
        
    def getGroupModifications(fwObjects):
        
        query = '''search index=cirta level=INFO msg="quarantine hosts" | head 1 | table _time hosts'''
    
        print('\nChecking Splunk...'),
            
        results = sp.search(query)
    
        print('Done\n')
        
         
        try:
            result = results.next()
            originalHosts = [x.strip() for x in result['hosts'].split(',')]
            hosts = originalHosts[:]
            hosts.extend(fwObjects.keys())
            hosts = set(hosts)
        except(StopIteration):
            log.warn("Unable to retrieve previous quarantine hosts from Splunk")
            hosts = fwObjects.keys()

        toRemove = getUserMultiChoice("Unquarantine Hosts", "Hosts to Unquarantine", hosts, 2, default=['None'], noneChoice=True)     
        
        remainingHosts = [host for host in hosts if host not in toRemove]
    
        print('')
        print(colors.BOLDON + "Hosts before:     " + colors.BOLDOFF + ' '.join(['"%s"' % x for x in originalHosts]))
        print(colors.BOLDON + "Hosts to add:     " + colors.BOLDOFF + ' '.join(['"%s"' % x for x in fwObjects.keys()]))
        print(colors.BOLDON + "Hosts to remove:  " + colors.BOLDOFF + ' '.join(['"%s"' % x for x in toRemove]))
        print(colors.BOLDON + "Hosts after:      " + colors.BOLDOFF + ' '.join(['"%s"' % x for x in remainingHosts]))        
    
        event.setAttribute('quarantine_hosts', ' '.join(['"%s"' % x for x in set(remainingHosts)]))

        groupMods = '''config vdom
edit vd-inet
config firewall addrgrp
edit "grp-infosec-blacklist-hosts"
set member %s
next
end
end''' % (event.quarantine_hosts)
        
        return groupMods
        
    if getUserInWithDef("Reset current quarantine state? (y/n)", "n") in YES:
        reset = True
        print('''
This option should be used sparingly. 
Intended use is to take the command preview 
output from the Fortigate and paste the existing
address object names including quotes. Please
note that little, if any, validation is done
with this input.

(Ctrl+D on empty line to end input)\n''')
        
        event.quarantine_hosts = sys.stdin.read().strip()
        
        groupModifications = '''config vdom
edit vd-inet
config firewall addrgrp
edit "grp-infosec-blacklist-hosts"
set member %s
next
end
end''' % (event.quarantine_hosts)

        final = '\n' + groupModifications 
        
    else:        
        reset = False
        fwObjects = {}
        
        name, obj = createFWObject()
        fwObjects[name] = obj
        
        while(getUserIn('Quarantine another device? (y/n)') in YES):
            name, obj = createFWObject()
            fwObjects[name] = obj        
            
        groupModifications = getGroupModifications(fwObjects)
    
        final = '\n'.join([x.strip() for x in fwObjects.values()])
        final += '\n' + groupModifications
        
    printStatusMsg('Final FW Change', 22, '>', color=colors.HEADER2)
    print final
    printStatusMsg('Final FW Change', 22, '<', color=colors.HEADER2)
    
    if getUserIn('Commit final changes to quarantine state? (y/n)') in YES:
        #print '''msg="quarantine hosts" hosts="%s"''' % (','.join(event.quarantine_hosts.strip('"').split('" "')))
        log.info('''msg="quarantine hosts" hosts="%s"''' % (','.join(event.quarantine_hosts.strip('"').split('" "'))))
        if not reset:
            with open(event._baseFilePath + '.fgblock', 'w') as outFile:
                outFile.write(final)
예제 #20
0
    def createFWObject():
        event.setAttribute('cirtaID', prompt='CIRTA ID', header='Quarantine', force=True)
            
        query = '''search index=cirta cirta_id=%s level=STATE | head 1 | fields - _raw | table *''' % (event.cirtaID)
    
        print('\nChecking Splunk...'),
            
        results = sp.search(query)
    
        print('Done\n')
        
        try:
            result = results.next()
        except(StopIteration):
            log.warn("Error: unable to pull CIRTA ID state from Splunk")
            exit()

        if result.get('hostname'):
            defaultName = 'cmpd-host-' + result.get('hostname')
        else:
            defaultName = 'cmpd-host-' + result.get('ip_address')
        
        event.setAttribute('fw_object_name', default=defaultName, prompt="Firewall Object Name", force=True)
        event.setAttribute('ip_address', default=result['ip_address'], prompt="IP to Quarantine", force=True)
        event.setAttribute('subnet_mask', default='255.255.255.255', prompt="Subnet Mask", force=True)
        
        msg = ''
        for qAttr in [x.strip() for x in quarantineAttrs.split(',') if x if x.strip()]:
            value = result.get(qAttr.lstrip('_'))
    
            if value:                
                event.setAttribute(qAttr, result.get(qAttr.lstrip('_')), force=True)
                msg += '%s -- %s\n' % (event._fifoAttrs[qAttr].formalName, event._fifoAttrs[qAttr].value)
     
        event._baseFilePath = result['baseFilePath']
        outfilePath = event._baseFilePath + '.eventd'
        
        with open(outfilePath, 'w') as outfile:
            outfile.write(msg)
            
        subprocess.call(['nano', outfilePath])
        
        with open(outfilePath, 'r') as infile:
            msg = infile.read()
    
        firewallObject = '''config vdom
edit vd-inet
config firewall address
edit "%s"
set comment "%s"
set color 13
set subnet %s %s
next
end
end''' % (event.fw_object_name, msg.replace('"', '').rstrip(), event.ip_address, event.subnet_mask)
    
        printStatusMsg('Firewall Object(s)', 22, '>', color=colors.HEADER2)
        
        print firewallObject

        printStatusMsg('Firewall Object(s)', 22, '<', color=colors.HEADER2)
        
        return event.fw_object_name, firewallObject
예제 #21
0
def execute(event):
    
    def splitAndStrip(raw):
        return [x.strip() for x in raw.split(',')]
      
    #subject = getUserInWithDef('Subject', '%s %s' % (subjectStart, event.Category.split(',')[0]))
    
    event.ir_ticket = getUserIn('IR Ticket')
    
    toAddress = splitAndStrip(getUserInWithDef('Recipient(s)', confVars.toAddr))
    
    if confVars.cc:
        cc = [confVars.cc]
    else:
        cc = []
        
    if confVars.bcc:
        bcc = [confVars.bcc]
    else:
        bcc = []
        
    mailServer = MailServer(confVars.fromAddr, toAddress, server=confVars.mailServerName)
    
    if event.hostname:
        subjectAdd = "%s - %s" % (event.hostname, event.description) 
    else:
        subjectAdd = "%s - %s" % (event.ip_address, event.description)
        
    subject = getUserInWithDef('Subject', '%s - %s' % (confVars.subject, subjectAdd))
    
    print('')

    msg = confVars.header
    
    eventStage = splitAndStrip(confVars.eventStage)
    eventDefaultStage = splitAndStrip(confVars.eventDefaultStage)
    
    containmentActions = splitAndStrip( confVars.containmentActions)
    containmentPreferred = splitAndStrip( confVars.containmentPreferred)
    containmentAlternative = splitAndStrip( confVars.containmentAlternative)
    containmentTimeline = splitAndStrip( confVars.containmentTimeline)
    containmentDefaultTimeline = splitAndStrip( confVars.containmentDefaultTimeline)
    
    eradicationActions = splitAndStrip( confVars.eradicationActions)
    eradicationDefaultActions = splitAndStrip( confVars.eradicationDefaultActions)
    eradicationTimeline = splitAndStrip( confVars.eradicationTimeline)
    eradicationDefaultTimeline = splitAndStrip( confVars.eradicationDefaultTimeline)
    

    event.eventStage = ', '.join(getUserMultiChoice('Current Event Stage', 'Selection', eventStage, numCols=1, default=eventDefaultStage, allowMultiple=False))
    
    event.containmentPreferred = ', '.join(getUserMultiChoice('Preferred Containment', 'Selection', containmentActions, numCols=2, default=containmentPreferred, allowMultiple=True, other=True))
    event.containmentAlternative = ', '.join(getUserMultiChoice('Alternative Containment', 'Selection', containmentActions, numCols=2, default=containmentAlternative, allowMultiple=True, other=True))
    event.containmentTimeline = ', '.join(getUserMultiChoice('Containment Timeline', 'Selection', containmentTimeline, numCols=2, default=containmentDefaultTimeline, allowMultiple=False, other=True))
    
    event.eradicationActions = ', '.join(getUserMultiChoice('Mitigation Actions', 'Selection', eradicationActions, numCols=1, default=eradicationDefaultActions, allowMultiple=True, other=True))
    event.eradicationTimeline = ', '.join(getUserMultiChoice('Mitigation Timeline', 'Selection', eradicationTimeline, numCols=2, default=eradicationDefaultTimeline, allowMultiple=False, other=True)) 
        
    
    msg += 'Incident Response Details\n'
    msg += '------------------------------------------------\n'
    msg += 'Response Stage -- %s\n\n' % event.eventStage
    
    msg += 'Containment Timeline -- %s\n' % event.containmentTimeline
    msg += 'Containment Preference -- %s\n\n' % event.containmentPreferred
    msg += 'Containment Alternatives -- %s\n\n' % event.containmentAlternative
    
    msg += 'Mitigation Timeline -- %s\n' % event.eradicationTimeline
    msg += 'Mitigation Action -- %s\n' % event.eradicationActions
    
    emailSections = splitAndStrip(confVars.emailSections)
    
    for emailSection in emailSections:
        sectionAttrs = [attr for attr in event._fifoAttrs.values() if attr.value and attr.verify and attr.emailSection == emailSection]
        if sectionAttrs:
            msg += '\n%s\n' % emailSection
            msg += '------------------------------------------------\n'
            for attr in sectionAttrs:
                msg += '%s -- %s\n' % (attr.formalName, attr.value)

    msg += confVars.footer
     
    ticketFilePath = event._baseFilePath + '.ticket'
    f = open(ticketFilePath, 'w')
    f.write(msg)
    f.close()
    subprocess.call(['nano', ticketFilePath])
    f = open(ticketFilePath, 'r')
    msg = f.read()
    f.close()
    
    printStatusMsg('IR Final Ticket', 22, '>', color=colors.HEADER2)
    
    print('Subject: %s\n' % subject)
    print(msg + '\n')
    
    printStatusMsg('IR Final Ticket', 22, '<', color=colors.HEADER2)
    
    raw_input(colors.BOLDON + "Hit 'Enter' to continue..." + colors.BOLDOFF)
    
    printStatusMsg('Email Final Ticket', 22, '-', color=colors.HEADER2)
    
    f = open(ticketFilePath, 'w')
    f.write(msg)
    f.close()
    
    print('From: %s' % confVars.fromAddr)
    print('To:   %s' % ', '.join(toAddress))
    if cc:
        print('CC:   %s' % ', '.join(cc))
    if bcc:
        print('BCC:   %s' % ', '.join(bcc))
    print('Subject: %s\n' % subject)
    print(msg + '\n')
    
    if getUserIn('Send Email?') in YES:
        if not event._testing:
            mailServer.sendMail(subject, msg, ccAddr=cc, bccAddr=bcc, prior=priority)
예제 #22
0
def execute(event):

    if not os.path.exists(confVars.broPath):
        log.error('Bro does not exist check installation and [%s] in sources.conf' % __name__)
        log.debug('msg="configured bro path invalid" path="%s"' % confVars.broPath)
        return 
    
    if not os.path.exists('%s/bro/extract.bro' % (event._resourcesPath)):
        log.error('Bro extract script does not exist check CIRTA resources directory')
        log.debug('msg="bro extract resource path invalid" path="%s"' % '%s/bro/extract.bro' % (event._resourcesPath))
        return 
    
    extracted = []
    
    for pcap in event.pcaps:
        
        outDir = os.path.dirname(os.path.abspath(pcap))
        
        try:
            tempPath = tempfile.mkdtemp(dir=outDir)
        except(OSError):
            log.warning("Warning: problem creating temporary directory at '%s'. Skipping..." % outDir)
            log.debug('msg="unable to create temp pcap directory" path="%s" result="skipping"' % outDir)
            break
        
        printStatusMsg(os.path.basename(pcap), length=20, char='-', color=colors.HEADER2)
        
        os.chdir(tempPath)
        
        pcapBase = "%s/%s" % (outDir, '.'.join(os.path.basename(pcap).split('.')[:-1]))

        runBash("%s -r %s %s/bro/extract.bro" % (confVars.broPath, pcap, event._resourcesPath))
        
        logs = ["%s/%s" % (tempPath,x) for x in os.listdir(tempPath)]

        for log in [x for x in logs if '.log' in x]:
            dest = '.'.join([pcapBase, 'bro', os.path.basename(log)])
            os.rename(log, dest)
            if 'files.log' in dest:
                filesPath = dest
            print('Bro Generated: %s' % dest)
            
            event._splunk.push(sourcetype="brospect_" + dest.split('.')[-2], filename=dest, exclusionRegex='^#')

        if os.path.exists(tempPath + '/extract_files'):
            files = open(filesPath).read().splitlines()
            print('')
            extractBase = os.sep.join([outDir, 'bin',  '.'.join(os.path.basename(pcap).split('.')[:-1])])
    
            for extract in ["%s/%s/%s" % (tempPath,'extract_files',x) for x in os.listdir(tempPath + '/extract_files')]:
                extractName = os.path.basename(extract)
                
                filename = [x for x in files if extractName in x][0].split('\t')[9]
                if filename != '-':
                    newName = '.'.join([extractBase, filename, extractName])
                else:
                    newName = '.'.join([extractBase, extractName])
                os.rename(extract, newName)
                print('Bro Extracted: %s' % newName)
                extracted.append(newName)
        
        runBash('rm -r %s' % tempPath)

    if not extracted:
        extracted = None
    
    event.setAttribute('extracted_files', extracted)

    os.chdir(outDir)
예제 #23
0
def execute(event):
    def normMV(prompt, result, field):
        if result.get(field):
            value = result[field]
            if isinstance(value, list):
                if len(set(value)) > 1:
                    return ", ".join(
                        getUserMultiChoice(
                            prompt, "Selection", list(set(value)), numCols=1, default=[value[-1]], allowMultiple=False
                        )
                    )
                else:
                    return value[0]
            elif value:
                return value

        return ""

    sp = Splunk(
        host=SPLUNK_SEARCH_HEAD,
        port=SPLUNK_SEARCH_HEAD_PORT,
        username=SPLUNK_SEARCH_HEAD_USERNAME,
        password=SPLUNK_SEARCH_HEAD_PASSWORD,
        scheme=SPLUNK_SEARCH_HEAD_SCHEME,
    )

    if not sp.connected:
        log.warn(
            "FireEye initializer requires the Splunk API, please ensure your Splunk instance is available for API connections"
        )
        exit()

    if hasattr(event, "fireID"):
        event.setAttribute("fireID", prompt="FireEye ID", header="", force=True)
    else:
        event.setAttribute("fireID", prompt="FireEye ID", header="FireEye Initial Indicator")

    event.setAttribute("alertID", event.fireID, force=True)
    event.setAttribute("alertType", "FireEye", force=True)

    query = """search index=fireeye earliest_time=-60d 
| spath output="alert_id" alert.id 
| spath output="alert_id_mv" "alert{}.id" 
| eval alert_id = coalesce(alert_id, alert_id_mv)
| spath output="alert_product" alert.product 
| spath output="alert_product_mv" "alert{}.product" 
| eval  alert_product = coalesce(alert_product, alert_product_mv)
| spath output="alert_sensor" alert.sensor 
| spath output="alert_sensor_mv" "alert{}.sensor" 
| eval  alert_sensor = coalesce(alert_sensor, alert_sensor_mv)
| spath output="alert_occurred" alert.occurred 
| spath output="alert_occurred_mv" "alert{}.occurred" 
| eval  alert_occurred = coalesce(alert_occurred, alert_occurred_mv)
| spath output="alert_src_ip" alert.src.ip 
| spath output="alert_src_ip_mv" "alert{}.src.ip" 
| eval  alert_src_ip = coalesce(alert_src_ip, alert_src_ip_mv)
| spath output="alert_src_mac" alert.src.mac 
| spath output="alert_src_mac_mv" "alert{}.src.mac" 
| eval  alert_src_mac = coalesce(alert_src_mac, alert_src_mac_mv)
| spath output="alert_dst_ip" alert.dst.ip 
| spath output="alert_dst_ip_mv" "alert{}.dst.ip" 
| eval  alert_dst_ip = coalesce(alert_dst_ip, alert_dst_ip_mv)
| spath output="alert_dst_mac" alert.dst.mac 
| spath output="alert_dst_mac_mv" "alert{}.dst.mac" 
| eval  alert_dst_mac = coalesce(alert_dst_mac, alert_dst_mac_mv)
| spath output="alert_name" alert.name 
| spath output="alert_name_mv" "alert{}.name" 
| eval  alert_name = coalesce(alert_name, alert_name_mv)
| spath output="malware_names" "alert.explanation.malware-detected.malware{}.name" 
| spath output="malware_names_mv" "alert{}.explanation.malware-detected.malware{}.name" 
| eval  malware_names = coalesce(malware_names, malware_names_mv)
| search alert_id="%s"
| table alert_occurred alert_product alert_sensor alert_id alert_src_ip alert_src_mac alert_dst_ip alert_dst_mac alert_name malware_names""" % (
        event.fireID
    )

    print("\nChecking Splunk..."),

    sys.stdout.flush()

    results = sp.search(query)

    print("Done")

    try:
        result = results.next()
    except (StopIteration):
        log.warn("Error: unable to pull FireEye ID event details from Splunk")
        exit()

    event.setOutPath(event.fireID)

    product = normMV("Product", result, "alert_product")
    sensor = normMV("Sensor", result, "alert_sensor")

    printStatusMsg("%s - %s" % (product, sensor))

    occurred = normMV("Occurred", result, "alert_occurred")
    if "T" in occurred:
        timestamp = datetime.datetime.strptime(occurred, "%Y-%m-%dT%H:%M:%SZ").strftime("%Y-%m-%d %H:%M:%S")
    else:
        timestamp = occurred.split("+")[0]

    srcIP = normMV("Source IP", result, "alert_src_ip")
    srcMAC = normMV("Source Mac", result, "alert_src_mac")
    dstIP = normMV("Destination IP", result, "alert_dst_ip")
    dstMAC = normMV("Destination Mac", result, "alert_dst_mac")
    secondaryName = normMV("Secondary Alert Name", result, "malware_names")
    name = normMV("Alert Name", result, "alert_name")
    signature = "%s %s" % (name, secondaryName)

    """
    if isinstance(malwareNames, list):
        secondaryName = ', '.join(getUserMultiChoice('Secondary Alert Name', 'Selection', malwareNames, numCols=1, default=[malwareNames[-1]], allowMultiple=False))
    else:
        secondaryName = malwareNames
    """

    # Note the utc offset for the US will always be -x so by adding the offset you are adding a negative, i.e. subtracting
    # This is very important for accurate time conversion.  You should always add the offset if the time is in UTC and
    # subtract the offset if the time is local.  If the reverse makes more sense to you, event._absUTCOffsetTimeDelta
    # is available
    # Also note, setEventDateTime is called twice to initialize utcOffsetTimeDelta then adjust.
    event.setEventDateTime(datetime.datetime.strptime(timestamp, "%Y-%m-%d %H:%M:%S"))
    event.setEventDateTime(event._DT + event._utcOffsetTimeDelta)

    print("\nLocal Timestamp      Source IP        Destination IP   Signature")
    print("-" * 80)
    print("%-20s %-16s %-16s %s\n" % (event._DT.strftime("%Y-%m-%d %H:%M:%S"), srcIP, dstIP, signature))

    event.setAttribute("Event_Date/Time", event._DT.strftime("%Y-%m-%d %H:%M:%S"))

    if "CMS" in product:
        event.setAttribute("ip_address", prompt="IP Address")
    else:
        ans = getUserInWithDef("Track source or destination (s/d)", "s")
        if "s" in ans:
            if srcIP:
                event.setAttribute("ip_address", srcIP)
            else:
                event.setAttribute("ip_address", prompt="\nIP Address")
            # if srcMAC:
            #    event.setAttribute('mac_address', srcMAC)
        elif "d" in ans:
            if dstIP:
                event.setAttribute("ip_address", dstIP)
            else:
                event.setAttribute("ip_address", prompt="\nIP Address")
            # if dstMAC:
            #    event.setAttribute('mac_address', dstMAC)
        else:
            event.setAttribute(
                "ip_address",
                prompt="IP Address",
                default=ans,
                description="Neither the source or destination was chosen, please confirm.",
            )

    print("")

    event.setAttribute("description", prompt="Description", default=signature)
    event.setDateRange()
예제 #24
0
def execute(event):
    
    try:
        sc = SecurityCenter5(event.scHostname)
    except:
        log.error("Failed to connect to Security Center")
        return

    sc.login(event.scUser, event.scPassword)

    ipInfo = sc.get('''ipInfo?ip=%s''' % event.ip_address)
    
    if ipInfo.status_code == 200:
        ipInfo = ipInfo.json()['response']
        if not ipInfo.get('repositories'):
            log.warn("No vulnerability results found")
            return
    else:
        log.warn("No vulnerability results found")
        return

    #ipInfo = sc.ip_info(event.ip_address)['records']

    if ipInfo:
        event.setAttribute('operating_system', ipInfo.get('os'))
        if ipInfo.get('netbiosName'):
            event.setAttribute('netbios_name', ipInfo.get('netbiosName').split('\\')[-1])
        event.setAttribute('mac_address', ipInfo.get('macAddress'))
        try:
            if ipInfo.get('dnsName'):
                socket.inet_aton(ipInfo.get('dnsName'))
        except socket.error:
            event.setAttribute('hostname', ipInfo.get('dnsName').split('.')[0])
            event.setAttribute('fqdn', ipInfo.get('dnsName'))
            event.setAttribute('domain_name', ipInfo.get('dnsName').split('.', 1)[-1])
        event.setAttribute('sc_compliant', ipInfo.get('hasCompliance'))
        if ipInfo.get('lastScan'):
            event.setAttribute('sc_lastScan', epochToDatetime(ipInfo.get('lastScan')))
      
    vulns = sc.analysis(('ip','=', event.ip_address), ('severity','!=','0'), tool='vulndetails')
    
    
    if vulns:
        for vuln in vulns:
            if vuln['pluginID'] == '38689':
                event.setAttribute('username', vuln['pluginText'].split('Last Successful logon : ')[-1].split('<')[0])
                
        localAdmins = []
        for vuln in vulns:
            vuln['severity'] = vuln['severity']['id']
            vuln['repository'] = vuln['repository']['name']
            vuln['family'] = vuln['family']['name']

            if vuln['pluginID'] == '10902':
                localAdmins = [x.split('  - ')[-1] for x in vuln['pluginText'].split("'Administrators' group :<br/><br/>")[-1].split('</plugin_output')[0].split('<br/>') if x]
                
                if hasattr(event, 'username') and event.username:
                    if event.username.lower() in '\n'.join(localAdmins).lower():
                        event.setAttribute('local_admin', True, exceptional=True)
                    else:
                        event.setAttribute('local_admin', False)
    
        vulnerabilities = []
        splunkVulnerabilities = []
        excluded = ['pluginText', 'description', 'solution', 'synopsis']
        for vuln in sorted(vulns, key=lambda v: int(v['severity']), reverse=True):
            
            splunkVulnerabilities.append(event.sc_lastScan.isoformat() + ' ' + ' '.join([k + '="' + v + '"' for k,v in sorted(vuln.iteritems()) if k not in excluded]))
                    
            if int(vuln['severity']) >= event._riskFactors[event.scSeverity.lower()]:
                vulnerabilities.append('%(ip)-16s%(riskFactor)-13s%(port)-6s%(pluginID)-12s%(pluginName)s' % vuln)
                
        printStatusMsg('Scan Details', 22, '-', color=colors.HEADER2)
        print('Last Scan: %s' % event.sc_lastScan.isoformat())
        print('SC Compliant: %s' % event.sc_compliant)
        printStatusMsg('Local Admins', 22, '-', color=colors.HEADER2)
        print('\n'.join(sorted(localAdmins)))
        printStatusMsg('Vulnerabilities', 22, '-', color=colors.HEADER2)
        print('%-16s%-13s%-6s%-12s%s' % ('IP', 'Risk Factor', 'Port', 'Plugin ID', 'Plugin Name'))
        print('-' * 80)
        print('\n'.join(vulnerabilities))
        
        if vulnerabilities:
            event._splunk.push(sourcetype=confVars.splunkSourcetype, eventList=splunkVulnerabilities)
            with open('%s.%s' % (event._baseFilePath, confVars.outputExtension), 'w') as outFile:
                outFile.writelines([x + '\n' for x in splunkVulnerabilities])
    else:
        print('Asset not found.')
예제 #25
0
def execute(event):
    
    for server in [x.strip() for x in epoServers.split(',')]:
        print('Checking ePO (%s)...' % server)
        epoURL = 'https://%s/remote/system.find?searchText=%s' % (server, event.ip_address)

        passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
        
        passman.add_password(None, epoURL, event.epoUser, event.epoPassword)

        authhandler = urllib2.HTTPBasicAuthHandler(passman)

        opener = urllib2.build_opener(authhandler)

        urllib2.install_opener(opener)

        try:
            result = urllib2.urlopen(epoURL)
        except(urllib2.HTTPError):
            log.warn('Warning: HTTPError returned from ePO server, skipping...')
            log.debug('msg="HTTPError returned from ePO server, skipping" server="%s"' % server)
            return

        #print('curl -k -u %s:%s https://%s/remote/system.find?searchText=%s' % (event.epoUser, event.epoPassword, server, event.ip_address))
        #result = runBash('curl -k -u %s:%s https://%s/remote/system.find?searchText=%s' % (event.epoUser, event.epoPassword, server, event.ip_address))
        sresult = None
        if result:
            rawResult = result.read()
            if re.match("OK:", rawResult) and len(rawResult.splitlines()) > 3:
                entries = rawResult.split('\r\n\r\n')
                for entry in entries:
                    if re.search(event.ip_address.replace('.', '\.') + '\s', entry):
                        sresult = entry.splitlines()
                        break
        if sresult:
            break                                     
        
    if sresult:
        resDict = {}
        for r in sresult:
            if len(r.split(':', 1)) == 2:
                key, val = r.split(':', 1)
                resDict[key] = val.lstrip()

        event.setAttribute('hostname', resDict['System Name'].lower())
        event.setAttribute('domain_name', resDict['Domain Name'].lower())
        if resDict['User Name'] != 'N/A':
            event.setAttribute('username', resDict['User Name'])
        
        mac = ''
        for i, digit in enumerate(resDict['MAC Address'].lower()):
            if i and not i%2:
                mac += ':'
            mac += digit
            
        event.setAttribute('mac_address', mac)
        event.setAttribute('operating_system', resDict['OS Type'])
        event.setAttribute('system_location', resDict['System Location'])
        event.setAttribute('fqdn', resDict['DNS Name'].lower())
        
        if int(resDict['Is Laptop']):
            resDict['Is Laptop'] = 'True'
        else:
            resDict['Is Laptop'] = 'False'
        
        resDict['Tags'] = ','.join([x for x in resDict['Tags'].split(',') if 'Deploy' not in x])
        
        printStatusMsg('Informational Details', length=20, char='-', color=colors.HEADER2)

        for info in ['Description', 'System Description', 'Is Laptop', 'Tags', 'Time Zone', 'Last Communication']:
            print "%s -- %s" % (info, resDict[info])
    else:
        print 'nada'
예제 #26
0
def checkStackTraces(event):
    if event._stackTraces:
        printStatusMsg("  Fatal Data Source Errors Detected", 20, "@ ", color=colors.WARNING)
        for st in event._stackTraces:
            printStatusMsg(colors.GREY + st + colors.ENDC, 20, "-", color=colors.FAIL)