/analyzers/Maltiverse/maltiverse-client.py

https://github.com/TheHive-Project/Cortex-Analyzers · Python · 150 lines · 130 code · 13 blank · 7 comment · 25 complexity · 00faf72fa9140229ade1819ec355c046 MD5 · raw file

  1. #!/usr/bin/env python3
  2. # encoding: utf-8
  3. import sys
  4. import time
  5. import hashlib
  6. import urllib
  7. from cortexutils.analyzer import Analyzer
  8. from maltiverse import Maltiverse
  9. class MaltiverseAnalyzer(Analyzer):
  10. def __init__(self):
  11. Analyzer.__init__(self)
  12. self.service = self.get_param('config.service', None, 'Service parameter is missing')
  13. # self.username = self.get_param('config.username', None, 'Missing Maltiverse API Username')
  14. # self.password = self.get_param('config.password', None, 'Missing Maltiverse API Password')
  15. self.polling_interval = self.get_param('config.polling_interval', 60)
  16. self.proxies = self.get_param('config.proxy', None)
  17. self.m = Maltiverse()
  18. def maltiverse_query_ip(self, data):
  19. try:
  20. result = self.m.ip_get(data)
  21. self.report({
  22. 'registrant_name': result.get("registrant_name","-"),
  23. 'last_updated': result.get("last_updated","-"),
  24. 'asn_registry': result.get("asn_registry","-"),
  25. 'classification': result.get("classification","-"),
  26. 'asn_country_code': result.get("asn_country_code","-"),
  27. 'creation_time': result.get("creation_time","-"),
  28. 'visits': result.get("visits","-"),
  29. 'blacklist': result.get("blacklist","-"),
  30. 'asn_date': result.get("asn_date","-"),
  31. 'modification_time': result.get("modification_time","-"),
  32. 'asn_cidr': result.get("asn_cidr","-"),
  33. 'location': result.get("location","-"),
  34. 'country_code': result.get("country_code","-"),
  35. 'address': result.get("address","-"),
  36. 'ip_addr': result.get("ip_addr","-"),
  37. 'cidr': result.get("cidr","-"),
  38. 'tag': result.get("tag","-"),
  39. 'type': result.get("type","-"),
  40. 'email': result.get("email","-")
  41. })
  42. except Exception:
  43. self.error('API Error! Please verify data type is correct.')
  44. def maltiverse_query_domain(self, data):
  45. try:
  46. result = self.m.hostname_get(data)
  47. self.report({
  48. 'domain': result.get("domain","-"),
  49. 'classification': result.get("classification","-"),
  50. 'hostname': result.get("hostname","-"),
  51. 'creation_time': result.get("creation_time","-"),
  52. 'domain_lenght': result.get("domain_lenght","-"),
  53. 'resolved_ip': result.get("resolved_ip","-"),
  54. 'modification_time': result.get("modification_time","-"),
  55. 'domain_consonants': result.get("domain_consonants","-"),
  56. 'visits': result.get("visits","-"),
  57. 'tld': result.get("tld","-"),
  58. 'entropy': result.get("entropy","-"),
  59. 'type': result.get("type","-"),
  60. 'as_name': result.get("as_name","-")
  61. })
  62. except Exception:
  63. self.error('API Error! Please verify data type is correct.')
  64. def maltiverse_query_file(self, data):
  65. try:
  66. result = self.m.sample_get(data)
  67. self.report(result)
  68. except Exception:
  69. self.error('API Error! Please verify data type is correct.')
  70. def maltiverse_query_url(self, data):
  71. # urlencode the URL that we are searching for
  72. #data = urllib.quote_plus(data)
  73. try:
  74. result = self.m.url_get(data)
  75. self.report({
  76. 'original': data,
  77. 'hash': hash,
  78. 'url': result.get("url","-"),
  79. 'type': result.get("type","-"),
  80. 'classification': result.get("classification","-"),
  81. 'tag': result.get("tag","-"),
  82. 'blacklist': result.get("blacklist","-"),
  83. 'creation_time': result.get("creation_time","-"),
  84. 'modification_time': result.get("modification_time","-")
  85. })
  86. except:
  87. self.error('API Error! Please verify data type is correct.')
  88. def summary(self, raw):
  89. taxonomies = []
  90. level = "info"
  91. namespace = "Maltiverse"
  92. predicate = "Report"
  93. value = "{}".format("n/a")
  94. if "classification" in raw:
  95. if raw["classification"] == "malicious":
  96. level = "malicious"
  97. elif raw["classification"] == "suspicious":
  98. level = "suspicious"
  99. else:
  100. level = "safe"
  101. value = "{}".format(raw["classification"])
  102. taxonomies.append(self.build_taxonomy(level, namespace, predicate, value))
  103. return {"taxonomies": taxonomies}
  104. def run(self):
  105. Analyzer.run(self)
  106. if self.data_type == 'file':
  107. hashes = self.get_param('attachment.hashes', None)
  108. if hashes is None:
  109. filepath = self.get_param('file', None, 'File is missing')
  110. sha256 = hashlib.sha256()
  111. with io.open(filepath, 'rb') as fh:
  112. while True:
  113. data = fh.read(4096)
  114. if not data:
  115. break
  116. sha256.update(data)
  117. hash = sha256.hexdigest()
  118. else:
  119. # find SHA256 hash
  120. hash = next(h for h in hashes if len(h) == 64)
  121. self.maltiverse_query_file(hash)
  122. elif self.data_type == 'url':
  123. data = self.get_param('data', None, 'Data is missing')
  124. self.maltiverse_query_url(data)
  125. elif self.data_type == 'domain':
  126. data = self.get_param('data', None, 'Data is missing')
  127. self.maltiverse_query_domain(data)
  128. elif self.data_type == 'ip':
  129. data = self.get_param('data', None, 'Data is missing')
  130. self.maltiverse_query_ip(data)
  131. elif self.data_type == 'hash':
  132. data = self.get_param('data', None, 'Data is missing')
  133. self.maltiverse_query_file(data)
  134. else:
  135. self.error('Invalid data type')
  136. if __name__ == '__main__':
  137. MaltiverseAnalyzer().run()