mirror of https://github.com/MISP/PyMISP
				
				
				
			
		
			
				
	
	
		
			204 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			Python
		
	
	
			
		
		
	
	
			204 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			Python
		
	
	
import requests
 | 
						|
from requests.auth import HTTPBasicAuth
 | 
						|
import json
 | 
						|
from pymisp import ExpandedPyMISP, MISPEvent
 | 
						|
from keys import misp_url, misp_key, misp_verifycert, proofpoint_sp, proofpoint_secret
 | 
						|
import urllib3
 | 
						|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
 | 
						|
 | 
						|
if proofpoint_secret == '<proofpoint secret>':
 | 
						|
    print('Set the proofpoint_secret in keys.py before running.  Exiting...')
 | 
						|
    quit()
 | 
						|
 | 
						|
# initialize PyMISP and set url for Panorama
 | 
						|
misp = ExpandedPyMISP(url=misp_url, key=misp_key, ssl=misp_verifycert)
 | 
						|
 | 
						|
urlSiem = "https://tap-api-v2.proofpoint.com/v2/siem/all"
 | 
						|
 | 
						|
alertType = ("messagesDelivered", "messagesBlocked", "clicksPermitted", "clicksBlocked")
 | 
						|
 | 
						|
# max query is 1h, and we want Proofpoint TAP api to return json
 | 
						|
queryString = {
 | 
						|
    "sinceSeconds": "3600",
 | 
						|
    "format": "json"
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
responseSiem = requests.request("GET", urlSiem,  params=queryString, auth=HTTPBasicAuth(proofpoint_sp, proofpoint_secret))
 | 
						|
if 'Credentials authentication failed' in responseSiem.text:
 | 
						|
    print('Credentials invalid, please edit keys.py and try again')
 | 
						|
    quit()
 | 
						|
 | 
						|
jsonDataSiem = json.loads(responseSiem.text)
 | 
						|
 | 
						|
for alert in alertType:
 | 
						|
    for messages in jsonDataSiem[alert]:
 | 
						|
        # initialize and set MISPEvent()
 | 
						|
        event = MISPEvent()
 | 
						|
        if alert == "messagesDelivered" or alert == "messagesBlocked":
 | 
						|
            if alert == "messagesDelivered":
 | 
						|
                event.info = alert
 | 
						|
                event.distribution = 0  # Optional, defaults to MISP.default_event_distribution in MISP config
 | 
						|
                event.threat_level_id = 2  # setting this to 0 breaks the integration 
 | 
						|
                event.analysis = 0  # Optional, defaults to 0 (initial analysis)
 | 
						|
            else:
 | 
						|
                event.info = alert
 | 
						|
                event.distribution = 0  # Optional, defaults to MISP.default_event_distribution in MISP config
 | 
						|
                event.threat_level_id = 2  # BLOCKED = LOW
 | 
						|
                event.analysis = 0  # Optional, defaults to 0 (initial analysis)
 | 
						|
 | 
						|
            recipient = event.add_attribute('email-dst', messages["recipient"][0])
 | 
						|
            recipient.comment = 'recipient address'
 | 
						|
 | 
						|
            sender = event.add_attribute('email-src', messages["sender"])
 | 
						|
            sender.comment = 'sender address'
 | 
						|
 | 
						|
            if messages["fromAddress"] is not None and messages["fromAddress"] != "" :
 | 
						|
                fromAddress = event.add_attribute('email-src-display-name', messages["fromAddress"])
 | 
						|
 | 
						|
            headerFrom = event.add_attribute('email-header', messages["headerFrom"])
 | 
						|
            headerFrom.comment = 'email header from'
 | 
						|
 | 
						|
            senderIP = event.add_attribute('ip-src', messages["senderIP"])
 | 
						|
            senderIP.comment = 'sender IP'
 | 
						|
 | 
						|
            subject = event.add_attribute('email-subject', messages["subject"])
 | 
						|
            subject.comment = 'email subject'
 | 
						|
 | 
						|
            if messages["quarantineFolder"] is not None and messages["quarantineFolder"] != "":
 | 
						|
                quarantineFolder = event.add_attribute('comment', messages["quarantineFolder"])
 | 
						|
                quarantineFolder.comment = 'quarantine folder'
 | 
						|
 | 
						|
            if messages["quarantineRule"] is not None and messages["quarantineRule"] != "":
 | 
						|
                quarantineRule = event.add_attribute('comment', messages["quarantineRule"])
 | 
						|
                quarantineRule.comment = 'quarantine rule'
 | 
						|
 | 
						|
            messageSize = event.add_attribute('size-in-bytes', messages["messageSize"])
 | 
						|
            messageSize.comment = 'size of email in bytes'
 | 
						|
 | 
						|
            malwareScore = event.add_attribute('comment', messages["malwareScore"])
 | 
						|
            malwareScore.comment = 'malware score'
 | 
						|
 | 
						|
            phishScore = event.add_attribute('comment', messages["phishScore"])
 | 
						|
            phishScore.comment = 'phish score'
 | 
						|
 | 
						|
            spamScore = event.add_attribute('comment', messages["spamScore"])
 | 
						|
            spamScore.comment = 'spam score'
 | 
						|
 | 
						|
            imposterScore = event.add_attribute('comment', messages["impostorScore"])
 | 
						|
            imposterScore.comment = 'impostor score'
 | 
						|
 | 
						|
            completelyRewritten = event.add_attribute('comment', messages["completelyRewritten"])
 | 
						|
            completelyRewritten.comment = 'proofpoint url defense'
 | 
						|
 | 
						|
            # grab the threat info for each message in TAP
 | 
						|
            for threatInfo in messages["threatsInfoMap"]:
 | 
						|
                threat_type = {
 | 
						|
                    "url": "url",
 | 
						|
                    "attachment": "email-attachment",
 | 
						|
                    "message": "email-body"
 | 
						|
                }
 | 
						|
 | 
						|
                threat = event.add_attribute(threat_type.get(threatInfo["threatType"]), threatInfo["threat"])
 | 
						|
                threat.comment = 'threat'
 | 
						|
 | 
						|
                threatUrl = event.add_attribute('link', threatInfo["threatUrl"])
 | 
						|
                threatUrl.comment = 'link to threat in TAP'
 | 
						|
 | 
						|
                threatStatus = event.add_attribute('comment', threatInfo["threatStatus"])
 | 
						|
                threatStatus.comment = "proofpoint's threat status"
 | 
						|
 | 
						|
                event.add_tag(threatInfo["classification"])
 | 
						|
 | 
						|
                # get campaignID from each TAP alert and query campaign API
 | 
						|
                if threatInfo["campaignID"] is not None and threatInfo["campaignID"] != "":
 | 
						|
                    urlCampaign = "https://tap-api-v2.proofpoint.com/v2/campaign/" + threatInfo["campaignID"]
 | 
						|
                    responseCampaign = requests.request("GET", urlCampaign, auth=HTTPBasicAuth(proofpoint_sp, proofpoint_secret))
 | 
						|
 | 
						|
                    jsonDataCampaign = json.loads(responseCampaign.text)
 | 
						|
 | 
						|
                    campaignType = ("actors", "families", "malware", "techniques")
 | 
						|
 | 
						|
                    # loop through campaignType and grab tags to add to MISP event
 | 
						|
                    for tagType in campaignType:
 | 
						|
                        for tag in jsonDataCampaign[tagType]:
 | 
						|
                            event.add_tag(tag['name'])
 | 
						|
 | 
						|
            # grab which policy route the message took
 | 
						|
            for policy in messages["policyRoutes"]:
 | 
						|
                policyRoute = event.add_attribute('comment', policy)
 | 
						|
                policyRoute.comment = 'email policy route'
 | 
						|
 | 
						|
            # was the threat in the body of the email or is it an attachment?
 | 
						|
            for parts in messages["messageParts"]:
 | 
						|
                disposition = event.add_attribute('comment', parts["disposition"])
 | 
						|
                disposition.comment = 'email body or attachment'
 | 
						|
 | 
						|
                # sha256 hash of threat
 | 
						|
                if parts["sha256"] is not None and parts["sha256"] != "":
 | 
						|
                    sha256 = event.add_attribute('sha256', parts["sha256"])
 | 
						|
                    sha256.comment = 'sha256 hash'
 | 
						|
 | 
						|
                # md5 hash of threat
 | 
						|
                if parts["md5"] is not None and parts["md5"] != "":
 | 
						|
                    md5 = event.add_attribute('md5', parts["md5"])
 | 
						|
                    md5.comment = 'md5 hash'
 | 
						|
 | 
						|
                # filename of threat
 | 
						|
                if parts["filename"] is not None and parts["filename"] != "":
 | 
						|
                    filename = event.add_attribute('filename', parts["filename"])
 | 
						|
                    filename.comment = 'filename'
 | 
						|
 | 
						|
            misp.add_event(event.to_json())
 | 
						|
 | 
						|
        if alert == "clicksPermitted" or alert == "clicksBlocked":
 | 
						|
            if alert == "clicksPermitted":
 | 
						|
                print(alert + " is a permitted click")
 | 
						|
                event.info = alert
 | 
						|
                event.distribution = 0  # Optional, defaults to MISP.default_event_distribution in MISP config
 | 
						|
                event.threat_level_id = 2  # setting this to 0 breaks the integration
 | 
						|
                event.analysis = 0  # Optional, defaults to 0 (initial analysis)
 | 
						|
            else:
 | 
						|
                print(alert + " is a blocked click")
 | 
						|
                event.info = alert
 | 
						|
                event.distribution = 0  # Optional, defaults to MISP.default_event_distribution in MISP config
 | 
						|
                event.threat_level_id = 2  # BLOCKED = LOW
 | 
						|
                event.analysis = 0  # Optional, defaults to 0 (initial analysis)
 | 
						|
 | 
						|
            event.add_tag(messages["classification"])
 | 
						|
 | 
						|
            campaignId = event.add_attribute('campaign-id', messages["campaignId"][0])
 | 
						|
            campaignId.comment = 'campaignId'
 | 
						|
 | 
						|
            clickIP = event.add_attribute('ip-src', messages["clickIP"])
 | 
						|
            clickIP.comment = 'clickIP'
 | 
						|
 | 
						|
            clickTime = event.add_attribute('datetime', messages["clickTime"])
 | 
						|
            clickTime.comment = 'clicked threat'
 | 
						|
 | 
						|
            threatTime = event.add_attribute('datetime', messages["threatTime"])
 | 
						|
            threatTime.comment = 'identified threat'
 | 
						|
 | 
						|
            GUID = event.add_attribute('comment', messages["GUID"])
 | 
						|
            GUID.comment = 'PPS message ID'
 | 
						|
 | 
						|
            recipient = event.add_attribute('email-dst', messages["recipient"][0])
 | 
						|
            recipient.comment = 'recipient address'
 | 
						|
 | 
						|
            sender = event.add_attribute('email-src', messages["sender"])
 | 
						|
            sender.comment = 'sender address'
 | 
						|
 | 
						|
            senderIP = event.add_attribute('ip-src', messages["senderIP"])
 | 
						|
            senderIP.comment = 'sender IP'
 | 
						|
 | 
						|
            threatURL = event.add_attribute('link', messages["threatURL"])
 | 
						|
            threatURL.comment = 'link to threat in TAP'
 | 
						|
 | 
						|
            url = event.add_attribute('link', messages["url"])
 | 
						|
            url.comment = 'malicious url clicked'
 | 
						|
 | 
						|
            userAgent = event.add_attribute('user-agent', messages["userAgent"])
 | 
						|
 | 
						|
            misp.add_event(event.to_json())
 |