2018-06-08 16:38:41 +02:00
# -*- coding: utf-8 -*-
import json
2021-04-22 15:05:29 +02:00
2021-04-23 16:02:21 +02:00
from pymisp import MISPEvent , MISPObject
2021-04-22 15:05:29 +02:00
2018-06-08 16:38:41 +02:00
try :
from onyphe import Onyphe
except ImportError :
print ( " pyonyphe module not installed. " )
misperrors = { ' error ' : ' Error ' }
2018-12-11 15:29:09 +01:00
mispattributes = { ' input ' : [ ' ip-src ' , ' ip-dst ' , ' hostname ' , ' domain ' ] ,
2021-04-22 15:05:29 +02:00
' output ' : [ ' hostname ' , ' domain ' , ' ip-src ' , ' ip-dst ' , ' url ' ] ,
' format ' : ' misp_standard ' }
2018-06-08 16:38:41 +02:00
# possible module-types: 'expansion', 'hover' or both
2024-08-12 11:23:10 +02:00
moduleinfo = {
' version ' : ' 2 ' ,
' author ' : ' Sebastien Larinier @sebdraven ' ,
' description ' : ' Module to process a query on Onyphe. ' ,
' module-type ' : [ ' expansion ' , ' hover ' ] ,
' name ' : ' Onyphe Lookup ' ,
' logo ' : ' onyphe.jpg ' ,
' requirements ' : [ ' onyphe python library ' , ' An access to the Onyphe API (apikey) ' ] ,
' features ' : ' This module takes a domain, hostname, or IP address attribute as input in order to query the Onyphe API. Data fetched from the query is then parsed and MISP attributes are extracted. ' ,
' references ' : [ ' https://www.onyphe.io/ ' , ' https://github.com/sebdraven/pyonyphe ' ] ,
' input ' : ' A domain, hostname or IP address MISP attribute. ' ,
' output ' : ' MISP attributes fetched from the Onyphe query. ' ,
}
2018-06-08 16:38:41 +02:00
# config fields that your code expects from the site admin
moduleconfig = [ ' apikey ' ]
2021-04-22 15:05:29 +02:00
class OnypheClient :
def __init__ ( self , api_key , attribute ) :
self . onyphe_client = Onyphe ( api_key = api_key )
self . attribute = attribute
self . misp_event = MISPEvent ( )
self . misp_event . add_attribute ( * * attribute )
def get_results ( self ) :
event = json . loads ( self . misp_event . to_json ( ) )
2021-05-07 12:27:11 +02:00
results = { key : event [ key ]
for key in ( ' Attribute ' , ' Object ' ) if key in event }
2021-04-22 15:05:29 +02:00
return results
2021-04-23 16:02:21 +02:00
def get_query_onyphe ( self ) :
2021-04-23 16:11:10 +02:00
if self . attribute [ ' type ' ] == ' ip-src ' or self . attribute [ ' type ' ] == ' ip-dst ' :
2021-04-23 16:02:21 +02:00
self . __summary_ip ( )
2021-05-07 12:27:11 +02:00
if self . attribute [ ' type ' ] == ' domain ' :
self . __summary_domain ( )
if self . attribute [ ' type ' ] == ' hostname ' :
self . __summary_hostname ( )
2021-04-23 16:02:21 +02:00
def __summary_ip ( self ) :
results = self . onyphe_client . summary_ip ( self . attribute [ ' value ' ] )
if ' results ' in results :
for r in results [ ' results ' ] :
2021-04-23 16:15:38 +02:00
if ' domain ' in r :
domain = r [ ' domain ' ]
if type ( domain ) == list :
for d in domain :
self . __get_object_domain_ip ( d , ' domain ' )
elif type ( domain ) == str :
self . __get_object_domain_ip ( domain , ' domain ' )
2021-04-23 16:02:21 +02:00
2021-04-23 16:19:47 +02:00
if ' hostname ' in r :
hostname = r [ ' hostname ' ]
if type ( hostname ) == list :
for d in hostname :
self . __get_object_domain_ip ( d , ' domain ' )
elif type ( hostname ) == str :
self . __get_object_domain_ip ( hostname , ' domain ' )
2021-04-30 15:16:22 +02:00
if ' issuer ' in r :
self . __get_object_certificate ( r )
2021-05-07 12:27:11 +02:00
def __summary_domain ( self ) :
results = self . onyphe_client . summary_domain ( self . attribute [ ' value ' ] )
if ' results ' in results :
for r in results [ ' results ' ] :
for domain in r . get ( ' domain ' ) :
self . misp_event . add_attribute ( ' domain ' , domain )
for hostname in r . get ( ' hostname ' ) :
self . misp_event . add_attribute ( ' hostname ' , hostname )
if ' ip ' in r :
if type ( r [ ' ip ' ] ) is str :
self . __get_object_domain_ip ( r [ ' ip ' ] , ' ip ' )
if type ( r [ ' ip ' ] ) is list :
for ip in r [ ' ip ' ] :
self . __get_object_domain_ip ( ip , ' ip ' )
if ' issuer ' in r :
self . __get_object_certificate ( r )
def __summary_hostname ( self ) :
results = self . onyphe_client . summary_hostname ( self . attribute [ ' value ' ] )
if ' results ' in results :
for r in results [ ' results ' ] :
if ' domain ' in r :
if type ( r [ ' domain ' ] ) is str :
self . misp_event . add_attribute (
' domain ' , r [ ' domain ' ] )
if type ( r [ ' domain ' ] ) is list :
for domain in r [ ' domain ' ] :
self . misp_event . add_attribute ( ' domain ' , domain )
if ' hostname ' in r :
if type ( r [ ' hostname ' ] ) is str :
self . misp_event . add_attribute (
' hostname ' , r [ ' hostname ' ] )
if type ( r [ ' hostname ' ] ) is list :
for hostname in r [ ' hostname ' ] :
self . misp_event . add_attribute (
2021-05-07 14:38:42 +02:00
' hostname ' , hostname )
2021-05-07 12:27:11 +02:00
if ' ip ' in r :
if type ( r [ ' ip ' ] ) is str :
self . __get_object_domain_ip ( r [ ' ip ' ] , ' ip ' )
if type ( r [ ' ip ' ] ) is list :
for ip in r [ ' ip ' ] :
self . __get_object_domain_ip ( ip , ' ip ' )
if ' issuer ' in r :
self . __get_object_certificate ( r )
if ' cve ' in r :
if type ( r [ ' cve ' ] ) is list :
for cve in r [ ' cve ' ] :
self . __get_object_cve ( r , cve )
2021-04-30 15:22:55 +02:00
def __get_object_certificate ( self , r ) :
2021-04-30 15:16:22 +02:00
object_certificate = MISPObject ( ' x509 ' )
object_certificate . add_attribute ( ' ip ' , self . attribute [ ' value ' ] )
object_certificate . add_attribute ( ' serial-number ' , r [ ' serial ' ] )
2021-05-07 12:27:11 +02:00
object_certificate . add_attribute (
' x509-fingerprint-sha256 ' , r [ ' fingerprint ' ] [ ' sha256 ' ] )
object_certificate . add_attribute (
' x509-fingerprint-sha1 ' , r [ ' fingerprint ' ] [ ' sha1 ' ] )
object_certificate . add_attribute (
' x509-fingerprint-md5 ' , r [ ' fingerprint ' ] [ ' md5 ' ] )
2021-04-30 15:16:22 +02:00
signature = r [ ' signature ' ] [ ' algorithm ' ]
value = ' '
if ' sha256 ' in signature and ' RSA ' in signature :
value = ' SHA256_WITH_RSA_ENCRYPTION '
elif ' sha1 ' in signature and ' RSA ' in signature :
2021-05-07 12:27:11 +02:00
value = ' SHA1_WITH_RSA_ENCRYPTION '
2021-04-30 15:16:22 +02:00
if value :
object_certificate . add_attribute ( ' signature_algorithm ' , value )
2021-05-07 12:27:11 +02:00
object_certificate . add_attribute (
' pubkey-info-algorithm ' , r [ ' publickey ' ] [ ' algorithm ' ] )
if ' exponent ' in r [ ' publickey ' ] :
object_certificate . add_attribute (
' pubkey-info-exponent ' , r [ ' publickey ' ] [ ' exponent ' ] )
if ' length ' in r [ ' publickey ' ] :
object_certificate . add_attribute (
' pubkey-info-size ' , r [ ' publickey ' ] [ ' length ' ] )
object_certificate . add_attribute ( ' issuer ' , r [ ' issuer ' ] [ ' commonname ' ] )
object_certificate . add_attribute (
' validity-not-before ' , r [ ' validity ' ] [ ' notbefore ' ] )
object_certificate . add_attribute (
' validity-not-after ' , r [ ' validity ' ] [ ' notbefore ' ] )
2021-04-30 15:39:56 +02:00
object_certificate . add_reference ( self . attribute [ ' uuid ' ] , ' related-to ' )
2021-04-30 15:16:22 +02:00
self . misp_event . add_object ( object_certificate )
2021-05-07 12:27:11 +02:00
2021-04-23 16:02:21 +02:00
def __get_object_domain_ip ( self , obs , relation ) :
objet_domain_ip = MISPObject ( ' domain-ip ' )
objet_domain_ip . add_attribute ( relation , obs )
relation_attr = self . __get_relation_attribute ( )
if relation_attr :
2021-05-07 12:27:11 +02:00
objet_domain_ip . add_attribute (
relation_attr , self . attribute [ ' value ' ] )
2021-04-30 15:46:59 +02:00
objet_domain_ip . add_reference ( self . attribute [ ' uuid ' ] , ' related-to ' )
self . misp_event . add_object ( objet_domain_ip )
2021-04-23 16:02:21 +02:00
def __get_relation_attribute ( self ) :
if self . attribute [ ' type ' ] == ' ip-src ' :
return ' ip '
2021-04-23 16:16:43 +02:00
elif self . attribute [ ' type ' ] == ' ip-dst ' :
2021-04-23 16:02:21 +02:00
return ' ip '
elif self . attribute [ ' type ' ] == ' domain ' :
return ' domain '
elif self . attribute [ ' type ' ] == ' hostname ' :
return ' domain '
2021-05-07 12:27:11 +02:00
def __get_object_cve ( self , item , cve ) :
attributes = [ ]
object_cve = MISPObject ( ' vulnerability ' )
object_cve . add_attribute ( ' id ' , cve )
object_cve . add_attribute ( ' state ' , ' Published ' )
if type ( item [ ' ip ' ] ) is list :
for ip in item [ ' ip ' ] :
attributes . extend (
list ( filter ( lambda x : x [ ' value ' ] == ip , self . misp_event [ ' Attribute ' ] ) ) )
for obj in self . misp_event [ ' Object ' ] :
attributes . extend (
list ( filter ( lambda x : x [ ' value ' ] == ip , obj [ ' Attribute ' ] ) ) )
if type ( item [ ' ip ' ] ) is str :
for obj in self . misp_event [ ' Object ' ] :
for att in obj [ ' Attribute ' ] :
if att [ ' value ' ] == item [ ' ip ' ] :
object_cve . add_reference ( obj [ ' uuid ' ] , ' cve ' )
self . misp_event . add_object ( object_cve )
2021-04-22 15:05:29 +02:00
2018-06-08 16:38:41 +02:00
def handler ( q = False ) :
2018-06-11 13:34:45 +02:00
if q :
2018-06-08 16:38:41 +02:00
2018-06-11 13:34:45 +02:00
request = json . loads ( q )
2021-04-22 15:05:29 +02:00
attribute = request [ ' attribute ' ]
2018-06-08 16:38:41 +02:00
2019-10-30 09:09:55 +01:00
if not request . get ( ' config ' ) or not request [ ' config ' ] . get ( ' apikey ' ) :
2018-06-11 13:34:45 +02:00
misperrors [ ' error ' ] = ' Onyphe authentication is missing '
return misperrors
2018-06-08 16:38:41 +02:00
2021-04-23 16:02:21 +02:00
api_key = request [ ' config ' ] . get ( ' apikey ' )
onyphe_client = OnypheClient ( api_key , attribute )
onyphe_client . get_query_onyphe ( )
results = onyphe_client . get_results ( )
return { ' results ' : results }
2018-06-08 16:38:41 +02:00
2021-05-07 12:27:11 +02:00
2018-06-08 16:38:41 +02:00
def introspection ( ) :
return mispattributes
def version ( ) :
moduleinfo [ ' config ' ] = moduleconfig
2018-11-11 15:49:14 +01:00
return moduleinfo