From 58265dc92558e3e98cfe83b9c5ccf47125da7a49 Mon Sep 17 00:00:00 2001 From: ip2location Date: Thu, 7 Dec 2023 10:40:04 +0800 Subject: [PATCH 1/3] Add IP2Location.io module --- misp_modules/modules/expansion/__init__.py | 2 +- .../modules/expansion/ip2locationio.py | 95 +++++++++++++++++++ 2 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 misp_modules/modules/expansion/ip2locationio.py diff --git a/misp_modules/modules/expansion/__init__.py b/misp_modules/modules/expansion/__init__.py index ad29eff..77ff4f8 100644 --- a/misp_modules/modules/expansion/__init__.py +++ b/misp_modules/modules/expansion/__init__.py @@ -20,7 +20,7 @@ __all__ = ['cuckoo_submit', 'vmray_submit', 'bgpranking', 'circl_passivedns', 'c 'trustar_enrich', 'recordedfuture', 'html_to_markdown', 'socialscan', 'passive-ssh', 'qintel_qsentry', 'mwdb', 'hashlookup', 'mmdb_lookup', 'ipqs_fraud_and_risk_scoring', 'clamav', 'jinja_template_rendering','hyasinsight', 'variotdbs', 'crowdsec', - 'extract_url_components', 'ipinfo', 'whoisfreaks'] + 'extract_url_components', 'ipinfo', 'whoisfreaks', 'ip2locationio'] minimum_required_fields = ('type', 'uuid', 'value') diff --git a/misp_modules/modules/expansion/ip2locationio.py b/misp_modules/modules/expansion/ip2locationio.py new file mode 100644 index 0000000..6ba88a5 --- /dev/null +++ b/misp_modules/modules/expansion/ip2locationio.py @@ -0,0 +1,95 @@ +import json +import requests +from . import check_input_attribute, standard_error_message +from pymisp import MISPAttribute, MISPEvent, MISPObject + +mispattributes = { + 'input': ['ip-src', 'ip-dst'], + 'format': 'misp_standard' +} +moduleinfo = { + 'version': 1, + 'author': 'IP2Location.io', + 'description': 'An expansion module to query IP2Location.io for additional information on an IP address', + 'module-type': ['expansion', 'hover'] +} +moduleconfig = ['key'] + +_GEOLOCATION_OBJECT_MAPPING = { + 'country_code': 'country code', + 'country_name': 'country name', + 'region_name': 'region name', + 'city_name': 'city', + 'zip_code': 'zipcode', + 'latitude': 'latitude', + 'longitude': 'longitude' +} + + +def handler(q=False): + # Input checks + 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'] + if attribute.get('type') not in mispattributes['input']: + return {'error': 'Wrong input attribute type.'} + if not request.get('config'): + return {'error': 'Missing ip2locationio config.'} + if not request['config'].get('key'): + return {'error': 'Missing ip2locationio API key.'} + + # Query ip2location.io + query = requests.get( + f"https://api.ip2location.io/json?key={request['config']['key']&ip={attribute['value']}" + ) + if query.status_code != 200: + return {'error': f'Error while querying ip2location.io - {query.status_code}: {query.reason}'} + iplio_result = query.json() + + # Check if the IP address is not reserved for special use + # if ipinfo.get('bogon', False): + if '' in iplio_result and iplio_result[''] == 'RSV': + return {'error': 'The IP address is reserved for special use'} + + # Initiate the MISP data structures + misp_event = MISPEvent() + input_attribute = MISPAttribute() + input_attribute.from_dict(**attribute) + misp_event.add_attribute(**input_attribute) + + # Parse the geolocation information related to the IP address + geolocation = MISPObject('geolocation') + for field, relation in _GEOLOCATION_OBJECT_MAPPING.items(): + geolocation.add_attribute(relation, iplio_result[field]) + geolocation.add_reference(input_attribute.uuid, 'locates') + misp_event.add_object(geolocation) + + # Parse proxy information + proxy = MISPObject('proxy') + proxy.add_reference(input_attribute.uuid, 'related-to') + if iplio_result.get('proxy') is not None: + proxy_info = iplio_result['proxy'] + proxy.add_attribute('proxy_type', proxy_info['proxy_type']) + proxy.add_attribute('threat', proxy_info['threat']) + proxy.add_attribute('provider', proxy_info['provider']) + proxy.add_attribute('last_seen', proxy_info['last_seen']) + misp_event.add_object(proxy) + + + # Return the results in MISP format + event = json.loads(misp_event.to_json()) + return { + 'results': {key: event[key] for key in ('Attribute', 'Object')} + } + + +def introspection(): + return mispattributes + + +def version(): + moduleinfo['config'] = moduleconfig + return moduleinfo From f0b610907de5a6d66b005934beca55cccb4aec59 Mon Sep 17 00:00:00 2001 From: ip2location Date: Fri, 8 Dec 2023 10:01:14 +0800 Subject: [PATCH 2/3] Update ip2locationiopy and add documentations --- README.md | 1 + docs/index.md | 1 + docs/logos/ip2locationio.png | Bin 0 -> 7126 bytes documentation/logos/ip2locationio.png | Bin 0 -> 7126 bytes .../website/expansion/ip2locationio.json | 13 ++++++++++++ misp_modules/lib/joe_parser.py | 8 +++++++ .../modules/expansion/ip2locationio.py | 20 ++++-------------- 7 files changed, 27 insertions(+), 16 deletions(-) create mode 100644 docs/logos/ip2locationio.png create mode 100644 documentation/logos/ip2locationio.png create mode 100644 documentation/website/expansion/ip2locationio.json diff --git a/README.md b/README.md index 26a8360..d8e0adb 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ For more information: [Extending MISP with Python modules](https://www.misp-proj * [html_to_markdown](misp_modules/modules/expansion/html_to_markdown.py) - Simple HTML to markdown converter * [HYAS Insight](misp_modules/modules/expansion/hyasinsight.py) - a hover and expansion module to get information from [HYAS Insight](https://www.hyas.com/hyas-insight). * [intel471](misp_modules/modules/expansion/intel471.py) - an expansion module to get info from [Intel471](https://intel471.com). +* [IP2Location.io](misp_modules/modules/expansion/ip2locationio.py) - an expansion module to get additional information on an IP address using the IP2Location.io API * [IPASN](misp_modules/modules/expansion/ipasn.py) - a hover and expansion to get the BGP ASN of an IP address. * [ipinfo.io](misp_modules/modules/expansion/ipinfo.py) - an expansion module to get additional information on an IP address using the ipinfo.io API * [iprep](misp_modules/modules/expansion/iprep.py) - an expansion module to get IP reputation from packetmail.net. diff --git a/docs/index.md b/docs/index.md index e2c5a13..187892b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -42,6 +42,7 @@ For more information: [Extending MISP with Python modules](https://www.circl.lu/ * [hashdd](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hashdd.py) - a hover module to check file hashes against [hashdd.com](http://www.hashdd.com) including NSLR dataset. * [hibp](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/hibp.py) - a hover module to lookup against Have I Been Pwned? * [intel471](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/intel471.py) - an expansion module to get info from [Intel471](https://intel471.com). +* [IP2Location.io](misp_modules/modules/expansion/ip2locationio.py) - an expansion module to get additional information on an IP address using the IP2Location.io API * [IPASN](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/ipasn.py) - a hover and expansion to get the BGP ASN of an IP address. * [iprep](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/iprep.py) - an expansion module to get IP reputation from packetmail.net. * [Joe Sandbox submit](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/joesandbox_submit.py) - Submit files and URLs to Joe Sandbox. diff --git a/docs/logos/ip2locationio.png b/docs/logos/ip2locationio.png new file mode 100644 index 0000000000000000000000000000000000000000..85581af808a98e58ca0f510a06d4e489e1a54ee0 GIT binary patch literal 7126 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 HZKM7Ja(F`S literal 0 HcmV?d00001 diff --git a/documentation/logos/ip2locationio.png b/documentation/logos/ip2locationio.png new file mode 100644 index 0000000000000000000000000000000000000000..85581af808a98e58ca0f510a06d4e489e1a54ee0 GIT binary patch literal 7126 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 HZKM7Ja(F`S literal 0 HcmV?d00001 diff --git a/documentation/website/expansion/ip2locationio.json b/documentation/website/expansion/ip2locationio.json new file mode 100644 index 0000000..71de545 --- /dev/null +++ b/documentation/website/expansion/ip2locationio.json @@ -0,0 +1,13 @@ +{ + "description": "An expansion module to query IP2Location.io to gather more information on a given IP address.", + "logo": "ip2locationio.png", + "requirements": [ + "An IP2Location.io token" + ], + "input": "IP address attribute.", + "output": "Additional information on the IP address, such as geolocation, proxy and so on. Refer to the Response Format section in https://www.ip2location.io/ip2location-documentation to find out the full format of the data returned.", + "references": [ + "https://www.ip2location.io/ip2location-documentation" + ], + "features": "The module takes an IP address attribute as input and queries the IP2Location.io API. \nFree plan user will get the basic geolocation informaiton, and different subsription plan will get more information on the IP address. \n Refer to [pricing page](https://www.ip2location.io/pricing) for more information on data available for each plan. \n\nMore information on the responses content is available in the [documentation](https://www.ip2location.io/ip2location-documentation)." +} diff --git a/misp_modules/lib/joe_parser.py b/misp_modules/lib/joe_parser.py index e701ff3..944ef0c 100644 --- a/misp_modules/lib/joe_parser.py +++ b/misp_modules/lib/joe_parser.py @@ -497,6 +497,14 @@ class JoeParser(): self.misp_event.add_attribute(**attribute) reference = dict(referenced_uuid=attribute.uuid, relationship_type='contacts') self.add_process_reference(ip['@targetid'], ip['@currentpath'], reference) + ip2locationio = self.data['ip2locationio'] + if ip2locationio: + for ip in ip2locationio['ip']: + attribute = MISPAttribute() + attribute.from_dict(**{'type': 'ip-dst', 'value': ip['@ip'], 'to_ids': False}) + self.misp_event.add_attribute(**attribute) + reference = dict(referenced_uuid=attribute.uuid, relationship_type='contacts') + self.add_process_reference(ip['@targetid'], ip['@currentpath'], reference) urlinfo = self.data['urlinfo'] if urlinfo: for url in urlinfo['url']: diff --git a/misp_modules/modules/expansion/ip2locationio.py b/misp_modules/modules/expansion/ip2locationio.py index 6ba88a5..5303b15 100644 --- a/misp_modules/modules/expansion/ip2locationio.py +++ b/misp_modules/modules/expansion/ip2locationio.py @@ -16,9 +16,9 @@ moduleinfo = { moduleconfig = ['key'] _GEOLOCATION_OBJECT_MAPPING = { - 'country_code': 'country code', - 'country_name': 'country name', - 'region_name': 'region name', + 'country_code': 'countrycode', + 'country_name': 'country', + 'region_name': 'region', 'city_name': 'city', 'zip_code': 'zipcode', 'latitude': 'latitude', @@ -43,7 +43,7 @@ def handler(q=False): # Query ip2location.io query = requests.get( - f"https://api.ip2location.io/json?key={request['config']['key']&ip={attribute['value']}" + f"https://api.ip2location.io/json?key={request['config']['key']}&ip={attribute['value']}" ) if query.status_code != 200: return {'error': f'Error while querying ip2location.io - {query.status_code}: {query.reason}'} @@ -66,18 +66,6 @@ def handler(q=False): geolocation.add_attribute(relation, iplio_result[field]) geolocation.add_reference(input_attribute.uuid, 'locates') misp_event.add_object(geolocation) - - # Parse proxy information - proxy = MISPObject('proxy') - proxy.add_reference(input_attribute.uuid, 'related-to') - if iplio_result.get('proxy') is not None: - proxy_info = iplio_result['proxy'] - proxy.add_attribute('proxy_type', proxy_info['proxy_type']) - proxy.add_attribute('threat', proxy_info['threat']) - proxy.add_attribute('provider', proxy_info['provider']) - proxy.add_attribute('last_seen', proxy_info['last_seen']) - misp_event.add_object(proxy) - # Return the results in MISP format event = json.loads(misp_event.to_json()) From 59116b4769484a536e462a4f74d7f64e32605e97 Mon Sep 17 00:00:00 2001 From: ip2location Date: Mon, 11 Dec 2023 10:14:33 +0800 Subject: [PATCH 3/3] Removed ip2locationio from joe_parser lib. --- misp_modules/lib/joe_parser.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/misp_modules/lib/joe_parser.py b/misp_modules/lib/joe_parser.py index 944ef0c..e701ff3 100644 --- a/misp_modules/lib/joe_parser.py +++ b/misp_modules/lib/joe_parser.py @@ -497,14 +497,6 @@ class JoeParser(): self.misp_event.add_attribute(**attribute) reference = dict(referenced_uuid=attribute.uuid, relationship_type='contacts') self.add_process_reference(ip['@targetid'], ip['@currentpath'], reference) - ip2locationio = self.data['ip2locationio'] - if ip2locationio: - for ip in ip2locationio['ip']: - attribute = MISPAttribute() - attribute.from_dict(**{'type': 'ip-dst', 'value': ip['@ip'], 'to_ids': False}) - self.misp_event.add_attribute(**attribute) - reference = dict(referenced_uuid=attribute.uuid, relationship_type='contacts') - self.add_process_reference(ip['@targetid'], ip['@currentpath'], reference) urlinfo = self.data['urlinfo'] if urlinfo: for url in urlinfo['url']: