Skip to content

Commit

Permalink
Merge pull request #678 from ByronLabs/main
Browse files Browse the repository at this point in the history
Re-add Vysion
  • Loading branch information
adulau authored Aug 9, 2024
2 parents dd3ac91 + 7a3ab8e commit e0d44bd
Show file tree
Hide file tree
Showing 9 changed files with 264 additions and 1 deletion.
1 change: 1 addition & 0 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ Jinja2 = ">=3.1.2"
mattermostdriver = "7.3.2"
openpyxl = "*"
slack-sdk = "3.27.1"
vysion = "*"

[requires]
python_version = "3.12"
9 changes: 9 additions & 0 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions REQUIREMENTS
Original file line number Diff line number Diff line change
Expand Up @@ -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.7; python_version >= '3.8'
wand==0.6.13
websocket-client==1.8.0; python_version >= '3.8'
websockets==12.0; python_version >= '3.8'
Expand Down
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
20 changes: 20 additions & 0 deletions documentation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down
16 changes: 16 additions & 0 deletions documentation/website/expansion/vysion.json
Original file line number Diff line number Diff line change
@@ -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."
}
2 changes: 1 addition & 1 deletion misp_modules/modules/expansion/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
'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')
Expand Down
214 changes: 214 additions & 0 deletions misp_modules/modules/expansion/vysion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
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
from . import standard_error_message

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

0 comments on commit e0d44bd

Please sign in to comment.