Files
securityonion/salt/sensoroni/files/analyzers/threatfox/threatfox.py
2025-08-21 11:47:54 -05:00

94 lines
2.9 KiB
Python

import requests
import helpers
import json
import sys
import argparse
import os
def buildReq(observ_type, observ_value):
# supports hash, ip, and domain. determines which query type to send.
if observ_type == 'hash':
qterms = {'query': 'search_hash', 'hash': observ_value}
elif observ_type == 'ip' or observ_type == 'domain':
qterms = {'query': 'search_ioc', 'search_term': observ_value}
return qterms
def checkConfigRequirements(conf):
if not conf.get('api_key'):
sys.exit(126)
else:
return True
def sendReq(conf, meta, query):
# send a post request based off of our compiled query
url = meta['baseUrl']
headers = {}
if conf.get('api_key'):
headers['Auth-Key'] = conf['api_key']
response = requests.post(url, json.dumps(query), headers=headers)
return response.json()
def prepareResults(raw):
# gauge threat level based off of threatfox's confidence level
if raw != {} and raw['query_status'] == 'ok':
parsed = raw['data'][0]
# get summary
if parsed['threat_type'] != '':
summary = parsed['threat_type']
else:
summary = parsed['threat_type_desc']
if parsed['confidence_level'] > 75:
status = 'threat'
elif parsed['confidence_level'] > 50:
status = 'caution'
elif parsed['confidence_level'] > 25:
status = 'info'
else:
status = 'ok'
elif raw != {} and raw['query_status'] in ['no_result', 'illegal_search_term', 'illegl_hash']:
status = 'info'
summary = 'no result'
else:
raw = {}
status = 'caution'
summary = 'internal_failure'
results = {'response': raw, 'summary': summary, 'status': status}
return results
def analyze(conf, input):
# put all of our methods together, pass them input, and return
# properly formatted json/python dict output
checkConfigRequirements(conf)
meta = helpers.loadMetadata(__file__)
data = helpers.parseArtifact(input)
helpers.checkSupportedType(meta, data["artifactType"])
query = buildReq(data['artifactType'], data['value'])
response = sendReq(conf, meta, query)
return prepareResults(response)
def main():
dir = os.path.dirname(os.path.realpath(__file__))
parser = argparse.ArgumentParser(
description='Search ThreatFox for a given artifact')
parser.add_argument(
'artifact', help='the artifact represented in JSON format')
parser.add_argument('-c', '--config', metavar='CONFIG_FILE', default=dir + '/threatfox.yaml',
help='optional config file to use instead of the default config file')
args = parser.parse_args()
if args.artifact:
results = analyze(helpers.loadConfig(args.config), args.artifact)
print(json.dumps(results))
if __name__ == '__main__':
main()