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
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('" "'))))
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 ""
def adhocInput(event): inputHeader = '%s Query Options' % FORMAL_NAME event.setOutPath() setPCAPRange(event) existingSensors = getSguilSensorList(sguilserver=confVars.so_server) choices = ['All'] choices.extend(existingSensors) selected = getUserMultiChoice("Available Sensors", 'Selection', choices, default=['All']) if 'All' in selected: event._selectedSensors = existingSensors else: event._selectedSensors = selected event.setAttribute('_pcapBPF', prompt='BPF', default="host ")
def playbookInput(event): inputHeader = '%s Query Options' % FORMAL_NAME event.setOutPath() setPCAPRange(event) existingSensors = getSguilSensorList(sguilserver=confVars.so_server) choices = ['All'] choices.extend(existingSensors) selected = getUserMultiChoice("Sensors to pull PCAPs.", 'Sensors', choices, default=['All']) if 'All' in selected: event._selectedSensors = existingSensors else: event._selectedSensors = selected event.setAttribute('_pcapBPF', prompt='BPF', default="host %s" % event.ip_address)
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
def playbookInput(event): inputHeader = '%s Query Options' % FORMAL_NAME event.setOutPath() event.setAttribute('ip_address', prompt="IP Address", header=inputHeader) event.setAttribute('scHostname', confVars.scHostname) if confVars.scPassword: event.setAttribute('scUser', confVars.scUser) event.setAttribute('scPassword', confVars.scPassword) else: event.setAttribute('scUser', prompt="SecurityCenter Username", header=inputHeader) event.setAttribute('scPassword', getpass()) event._riskFactors = {'critical': 4, 'high': 3, 'medium': 2, 'low': 1, 'info': 0} if event._adhoc: selectedRiskFactor = getUserMultiChoice('Lowest Risk Factor', 'Risk Factor', ['Critical', 'High', 'Medium', 'Low', 'Info'], 1, default=['High'], allowMultiple=False)[0] event.setAttribute('scSeverity', selectedRiskFactor) else: event.setAttribute('scSeverity', confVars.scSeverity.lower())
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])
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)