Example #1
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
Example #2
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)
Example #3
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])
Example #4
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
Example #5
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('" "'))))
        
Example #6
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        
Example #7
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))
Example #8
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
Example #9
0
 def toAddresses(self):
     return [x.strip() for x in getUserIn("To Address(es) '[email protected], [email protected]'").split(",")]
Example #10
0
 def fromAddress(self):
     return getUserIn("From Address [email protected]")
Example #11
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)
Example #12
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)