2022-11-06 17:28:00 +01:00
|
|
|
import json
|
|
|
|
from pymisp import MISPEvent, MISPObject
|
|
|
|
from . import check_input_attribute, standard_error_message
|
|
|
|
from pyfaup.faup import Faup
|
|
|
|
|
|
|
|
misperrors = {'error': 'Error'}
|
|
|
|
mispattributes = {'input': ['url'], 'format': 'misp_standard'}
|
2024-08-12 11:23:10 +02:00
|
|
|
moduleinfo = {
|
|
|
|
'version': '1',
|
|
|
|
'author': 'MISP Team',
|
|
|
|
'description': 'Extract URL components',
|
|
|
|
'module-type': ['expansion', 'hover'],
|
|
|
|
'name': 'URL Components Extractor',
|
|
|
|
'logo': '',
|
|
|
|
'requirements': [],
|
|
|
|
'features': '',
|
|
|
|
'references': [],
|
|
|
|
'input': '',
|
|
|
|
'output': '',
|
|
|
|
}
|
2022-11-06 17:28:00 +01:00
|
|
|
moduleconfig = []
|
|
|
|
|
|
|
|
|
|
|
|
def createObjectFromURL(url):
|
|
|
|
f = Faup()
|
|
|
|
f.decode(url)
|
|
|
|
parsed = f.get()
|
|
|
|
obj = MISPObject('url')
|
|
|
|
obj.add_attribute('url', type='url', value=url)
|
|
|
|
if parsed['tld'] is not None:
|
|
|
|
obj.add_attribute('tld', type='text', value=parsed['tld'])
|
|
|
|
if parsed['subdomain'] is not None:
|
|
|
|
obj.add_attribute('subdomain', type='text', value=parsed['subdomain'])
|
|
|
|
obj.add_attribute('scheme', type='text', value=parsed['scheme'])
|
2023-07-13 16:14:04 +02:00
|
|
|
if parsed['resource_path'] is not None:
|
|
|
|
obj.add_attribute('resource_path', type='text', value=parsed['resource_path'])
|
|
|
|
if parsed['query_string'] is not None:
|
|
|
|
obj.add_attribute('query_string', type='text', value=parsed['query_string'])
|
|
|
|
if parsed['port'] is not None:
|
|
|
|
obj.add_attribute('port', type='port', value=parsed['port'])
|
2022-11-06 17:28:00 +01:00
|
|
|
obj.add_attribute('host', type='hostname', value=parsed['host'])
|
|
|
|
if parsed['fragment'] is not None:
|
|
|
|
obj.add_attribute('fragment', type='text', value=parsed['fragment'])
|
|
|
|
obj.add_attribute('domain_without_tld', type='text', value=parsed['domain_without_tld'])
|
|
|
|
obj.add_attribute('domain', type='domain', value=parsed['domain'])
|
|
|
|
return obj
|
|
|
|
|
|
|
|
|
|
|
|
def createEvent(urlObject, attributeUUID, urlAttribute):
|
|
|
|
mispEvent = MISPEvent()
|
|
|
|
mispEvent.add_attribute(**urlAttribute)
|
|
|
|
urlObject.add_reference(attributeUUID, 'generated-from')
|
|
|
|
mispEvent.add_object(urlObject)
|
|
|
|
return mispEvent
|
|
|
|
|
|
|
|
def handler(q=False):
|
|
|
|
if q is False:
|
|
|
|
return False
|
|
|
|
request = json.loads(q)
|
|
|
|
if not request.get('attribute') or not check_input_attribute(request['attribute']):
|
|
|
|
return {'error': f'{standard_error_message}, which should contain at least a type, a value and an uuid.'}
|
|
|
|
attribute = request['attribute']
|
2024-08-12 11:23:10 +02:00
|
|
|
|
2022-11-06 17:28:00 +01:00
|
|
|
if attribute['type'] not in mispattributes['input']:
|
2024-08-12 11:23:10 +02:00
|
|
|
return {'error': 'Bad attribute type'}
|
2022-11-06 17:28:00 +01:00
|
|
|
|
2024-08-12 11:23:10 +02:00
|
|
|
url = attribute['value']
|
2022-11-06 17:28:00 +01:00
|
|
|
urlObject = createObjectFromURL(url)
|
|
|
|
|
|
|
|
event = createEvent(urlObject, attribute['uuid'], attribute)
|
|
|
|
event = json.loads(event.to_json())
|
2024-08-12 11:23:10 +02:00
|
|
|
|
2022-11-06 17:28:00 +01:00
|
|
|
result = {'results': {'Object': event['Object']}}
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
|
|
def introspection():
|
|
|
|
return mispattributes
|
|
|
|
|
|
|
|
|
|
|
|
def version():
|
|
|
|
moduleinfo['config'] = moduleconfig
|
|
|
|
return moduleinfo
|