2022-02-03 13:25:29 +01:00
#!/usr/bin/env python3
# Copyright 2022 Google Inc. All Rights Reserved.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
""" Creates a VT Collection with indicators present in a given event. """
import base64
import json
import requests
misperrors = {
' error ' : ' Error '
}
mispattributes = {
' input ' : [
' hostname ' ,
' domain ' ,
' ip-src ' ,
' ip-dst ' ,
' md5 ' ,
' sha1 ' ,
' sha256 ' ,
' url '
] ,
' format ' : ' misp_standard ' ,
' responseType ' : ' application/txt ' ,
' outputFileExtension ' : ' txt ' ,
}
moduleinfo = {
' version ' : ' 1.0 ' ,
' author ' : ' VirusTotal ' ,
' description ' : ' Creates a VT Collection from an event iocs. ' ,
2024-08-12 11:23:10 +02:00
' module-type ' : [ ' export ' ] ,
' name ' : ' VirusTotal Collections Export ' ,
' logo ' : ' virustotal.png ' ,
' requirements ' : [ ' An access to the VirusTotal API (apikey). ' ] ,
' features ' : ' This export module which takes advantage of a new endpoint in VT APIv3 to create VT Collections from IOCs contained in a MISP event. With this module users will be able to create a collection just using the Download as... button. ' ,
' references ' : [ ' https://www.virustotal.com/ ' , ' https://blog.virustotal.com/2021/11/introducing-virustotal-collections.html ' ] ,
' input ' : ' A domain, hash (md5, sha1, sha256 or sha512), hostname, url or IP address attribute. ' ,
' output ' : ' A VirusTotal collection in VT. ' ,
2022-02-03 13:25:29 +01:00
}
moduleconfig = [
' vt_api_key ' ,
' proxy_host ' ,
' proxy_port ' ,
' proxy_username ' ,
' proxy_password '
]
class VTError ( Exception ) :
" Exception class to map vt api response errors. "
pass
def create_collection ( api_key , event_data ) :
headers = {
' x-apikey ' : api_key ,
' content-type ' : ' application/json ' ,
' x-tool ' : ' MISPModuleVirusTotalCollectionExport ' ,
}
response = requests . post ( ' https://www.virustotal.com/api/v3/integrations/misp/collections ' ,
headers = headers ,
json = event_data )
uuid = event_data [ ' Event ' ] [ ' uuid ' ]
response_data = response . json ( )
if response . status_code == 200 :
2023-09-12 14:49:30 +02:00
col_id = response_data [ ' data ' ] [ ' id ' ]
return f ' { uuid } : https://www.virustotal.com/gui/collection/ { col_id } /iocs '
2022-02-03 13:25:29 +01:00
error = response_data [ ' error ' ] [ ' message ' ]
if response . status_code == 400 :
return f ' { uuid } : { error } '
else :
misperrors [ ' error ' ] = error
raise VTError ( error )
def normalize_misp_data ( data ) :
normalized_data = { ' Event ' : data . pop ( ' Event ' , { } ) }
for attr_key in data :
if isinstance ( data [ attr_key ] , list ) or isinstance ( data [ attr_key ] , dict ) :
if attr_key == ' EventTag ' :
normalized_data [ ' Event ' ] [ ' Tag ' ] = [ tag [ ' Tag ' ] for tag in data [ attr_key ] ]
else :
normalized_data [ ' Event ' ] [ attr_key ] = data [ attr_key ]
return normalized_data
def handler ( q = False ) :
request = json . loads ( q )
if not request . get ( ' config ' ) or not request [ ' config ' ] . get ( ' vt_api_key ' ) :
misperrors [ ' error ' ] = ' A VirusTotal api key is required for this module. '
return misperrors
config = request [ ' config ' ]
data = request [ ' data ' ]
responses = [ ]
try :
for event_data in data :
normalized_event = normalize_misp_data ( event_data )
responses . append ( create_collection ( config . get ( ' vt_api_key ' ) ,
normalized_event ) )
output = ' \n ' . join ( responses )
return {
" response " : [ ] ,
" data " : str ( base64 . b64encode ( bytes ( output , ' utf-8 ' ) ) , ' utf-8 ' ) ,
}
except VTError :
return misperrors
def introspection ( ) :
return mispattributes
def version ( ) :
moduleinfo [ ' config ' ] = moduleconfig
return moduleinfo