mirror of https://github.com/MISP/misp-modules
commit
2efbbba31e
|
@ -100,6 +100,7 @@ For more information: [Extending MISP with Python modules](https://www.misp-proj
|
|||
* [VMware NSX](misp_modules/modules/expansion/vmware_nsx.py) - a module to enrich a file or URL with VMware NSX Defender.
|
||||
* [VulnDB](misp_modules/modules/expansion/vulndb.py) - a module to query [VulnDB](https://www.riskbasedsecurity.com/).
|
||||
* [Vulners](misp_modules/modules/expansion/vulners.py) - an expansion module to expand information about CVEs using Vulners API.
|
||||
* [Vysion](misp_modules/modules/expansion/vysion.py) - an expansion module to add dark web intelligence using Vysion API.
|
||||
* [whois](misp_modules/modules/expansion/whois.py) - a module to query a local instance of [uwhois](https://github.com/rafiot/uwhoisd).
|
||||
* [whoisfreaks](misp_modules/modules/expansion/whoisfreaks.py) - An expansion module for [whoisfreaks](https://whoisfreaks.com/) that will provide an enriched analysis of the provided domain, including WHOIS and DNS information.
|
||||
* [wikidata](misp_modules/modules/expansion/wiki.py) - a [wikidata](https://www.wikidata.org) expansion module.
|
||||
|
|
|
@ -170,6 +170,7 @@ urllib3==2.2.2; python_version >= '3.8'
|
|||
vt-graph-api==2.2.0
|
||||
vt-py==0.18.3; python_full_version >= '3.7.0'
|
||||
vulners==2.1.7; python_version >= '3.8'
|
||||
vysion==2.0.6; python_version >= '3.8'
|
||||
wand==0.6.13
|
||||
websocket-client==1.8.0; python_version >= '3.8'
|
||||
websockets==12.0; python_version >= '3.8'
|
||||
|
|
|
@ -76,6 +76,7 @@ For more information: [Extending MISP with Python modules](https://www.circl.lu/
|
|||
* [VMray](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vmray_submit.py) - a module to submit a sample to VMray.
|
||||
* [VulnDB](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vulndb.py) - a module to query [VulnDB](https://www.riskbasedsecurity.com/).
|
||||
* [Vulners](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vulners.py) - an expansion module to expand information about CVEs using Vulners API.
|
||||
* [Vysion](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vysion.py) - an expansion module to add dark web intelligence using Vysion API.
|
||||
* [whois](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/whois.py) - a module to query a local instance of [uwhois](https://github.com/rafiot/uwhoisd).
|
||||
* [wikidata](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/wiki.py) - a [wikidata](https://www.wikidata.org) expansion module.
|
||||
* [xforce](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/xforceexchange.py) - an IBM X-Force Exchange expansion module.
|
||||
|
|
|
@ -1944,6 +1944,26 @@ An expansion hover module to expand information about CVE id using Vulners API.
|
|||
|
||||
-----
|
||||
|
||||
#### [Vysion](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/vysion.py)
|
||||
|
||||
<img src=logos/vysion.png height=60>
|
||||
|
||||
Module to enrich the information by making use of the Vysion API.
|
||||
- **features**:
|
||||
>This module gets correlated information from our dark web intelligence database. With this you will get several objects containing information related to, for example, an organization victim of a ransomware attack.
|
||||
>MISP objects containing title, link to our webapp and TOR, i2p or clearnet URLs.
|
||||
- **input**:
|
||||
>MISP Attribute which include: company(target-org), country, info, BTC, XMR and DASH address.
|
||||
- **output**:
|
||||
>MISP objects containing title, link to our webapp and TOR, i2p or clearnet URLs.
|
||||
- **references**:
|
||||
>https://vysion.ai/
|
||||
- **requirements**:
|
||||
> Vysion python library
|
||||
> Vysion API Key
|
||||
|
||||
-----
|
||||
|
||||
#### [whois](https://github.com/MISP/misp-modules/tree/main/misp_modules/modules/expansion/whois.py)
|
||||
|
||||
Module to query a local instance of uwhois (https://github.com/rafiot/uwhoisd).
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"description": "Module to enrich the information by making use of the Vysion API.",
|
||||
"logo": "vysion.png",
|
||||
"requirements": [
|
||||
"Vysion python library",
|
||||
"Vysion API Key"
|
||||
],
|
||||
"input": "company(target-org), country, info, BTC, XMR and DASH address.",
|
||||
"output": "MISP objects containing title, link to our webapp and TOR, i2p or clearnet URLs.",
|
||||
"references": [
|
||||
"https://vysion.ai/",
|
||||
"https://developers.vysion.ai/",
|
||||
"https://github.com/ByronLabs/vysion-cti/tree/main"
|
||||
],
|
||||
"features": "This module gets correlated information from Byron Labs' dark web intelligence database. With this you will get several objects containing information related to, for example, an organization victim of a ransomware attack."
|
||||
}
|
|
@ -21,7 +21,7 @@ __all__ = ['cuckoo_submit', 'vmray_submit', 'bgpranking', 'circl_passivedns', 'c
|
|||
'qintel_qsentry', 'mwdb', 'hashlookup', 'mmdb_lookup', 'ipqs_fraud_and_risk_scoring',
|
||||
'clamav', 'jinja_template_rendering','hyasinsight', 'variotdbs', 'crowdsec',
|
||||
'extract_url_components', 'ipinfo', 'whoisfreaks', 'ip2locationio', 'stairwell',
|
||||
'google_threat_intelligence', 'vulnerability_lookup']
|
||||
'google_threat_intelligence', 'vulnerability_lookup', 'vysion']
|
||||
|
||||
|
||||
minimum_required_fields = ('type', 'uuid', 'value')
|
||||
|
|
|
@ -0,0 +1,213 @@
|
|||
import json
|
||||
from pymisp import MISPAttribute, MISPEvent
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import logging
|
||||
|
||||
import vysion.client as vysion
|
||||
|
||||
import vysion.dto as dto
|
||||
from vysion.dto.util import MISPProcessor
|
||||
|
||||
misperrors = {"error": "Error"}
|
||||
mispattributes = {
|
||||
"input": [
|
||||
"email",
|
||||
"domain",
|
||||
"hostname",
|
||||
"url",
|
||||
"text",
|
||||
"btc",
|
||||
"phone-number",
|
||||
"target-org",
|
||||
"xmr",
|
||||
"dash",
|
||||
],
|
||||
"format": "misp_standard",
|
||||
}
|
||||
|
||||
# possible module-types: 'expansion', 'hover' or both
|
||||
moduleinfo = {
|
||||
"version": "1",
|
||||
"author": "Byron Labs",
|
||||
"description": "Enrich observables with the Vysion API",
|
||||
"module-type": ["expansion"],
|
||||
}
|
||||
|
||||
# config fields that your code expects from the site admin
|
||||
moduleconfig = [
|
||||
"apikey",
|
||||
"event_limit",
|
||||
"proxy_host",
|
||||
"proxy_port",
|
||||
"proxy_username",
|
||||
"proxy_password",
|
||||
]
|
||||
|
||||
LOGGER = logging.getLogger("vysion")
|
||||
LOGGER.setLevel(logging.INFO)
|
||||
LOGGER.info("Starting Vysion")
|
||||
|
||||
DEFAULT_RESULTS_LIMIT = 10
|
||||
|
||||
|
||||
def get_proxy_settings(config: dict) -> dict:
|
||||
"""Returns proxy settings in the requests format.
|
||||
If no proxy settings are set, return None."""
|
||||
proxies = None
|
||||
host = config.get("proxy_host")
|
||||
port = config.get("proxy_port")
|
||||
username = config.get("proxy_username")
|
||||
password = config.get("proxy_password")
|
||||
|
||||
if host:
|
||||
if not port:
|
||||
misperrors["error"] = (
|
||||
"The vysion_proxy_host config is set, "
|
||||
"please also set the vysion_proxy_port."
|
||||
)
|
||||
raise KeyError
|
||||
parsed = urlparse(host)
|
||||
if "http" in parsed.scheme:
|
||||
scheme = "http"
|
||||
else:
|
||||
scheme = parsed.scheme
|
||||
netloc = parsed.netloc
|
||||
host = f"{netloc}:{port}"
|
||||
|
||||
if username:
|
||||
if not password:
|
||||
misperrors["error"] = (
|
||||
"The vysion_proxy_username config is set, "
|
||||
"please also set the vysion_proxy_password."
|
||||
)
|
||||
raise KeyError
|
||||
auth = f"{username}:{password}"
|
||||
host = auth + "@" + host
|
||||
|
||||
proxies = {"http": f"{scheme}://{host}", "https": f"{scheme}://{host}"}
|
||||
return proxies
|
||||
|
||||
|
||||
def parse_error(status_code: int) -> str:
|
||||
|
||||
status_mapping = {
|
||||
500: "Vysion is blind.",
|
||||
400: "Incorrect request, please check the arguments.",
|
||||
403: "You don't have enough privileges to make the request.",
|
||||
}
|
||||
|
||||
if status_code in status_mapping:
|
||||
return status_mapping[status_code]
|
||||
|
||||
return "Vysion may not be accessible."
|
||||
|
||||
|
||||
def handler(q=False):
|
||||
|
||||
if q is False:
|
||||
return False
|
||||
|
||||
request = json.loads(q)
|
||||
|
||||
if not request.get("config") or not request["config"].get("apikey"):
|
||||
misperrors["error"] = "A Vysion api key is required for this module."
|
||||
return misperrors
|
||||
|
||||
if not request.get("attribute"):
|
||||
return {
|
||||
"error": f"{standard_error_message}, which should contain at least a type, a value and an uuid."
|
||||
}
|
||||
|
||||
if request["attribute"]["type"] not in mispattributes["input"]:
|
||||
return {"error": "Unsupported attribute type."}
|
||||
|
||||
# event_limit = request["config"].get("event_limit")
|
||||
attribute = request["attribute"]
|
||||
proxy_settings = get_proxy_settings(request.get("config"))
|
||||
|
||||
try:
|
||||
|
||||
client = vysion.Client(
|
||||
api_key=request["config"]["apikey"],
|
||||
headers={
|
||||
"x-tool": "MISPModuleVysionExpansion",
|
||||
},
|
||||
proxy=proxy_settings["http"] if proxy_settings else None,
|
||||
)
|
||||
|
||||
LOGGER.debug(attribute)
|
||||
|
||||
misp_attribute = MISPAttribute()
|
||||
misp_attribute.from_dict(**attribute)
|
||||
|
||||
attribute_type = misp_attribute.type
|
||||
attribute_value = misp_attribute.value
|
||||
|
||||
# https://www.misp-project.org/datamodels/#types
|
||||
|
||||
LOGGER.debug(attribute_type)
|
||||
|
||||
result = None
|
||||
|
||||
if attribute_type == "email":
|
||||
result = client.find_email(attribute_value)
|
||||
elif attribute_type == "domain":
|
||||
result = client.find_url(attribute_value)
|
||||
elif attribute_type == "url":
|
||||
result = client.find_url(attribute_value)
|
||||
elif attribute_type == "text":
|
||||
result = client.search(attribute_value)
|
||||
elif attribute_type == "target-org":
|
||||
result = client.search(attribute_value)
|
||||
elif attribute_type == "phone-number":
|
||||
result = client.search(attribute_value)
|
||||
elif attribute_type == "btc":
|
||||
result = client.find_wallet("BTC",attribute_value)
|
||||
elif attribute_type == "xmr":
|
||||
result = client.find_wallet("XMR",attribute_value)
|
||||
elif attribute_type == "dash":
|
||||
result = client.find_wallet("DASH",attribute_value)
|
||||
|
||||
if result is None:
|
||||
return {"results": {}}
|
||||
|
||||
p = MISPProcessor()
|
||||
misp_event: MISPEvent = p.process(result, ref_attribute=misp_attribute)
|
||||
|
||||
LOGGER.info("Vysion client initialized")
|
||||
|
||||
LOGGER.info("Vysion result obtained")
|
||||
|
||||
return {
|
||||
"results": {
|
||||
"Object": [
|
||||
json.loads(object.to_json()) for object in misp_event.objects
|
||||
],
|
||||
"Attribute": [
|
||||
json.loads(attribute.to_json())
|
||||
for attribute in misp_event.attributes
|
||||
],
|
||||
"Tag": [
|
||||
json.loads(tag.to_json())
|
||||
for tag in misp_event.tags
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
except vysion.APIError as ex:
|
||||
|
||||
LOGGER.error("Error in Vysion")
|
||||
LOGGER.error(ex)
|
||||
|
||||
misperrors["error"] = ex.message
|
||||
return misperrors
|
||||
|
||||
|
||||
def introspection():
|
||||
return mispattributes
|
||||
|
||||
|
||||
def version():
|
||||
moduleinfo["config"] = moduleconfig
|
||||
return moduleinfo
|
Loading…
Reference in New Issue