Exemplo n.º 1
0
 def setUp(self, **kwargs):
     provided_key = kwargs.get('api_key', '')
     if provided_key:
         self.api_key = provided_key
     else:
         self.api_key = ALIEN_API_APIKEY
     self.otx = OTXv2(self.api_key)
Exemplo n.º 2
0
def main():
	otx_settings = OTXSetting()
	otx = OTXv2(otx_settings.API_KEY)
	ip = sys.argv[1]

	general_result = otx.get_indicator_details_by_section(IndicatorTypes.IPv4, ip, 'general')
	found_pulse = getPulse(general_result)
	if found_pulse != '':
		m.addEntity("otx.OTXPulse", found_pulse)

	malware_result = otx.get_indicator_details_by_section(IndicatorTypes.IPv4, ip, 'malware')
	pdns_result = otx.get_indicator_details_by_section(IndicatorTypes.IPv4, ip, 'passive_dns')

	added_ips = 0
	if 'passive_dns' in pdns_result:
		for pdns in pdns_result['passive_dns']:
			added_ips +=1
			# Dont add too many IPs if fast flux etc
			if added_ips < 50:
				hostname = pdns['hostname']
				m.addEntity("maltego.Domain", hostname)

	if 'data' in malware_result:
		for malware in malware_result['data']:
			hash = malware['hash']
			m.addEntity("maltego.Hash", hash)
	return
Exemplo n.º 3
0
def get_otx_data(indicator, ind_type, otx_api_key):
    data={'av_general':'n/a','av_reputation':'n/a','av_malware_data':'n/a','av_url_data':'n/a','av_passive_data':'n/a','av_pulse_count':'0','av_tlp':'n/a'}
    if otx_api_key:
        try:
            otx = OTXv2(otx_api_key)
            indicator_details=None
            if ind_type=='md5':
                indicator_details = otx.get_indicator_details_full(IndicatorTypes.FILE_HASH_MD5, indicator)
            elif ind_type=='sha256':
                indicator_details = otx.get_indicator_details_full(IndicatorTypes.FILE_HASH_SHA256, indicator)
            elif ind_type=='domain':    
                indicator_details = otx.get_indicator_details_full(IndicatorTypes.DOMAIN, indicator)
            elif ind_type=='ip':    
                indicator_details = otx.get_indicator_details_full(IndicatorTypes.IPv4, indicator)
            if indicator_details:
                data['av_general'] = str(indicator_details.get('general', {}))
                data['av_reputation'] =  str(indicator_details.get('reputation', {}).get('reputation'))
                data['av_malware_data'] = str(indicator_details.get('malware', {}).get('data'))
                data['av_url_data']= str(indicator_details.get('url_list', {}).get('url_list'))
                data['av_passive_data'] = str(indicator_details.get('passive_dns'))
                data['av_pulse_count'] = str(indicator_details.get('general', {}).get('pulse_info', {}).get('count'))
                if indicator_details.get('analysis', {}).get('analysis'):
                    data['av_tlp'] = str(indicator_details.get('analysis', {}).get('analysis', {}).get('metadata',{}).get('tlp'))

        except Exception as err:
            print ('OTX error for indicator {}: {}'.format(indicator, traceback.format_exception(type(err), err, err.__traceback__)))
        
    return data
Exemplo n.º 4
0
def main():
    otx_settings = OTXSetting()
    otx = OTXv2(otx_settings.API_KEY)
    hash = sys.argv[1]

    indicator_type = IndicatorTypes.FILE_HASH_SHA256
    if len(hash) == 40:
        indicator_type = IndicatorTypes.FILE_HASH_SHA1
    if len(hash) == 32:
        indicator_type == IndicatorTypes.FILE_HASH_MD5

    general_result = otx.get_indicator_details_by_section(
        indicator_type, hash, 'general')
    found_pulse = getPulse(general_result)
    if found_pulse != '':
        m.addEntity("otx.OTXPulse", found_pulse)

    analysis_result = otx.get_indicator_details_by_section(
        indicator_type, hash, 'analysis')
    try:
        domainsJ = analysis_result['analysis']['plugins']['cuckoo']['result'][
            'network']['domains']
        for dns in domainsJ:
            # { 'ip': '', 'domain': '' }
            if len(str(dns).split("'")) > 6:
                domain = str(dns).split("'")[7]
                ip = str(dns).split("'")[3]
                m.addEntity("maltego.IPv4Address", ip)
                m.addEntity("maltego.Domain", domain)
    except Exception as ex:
        pass

    return
Exemplo n.º 5
0
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.otx = OTXv2(OTX_API_KEY, OTX_SERVER)
     self.alerts = []
     self.results = []
     self.entity_num = 0
     self.outfile_dic = {}
Exemplo n.º 6
0
def main():

    otx_settings = OTXSetting()
    otx = OTXv2(otx_settings.API_KEY)

    command_line = " ".join(sys.argv[:])
    if 'ID:' in command_line:
        pulse_id = command_line.split('ID:')[1]
        if ' ' in pulse_id:
            pulse_id = pulse_id.split(' ')[0]
        pulse_indicators = otx.get_pulse_indicators(pulse_id)

        for ind in pulse_indicators:
            indicator = ind['indicator']
            if 'FileHash' in ind['type']:
                m.addEntity("maltego.Hash", indicator)
            if ind['type'] == 'domain' or ind['type'] == 'hostname':
                m.addEntity("maltego.Domain", indicator)
            if ind['type'] == 'IPv4':
                m.addEntity("maltego.IPv4Address", indicator)

        url = 'https://otx.alienvault.com/api/v1/pulses/' + pulse_id + '/related/'
        result = requests.get(url).content
        j = json.loads(result)

        if 'results' in j:
            for pulse in j['results']:
                pulse_author = pulse['author']['username']
                if pulse_author == 'AlienVault':
                    pulse_id = pulse['id']
                    pulse_title = pulse['name'] + ' ID:' + pulse_id
                    m.addEntity("otx.OTXPulse", pulse_title)

    return
Exemplo n.º 7
0
 def __init__(self):
     self.otx = OTXv2 ("Enter OTX key here")
     self.vt_api = 'Enter VT API key here'
     self.ipdb = AbuseIPDB ('Enter AbuseIPDB key Here')
     self.user = '******'
     self.password = '******'
     self.vt_base_url = 'https://www.virustotal.com/'
Exemplo n.º 8
0
 def connect(self, params):
     api_key, otx_server = params.get(Input.API_KEY).get(
         "secretKey", None), params.get(Input.URL)
     try:
         self.client = OTXv2(api_key, server=otx_server)
     except Exception as e:
         raise Exception(f"An error has occurred while connecting: {e}")
Exemplo n.º 9
0
def sendTAXII(first=True):

    config = ConfigParser.ConfigParser()
    config.read('config.cfg')
    otx = OTXv2(config.get('otx', 'key'))

    if first:
        pulses = otx.getall_iter()
        mtimestamp = None
    else:
        mtimestamp = readTimestamp()
        pulses = otx.getsince(mtimestamp)

    if pulses:
        client = Client()
        client.from_dict(dict(config.items('taxii')))

        for pulse in pulses:
            if not mtimestamp:
                mtimestamp = pulse["modified"]
            st = StixExport(pulse)
            st.build()
            print "Sending %s" % pulse["name"]

            if not client.snd_post('inbox', st.to_xml()):
                print '######---[ Unable to Send Post ]---######'

        saveTimestamp(mtimestamp)
        print "%d new pulses" % len(pulses)
Exemplo n.º 10
0
 def checkip(request):
     if request.method == "POST":
         ip = request.POST.get('ip', False)
         user = User.objects.get(username=request.session["username"])
     otx = OTXv2(
         "cee9c5f59ddad6f61aead25b961fb1ca6060bee6157137f95a868d5bb0c842e7")
     re = otx.get_indicator_details_full(IndicatorTypes.IPv4, ip)
     response = requests.get(
         'https://otx.alienvault.com/api/v1/indicators/IPv4/' + ip +
         '/http_scans')
     http_scan = response.json()
     response2 = requests.get(
         'https://otx.alienvault.com/api/v1/indicators/IPv4/' + ip +
         '/passive_dns')
     passive_dns = response2.json()
     response3 = requests.get(
         'https://otx.alienvault.com/api/v1/indicators/IPv4/' + ip +
         '/malware')
     malware = response3.json()
     if len(http_scan) == 1:
         http_scan = None
     req = Requete(type='ip', date=date.today(), name=ip, user=user)
     req.save()
     return render(
         request, 'services/checkip.html', {
             'general': re['general'],
             'url_list': re['url_list']['url_list'],
             'passive_dns': passive_dns['passive_dns'],
             'http_scan': http_scan,
             'malware': malware['data']
         })
Exemplo n.º 11
0
 def Search(self):
     display(self.module_name, self.ioc, "INFO", "Search in Alienvault...")
     try:
         if "otx_api_keys" in self.config:
             otx = OTXv2(self.config["otx_api_keys"])
             if self.type == "IPv4":
                 indicator = IndicatorTypes.IPv4
             if self.type == "IPv6":
                 indicator = IndicatorTypes.IPv6
             if self.type == "domain":
                 indicator = IndicatorTypes.DOMAIN
             if self.type == "URL":
                 indicator = IndicatorTypes.URL
             if self.type == "MD5":
                 indicator = IndicatorTypes.FILE_HASH_MD5
             if self.type == "SHA1":
                 indicator = IndicatorTypes.FILE_HASH_SHA1
             if self.type == "SHA256":
                 indicator = IndicatorTypes.FILE_HASH_SHA256
             result = otx.get_indicator_details_full(indicator, self.ioc)
         else:
             display(
                 self.module_name,
                 message_type="ERROR",
                 string=
                 "Please check if you have otx_api_keys field in config.ini"
             )
     except Exception, e:
         display(self.module_name, self.ioc, "ERROR", e)
         return
Exemplo n.º 12
0
def getPulseData():
    logging.info('Querying AlienVault OTX for recent pulses...')

    otx = OTXv2(baseConfig.otxKey)

    days_back = int(baseConfig.osintDays) + 1
    date_since = (datetime.datetime.now() -
                  datetime.timedelta(days=days_back)).isoformat()
    pulses = otx.getsince(date_since, limit=None)

    ip_list = []
    domain_list = []
    url_list = []

    for pulse in pulses:
        indicators = pulse['indicators']

        if len(indicators) > 0:
            for indicator in indicators:
                if indicator['type'] == 'URL':
                    url_list.append(indicator['indicator'])

                host_indicators = ['domain', 'hostname', 'IPv4']

                if indicator['type'] in host_indicators:
                    if isValidIP(indicator['indicator']):
                        ip_list.append(indicator['indicator'])

                    else:
                        domain_list.append(indicator['indicator'])

    return ip_list, domain_list, url_list
Exemplo n.º 13
0
def get_iocs(today):
   dic = []
   cprint("\nCollecting iocs for the date : "+str(today)+"..This may take sometime depending on your network speed..",'yellow', attrs=['bold'])
   otx = OTXv2("758fe3198bde37e69611027cc1e90ed40d796aaaf7f6bf71470a5e6586eaf9a8")
   iocs = {}
   pulses = otx.getall()
   
   file = open('./OTX_IoCs.csv'+str(today),'w')
   for each in pulses:
       pulsedate=each['created'].split('T')[0] 
       if (pulsedate==today):
           dic.append(each)
   for each in dic:
      for ioc in each['indicators']:
         iocs['IOC']=str(ioc['indicator'])
         iocs['IOC_Created']=str(ioc['created'])
         iocs['Title']=ioc['title']
         iocs['Is_active_(0/1)_?']=str(ioc['is_active'])
         iocs['Type']=ioc['type']
         iocs['Tags']=','.join(each['tags'])
         iocs['Pulse_Created']=str(each['created'])
         iocs['Malware_Families']=','.join(each['malware_families'])
         iocs['References']=' '.join(each['references'])
         iocs['Targeted_Countries']=','.join(each['targeted_countries'])
         iocs['Industries']=','.join(each['industries'])
         writer = csv.DictWriter(file, iocs.keys())
         if file.tell() == 0:
            writer.writeheader()
         for data in iocs:
            writer.writerow(iocs)
Exemplo n.º 14
0
def check_api_key_state(args):
    print("=" * 80)
    print("Now checking api key is valid or not...")
    
    test_ip = "8.8.8.8"
    
    if args.virustotal == False:
        OTX_SERVER = 'https://otx.alienvault.com/'
        otx = OTXv2(alienvault_api_key, server=OTX_SERVER)
        try:
            result = otx.get_indicator_details_by_section(IndicatorTypes.IPv4, test_ip, 'general')
            print("Your alienVault API Key is valid.")
            return True     
        except:
            print("Your alienVault API Key is Invalid, Please check")
            return False 
        
    elif args.virustotal == True:
        url = 'https://www.virustotal.com/vtapi/v2/ip-address/report'
        params = {'apikey':virus_total_api_key,'ip': test_ip}
        response = requests.get(url, params=params)
    
        try:
            result = response.json()
            print("Your virustotal API Key is valid.")
            return True
        except:
            print("Your virustotal API Key is Invalid, Please check")
            return False
Exemplo n.º 15
0
def get_malicious_ip_and_country():
    sample_file_names = os.listdir(has_behavior_malware_dir)
    ip_country_dic = dict()

    for sample_file_name in sample_file_names:
        pcap_file_names = os.listdir(has_behavior_malware_dir +
                                     sample_file_name)
        for pcap_file_name in pcap_file_names:
            pcap_file_path = has_behavior_malware_dir + sample_file_name + "/" + pcap_file_name
            pcap = open_pcap(pcap_file_path)

            pkt_1 = pcap[0]
            malicious_ip = pkt_1[IP].dst

            if malicious_ip not in ip_country_dic.keys():
                OTX_SERVER = 'https://otx.alienvault.com/'
                otx = OTXv2(alienvault_api_key, server=OTX_SERVER)
                try:
                    result = otx.get_indicator_details_by_section(
                        IndicatorTypes.IPv4, malicious_ip, 'general')
                    country = result["country_code"]
                except:
                    country = "unknown"
                ip_country_dic[malicious_ip] = country

    return ip_country_dic
Exemplo n.º 16
0
def get_ti_from_OTX(ip, in_file_name, out_file_name, country, ti_type):
    mStr = ''
    ip_rep = 0
    pulses_names = ''
    res = ''
    try:
        if ti_type == 'ip':
            res = OTXv2(args.api_key_otx).get_indicator_details_full(
                IndicatorTypes.IPv4, ip)
            ip_rep = res['general']['reputation']
            print('IP rep: {0}'.format(ip_rep))
            # for malicious IPs, get pulse names
            if '1' in str(ip_rep):
                pulses_names = getPulseNames(
                    res['general']['pulse_info']['pulses'])
                print('IP: {0}\tIP Rep: {1}\tIP Pulses'.format(
                    ip, ip_rep, pulses_names))
        else:
            res = OTXv2(args.api_key_otx).search_pulses(ip)
            # res = OTXv2('0d89be741a69cb6cd8c3b56b0cd0d5ba9dedd0a9c0289b6148de9c3a3a3c2ba1').search_pulses(ip)
            if 'results' in res and len(res['results']) > 0:
                for result in res['results']:
                    pulses_names += result['name'] + ' ' + args.pulse_separator
                    # pulses_names += result['name'] + ' ' + '---'

                pulses_names = pulses_names.rstrip(' ' + args.pulse_separator)

        print(res)

    except Exception as e:
        rl_hit[0] = rl_hit[0] + 1
        print('Exception {0} occurred when fetching TI for IP {1} from OTX{2}'.
              format(e, ip, res))

    # write only malicious IPs to output file
    if '1' in str(ip_rep):
        mStr = str(pulses_names)

        add_to_malicious_ips(ip, mStr, type='otx')

        # put IP records in a separate file
        if is_ip_malicious(ip):
            put_ip_records_in_separate_file(ip, in_file_name, 'otx')

        print('\n\n\n')
        print('IP: {0}\t OTX TI Results: {1}'.format(ip, mStr))
        print('\n\n\n')
Exemplo n.º 17
0
 def __init__(self):
     try:
         api_key = config['AlienVault']['API_KEY']
     except KeyError as e:
         raise KeyError(
             "Failed to read configurations for AlienVault") from e
     self.otx = OTXv2(api_key)
     self.prev_request_time = 0
Exemplo n.º 18
0
    def process(self):
        self.logger.info("Downloading report through API")
        otx = OTXv2(self.parameters.api_key, proxy=self.parameters.https_proxy)
        pulses = otx.getall()
        self.logger.info("Report downloaded.")

        report = self.new_report()
        report.add("raw", json.dumps(pulses))
        self.send_message(report)
 def get_ics_pulses(self, api_key, siem_mode):
     #self.debug = debug
     self.otx = OTXv2(api_key)
     if siem_mode:
         self.separator = ","
         self.use_csv_header = True
         self.extension = "csv"
         self.hash_upper = True
         self.filename_regex_out = False
Exemplo n.º 20
0
 def __init__(self, api_key, siem_mode, debug, proxy):
     self.debug = debug
     self.otx = OTXv2(api_key, proxy)
     if siem_mode:
         self.separator = ","
         self.use_csv_header = True
         self.extension = "csv"
         self.hash_upper = True
         self.filename_regex_out = False
Exemplo n.º 21
0
def main():
    # Todo - Used?
    otx_settings = OTXSetting()
    otx = OTXv2(otx_settings.API_KEY)
    email = sys.argv[1]

    for domain in getDomains(email):
        m.addEntity("maltego.Domain", domain)

    return
Exemplo n.º 22
0
def Main(IPList, TicketID):
    conf = LoadConfig.Load()
    otx = OTXv2(conf["api_keys"]["AlienVaultAPI"])
    for IP in IPList:
        logging.info("[AlienVault] OTX Searching %s" % IP)
        result = pformat(
            otx.get_indicator_details_full(IndicatorTypes.IPv4, IP))

        otrs_functions.UpdateTicket("", "AlienVault OTX - %s Results" % IP,
                                    result, TicketID)
Exemplo n.º 23
0
 def threat_intelligence(self, ip):
     """
     威胁情报分析, 威胁情报平台采用OTX ,https://otx.alienvault.com/
     :return:
     """
     config = ConfigParser.ConfigParser()
     config.read('config/config.ini')
     otx_key = config.get('OTX_Token', 'key')
     otx = OTXv2(otx_key)
     otx_result = otx.get_indicator_details_full(IndicatorTypes.IPv4, ip)
     print(otx_result)
Exemplo n.º 24
0
 def update_credentials(self):
     try:
         credentials = db.session.query(ThreatIntelCredentials).filter(
             ThreatIntelCredentials.intel_name == 'alienvault').first()
         if credentials and 'key' in credentials.credentials:
             self.otx = OTXv2(credentials.credentials['key'])
             current_app.logger.info('AlienVault OTX  api  configured')
         else:
             self.otx = None
             current_app.logger.warn('AlienVault OTX  api not configured')
     except Exception as e:
         current_app.logger.error(e)
Exemplo n.º 25
0
 def Search(self):
     mod.display(self.module_name, "", "INFO",
                 "Search in Alienvault OTX ...")
     try:
         if "otx_api_keys" in self.config:
             otx = OTXv2(self.config["otx_api_keys"])
             if self.type == "IPv4":
                 indicator = IndicatorTypes.IPv4
             if self.type == "IPv6":
                 indicator = IndicatorTypes.IPv6
             if self.type == "domain":
                 indicator = IndicatorTypes.DOMAIN
             if self.type == "URL":
                 indicator = IndicatorTypes.URL
             if self.type == "MD5":
                 indicator = IndicatorTypes.FILE_HASH_MD5
             if self.type == "SHA1":
                 indicator = IndicatorTypes.FILE_HASH_SHA1
             if self.type == "SHA256":
                 indicator = IndicatorTypes.FILE_HASH_SHA256
             result = otx.get_indicator_details_full(indicator, self.ioc)
         else:
             mod.display(
                 self.module_name,
                 self.ioc,
                 message_type="ERROR",
                 string=
                 "Please check if you have otx_api_keys field in btg.cfg")
             return None
     except:
         mod.display(
             self.module_name, self.ioc, "ERROR",
             "Could not perform the request, either you did not fill the otx_api_keys field or the key maximum request is reached"
         )
         return None
     try:
         if self.ioc == str(result["general"]["indicator"]):
             _id = str(result["general"]["pulse_info"]["pulses"][0]["id"])
             tags = ""
             for tag in result["general"]["pulse_info"]["pulses"][0][
                     "tags"]:
                 tags = tags + "%s " % tag
             mod.display(
                 self.module_name, self.ioc, "FOUND",
                 "Tags: %s| https://otx.alienvault.com/pulse/%s/" %
                 (tags, _id))
     except:
         mod.display(self.module_name,
                     self.ioc,
                     message_type="NOT_FOUND",
                     string="Nothing found in OTX")
     return None
Exemplo n.º 26
0
    def process(self):
        self.logger.info("Downloading report through API")
        otx = OTXv2(self.parameters.api_key)
        pulses = otx.getall()
        self.logger.info("Report downloaded.")

        report = Report()
        report.add("raw", json.dumps(pulses), sanitize=True)
        report.add("feed.name", self.parameters.feed, sanitize=True)
        report.add("feed.accuracy", self.parameters.accuracy, sanitize=True)
        time_observation = DateTime().generate_datetime_now()
        report.add('time.observation', time_observation, sanitize=True)
        self.send_message(report)
Exemplo n.º 27
0
def mainalv(ip,url):
    """
    mainalv is managing alienvault api configuration and call api for IP or api for url. return a string in markdown style.
    :param ip:ip from user
    :param url:url from user
    """

    from OTXv2 import OTXv2
    import IndicatorTypes


    ############# API config #############
    # ---- Retrieving API Key ----    
    file = open('api_keys.txt', "r")
    for line in file:
        line=line.strip() #Removal of empty lines  
        if (line.find('api_key_alienvault') != -1):
            api_key_alienvault=line.partition('=')[2]
    file.close()
    OTX_SERVER = 'https://otx.alienvault.com/'
    otx = OTXv2(api_key_alienvault, server=OTX_SERVER)

    ############# String title #############
    stringalv = "##AlienVault"

    ############# IP #############
    if ip != None:
        alerts = ipalv(otx, ip, IndicatorTypes)
        if len(alerts) > 0:
            stringalv = '\n'.join([stringalv, "* {} is identified as potentially malicious".format(ip)])
            stringalv = '\n'.join([stringalv, "* {} is in {} AlienVault alerts".format(ip,len(alerts))])
            stringalv = '\n'.join([stringalv, "* [AlienVault source link](https://otx.alienvault.io/indicator/ip/{})".format(ip)])
        else:
            stringalv = '\n'.join([stringalv, "* {} is not identified as malicious".format(ip)])
            stringalv = '\n'.join([stringalv, "* [AlienVault source link](https://otx.alienvault.io/indicator/ip/{})".format(ip)])

    ############# URL#############
    if url != None:
        alerts = urlalv(otx, url, IndicatorTypes)
        if len(alerts) > 0:
            stringalv = '\n'.join([stringalv, "* {} is identified as potentially malicious".format(url)])
            stringalv = '\n'.join([stringalv, "* {} is in {} AlienVault alerts".format(url,len(alerts))])
            stringalv = '\n'.join([stringalv, "* [AlienVault source link](https://otx.alienvault.io/indicator/url/{})".format(url)])
        else:
            stringalv = '\n'.join([stringalv, "* {} is not identified".format(url)])
            stringalv = '\n'.join([stringalv, "* [AlienVault source link](https://otx.alienvault.io/indicator/url/{})".format(url)])
        
    ############# Rating #############
    grade = rating(len(alerts))

    return stringalv, grade
Exemplo n.º 28
0
def main(api_key, start_date):

    goat = GoatJockey(topx=1000000)
    otx = OTXv2(api_key)

    interesting_iocs = set()

    for pulse in otx.getsince_iter(start_date):
        for indicator in pulse['indicators']:
            b = goat.match(indicator['indicator'])

            if not b[0]:
                interesting_iocs.add(indicator['indicator'])

    for ioc in interesting_iocs:
        print(ioc)
Exemplo n.º 29
0
    def process(self):
        self.logger.info("Downloading report through API.")
        otx = OTXv2(self.parameters.api_key, proxy=self.parameters.https_proxy)
        if self.modified_pulses_only:
            self.logger.info("Fetching only modified pulses.")
            interval = (datetime.datetime.now() -
                        datetime.timedelta(hours=self.interval)).isoformat()
            pulses = otx.getsince(interval, limit=9999)
        else:
            self.logger.info("Fetching all pulses.")
            pulses = otx.getall()
        self.logger.info("Report downloaded.")

        report = self.new_report()
        report.add("raw", json.dumps(pulses))
        self.send_message(report)
Exemplo n.º 30
0
def otx_run(misp):
    LOGGER.info('Setting up OTX connector...')
    try:
        otx = OTXv2(OTX_API_KEY)

    except Exception as ex:
        LOGGER.error('Failed to connect to OTX: {0}'.format(str(ex)))
        sys.exit(1)

    date_since = (datetime.utcnow() - timedelta(hours=HOURS_TO_CHECK)).isoformat()
    pulses = get_pulses(otx, date_since)

    if pulses:
        process_pulses(misp, pulses)

    LOGGER.info('Run complete!')