Modules for expansion services, import and export in MISP http://misp.github.io/misp-modules
 
 
 
 
Go to file
Steve Clement 91f922b5c4 chg: [btc] Removed simple PoC for btc expansion. 2018-11-07 22:53:21 +09:00
doc chg: [doc] generated documentation updated 2018-11-06 07:31:55 +01:00
misp_modules chg: [btc] Removed simple PoC for btc expansion. 2018-11-07 22:53:21 +09:00
tests fix: Removed STIX related libraries, files, documentation, etc. 2018-06-11 17:03:23 +02:00
var default var directory added 2016-02-18 09:25:51 +01:00
.gitignore Added body.json to gitignore 2016-08-17 13:01:41 +01:00
.travis.yml remove the never release Python code in Travis 2018-07-12 14:29:04 +02:00
LICENSE Create LICENSE 2016-09-05 07:26:29 +02:00
README.md chg: [btc] Removed simple PoC for btc expansion. 2018-11-07 22:53:21 +09:00
README.rst Make it a package 2016-06-18 11:04:41 +09:00
REQUIREMENTS new: [btc] Very simple BTC expansion 2018-11-06 00:48:36 +09:00
setup.py fix: Removed STIX related libraries, files, documentation, etc. 2018-06-11 17:03:23 +02:00

README.md

MISP modules

Build Status Coverage Status codecov

MISP modules are autonomous modules that can be used for expansion and other services in MISP.

The modules are written in Python 3 following a simple API interface. The objective is to ease the extensions of MISP functionalities without modifying core components. The API is available via a simple REST API which is independent from MISP installation or configuration.

MISP modules support is included in MISP starting from version 2.4.28.

For more information: Extending MISP with Python modules slides from MISP training.

Existing MISP modules

Expansion modules

  • ASN History - a hover and expansion module to expand an AS number with the ASN description and its history.
  • BTC transactions - An expansion hover module to get a blockchain balance and the transactions from a BTC address in MISP.
  • CIRCL Passive DNS - a hover and expansion module to expand hostname and IP addresses with passive DNS information.
  • CIRCL Passive SSL - a hover and expansion module to expand IP addresses with the X.509 certificate seen.
  • countrycode - a hover module to tell you what country a URL belongs to.
  • CrowdStrike Falcon - an expansion module to expand using CrowdStrike Falcon Intel Indicator API.
  • CVE - a hover module to give more information about a vulnerability (CVE).
  • DBL Spamhaus - a hover module to check Spamhaus DBL for a domain name.
  • DNS - a simple module to resolve MISP attributes like hostname and domain to expand IP addresses attributes.
  • DomainTools - a hover and expansion module to get information from DomainTools whois.
  • EUPI - a hover and expansion module to get information about an URL from the Phishing Initiative project.
  • Farsight DNSDB Passive DNS - a hover and expansion module to expand hostname and IP addresses with passive DNS information.
  • GeoIP - a hover and expansion module to get GeoIP information from geolite/maxmind.
  • hashdd - a hover module to check file hashes against hashdd.com including NSLR dataset.
  • IPASN - a hover and expansion to get the BGP ASN of an IP address.
  • iprep - an expansion module to get IP reputation from packetmail.net.
  • macaddress.io - a hover module to retrieve vendor details and other information regarding a given MAC address or an OUI from MAC address Vendor Lookup. See integration tutorial here.
  • onyphe - a modules to process queries on Onyphe.
  • onyphe_full - a modules to process full queries on Onyphe.
  • OTX - an expansion module for OTX.
  • passivetotal - a passivetotal module that queries a number of different PassiveTotal datasets.
  • rbl - a module to get RBL (Real-Time Blackhost List) values from an attribute.
  • reversedns - Simple Reverse DNS expansion service to resolve reverse DNS from MISP attributes.
  • securitytrails - an expansion module for securitytrails.
  • shodan - a minimal shodan expansion module.
  • Sigma queries - Experimental expansion module querying a sigma rule to convert it into all the available SIEM signatures.
  • Sigma syntax validator - Sigma syntax validator.
  • sourcecache - a module to cache a specific link from a MISP instance.
  • STIX2 pattern syntax validator - a module to check a STIX2 pattern syntax.
  • ThreatCrowd - an expansion module for ThreatCrowd.
  • threatminer - an expansion module to expand from ThreatMiner.
  • virustotal - an expansion module to pull known resolutions and malware samples related with an IP/Domain from virusTotal (this modules require a VirusTotal private API key)
  • VMray - a module to submit a sample to VMray.
  • VulnDB - a module to query VulnDB.
  • whois - a module to query a local instance of uwhois.
  • wikidata - a wikidata expansion module.
  • xforce - an IBM X-Force Exchange expansion module.
  • YARA query - a module to create YARA rules from single hash attributes.
  • YARA syntax validator - YARA syntax validator.

Export modules

Import modules

  • CSV import Customizable CSV import module.
  • Cuckoo JSON Cuckoo JSON import.
  • Email Import Email import module for MISP to import basic metadata.
  • GoAML import Module to import GoAML XML format.
  • OCR Optical Character Recognition (OCR) module for MISP to import attributes from images, scan or faxes.
  • OpenIOC OpenIOC import based on PyMISP library.
  • ThreatAnalyzer - An import module to process ThreatAnalyzer archive.zip/analysis.json sandbox exports.
  • VMRay - An import module to process VMRay export.

How to install and start MISP modules in a Python virtualenv?

sudo apt-get install python3-dev python3-pip libpq5 libjpeg-dev tesseract-ocr imagemagick
sudo -u www-data virtualenv -p python3 /var/www/MISP/venv
cd /usr/local/src/
sudo git clone https://github.com/MISP/misp-modules.git
cd misp-modules
sudo -u www-data /var/www/MISP/venv/bin/pip install -I -r REQUIREMENTS
sudo -u www-data /var/www/MISP/venv/bin/pip install .
sudo apt install ruby-pygments.rb -y
sudo gem install asciidoctor-pdf --pre
sudo sed -i -e '$i \sudo -u www-data /var/www/MISP/venv/bin/misp-modules -l 127.0.0.1 -s > /tmp/misp-modules_rc.local.log &\n' /etc/rc.local
/var/www/MISP/venv/bin/misp-modules -l 127.0.0.1 -s & #to start the modules

How to install and start MISP modules?

sudo apt-get install python3-dev python3-pip libpq5 libjpeg-dev tesseract-ocr imagemagick
cd /usr/local/src/
sudo git clone https://github.com/MISP/misp-modules.git
cd misp-modules
sudo pip3 install -I -r REQUIREMENTS
sudo pip3 install -I .
sudo apt install ruby-pygments.rb -y
sudo gem install asciidoctor-pdf --pre
sudo sed -i -e '$i \sudo -u www-data /var/www/MISP/venv/bin/misp-modules -l 127.0.0.1 -s > /tmp/misp-modules_rc.local.log &\n' /etc/rc.local
/var/www/MISP/venv/bin/misp-modules -l 127.0.0.1 -s & #to start the modules

How to add your own MISP modules?

Create your module in misp_modules/modules/expansion/, misp_modules/modules/export_mod/, or misp_modules/modules/import_mod/. The module should have at minimum three functions:

  • introspection function that returns a dict of the supported attributes (input and output) by your expansion module.
  • handler function which accepts a JSON document to expand the values and return a dictionary of the expanded values.
  • version function that returns a dict with the version and the associated meta-data including potential configurations required of the module.

Don't forget to return an error key and value if an error is raised to propagate it to the MISP user-interface.

Your module's script name should also be added in the __all__ list of <module type folder>/__init__.py in order for it to be loaded.

...
    # Checking for required value
    if not request.get('ip-src'):
        # Return an error message
        return {'error': "A source IP is required"}
...

introspection

The function that returns a dict of the supported attributes (input and output) by your expansion module.

mispattributes = {'input': ['link', 'url'],
                  'output': ['attachment', 'malware-sample']}

def introspection():
    return mispattributes

version

The function that returns a dict with the version and the associated meta-data including potential configurations required of the module.

Additional Configuration Values

If your module requires additional configuration (to be exposed via the MISP user-interface), you can define those in the moduleconfig value returned by the version function.

# config fields that your code expects from the site admin
moduleconfig = ["apikey", "event_limit"]

def version():
    moduleinfo['config'] = moduleconfig
    return moduleinfo

When you do this a config array is added to the meta-data output containing all the potential configuration values:

"meta": {
      "description": "PassiveTotal expansion service to expand values with multiple Passive DNS sources",
      "config": [
        "username",
        "password"
      ],
      "module-type": [
        "expansion",
        "hover"
      ],

...

If you want to use the configuration values set in the web interface they are stored in the key config in the JSON object passed to the handler.

def handler(q=False):

    # Check if we were given a configuration
    config = q.get("config", {})

    # Find out if there is a username field
    username = config.get("username", None)

handler

The function which accepts a JSON document to expand the values and return a dictionary of the expanded values.

def handler(q=False):
    "Fully functional rot-13 encoder"
    if q is False:
        return False
    request = json.loads(q)
    src = request.get('ip-src')
    if src is None:
        # Return an error message
        return {'error': "A source IP is required"}
    else:
        return {'results':
                codecs.encode(src, "rot-13")}

export module

For an export module, the request["data"] object corresponds to a list of events (dictionaries) to handle.

Iterating over events attributes is performed using their Attribute key.

...
for event in request["data"]:
        for attribute in event["Attribute"]:
          # do stuff w/ attribute['type'], attribute['value'], ...
...

### Returning Binary Data

If you want to return a file or other data you need to add a data attribute.

~~~python
{"results": {"values": "filename.txt",
             "types": "attachment",
             "data"  : base64.b64encode(<ByteIO>)  # base64 encode your data first
             "comment": "This is an attachment"}}

If the binary file is malware you can use 'malware-sample' as the type. If you do this the malware sample will be automatically zipped and password protected ('infected') after being uploaded.

{"results": {"values": "filename.txt",
             "types": "malware-sample",
             "data"  : base64.b64encode(<ByteIO>)  # base64 encode your data first
             "comment": "This is an attachment"}}

To learn more about how data attributes are processed you can read the processing code here.

Module type

A MISP module can be of four types:

  • expansion - service related to an attribute that can be used to extend and update an existing event.
  • hover - service related to an attribute to provide additional information to the users without updating the event.
  • import - service related to importing and parsing an external object that can be used to extend an existing event.
  • export - service related to exporting an object, event, or data.

module-type is an array where the list of supported types can be added.

Testing your modules?

MISP uses the modules function to discover the available MISP modules and their supported MISP attributes:

% curl -s http://127.0.0.1:6666/modules | jq .
[
  {
    "name": "passivetotal",
    "type": "expansion",
    "mispattributes": {
      "input": [
        "hostname",
        "domain",
        "ip-src",
        "ip-dst"
      ],
      "output": [
        "ip-src",
        "ip-dst",
        "hostname",
        "domain"
      ]
    },
    "meta": {
      "description": "PassiveTotal expansion service to expand values with multiple Passive DNS sources",
      "config": [
        "username",
        "password"
      ],
      "author": "Alexandre Dulaunoy",
      "version": "0.1"
    }
  },
  {
    "name": "sourcecache",
    "type": "expansion",
    "mispattributes": {
      "input": [
        "link"
      ],
      "output": [
        "link"
      ]
    },
    "meta": {
      "description": "Module to cache web pages of analysis reports, OSINT sources. The module returns a link of the cached page.",
      "author": "Alexandre Dulaunoy",
      "version": "0.1"
    }
  },
  {
    "name": "dns",
    "type": "expansion",
    "mispattributes": {
      "input": [
        "hostname",
        "domain"
      ],
      "output": [
        "ip-src",
        "ip-dst"
      ]
    },
    "meta": {
      "description": "Simple DNS expansion service to resolve IP address from MISP attributes",
      "author": "Alexandre Dulaunoy",
      "version": "0.1"
    }
  }
]

The MISP module service returns the available modules in a JSON array containing each module name along with their supported input attributes.

Based on this information, a query can be built in a JSON format and saved as body.json:

{
  "hostname": "www.foo.be",
  "module": "dns"
}

Then you can POST this JSON format query towards the MISP object server:

curl -s http://127.0.0.1:6666/query -H "Content-Type: application/json" --data @body.json -X POST

The module should output the following JSON:

{
  "results": [
    {
      "types": [
        "ip-src",
        "ip-dst"
      ],
      "values": [
        "188.65.217.78"
      ]
    }
  ]
}

It is also possible to restrict the category options of the resolved attributes by passing a list of categories along (optional):

{
  "results": [
    {
      "types": [
        "ip-src",
        "ip-dst"
      ],
      "values": [
        "188.65.217.78"
      ],
      "categories": [
        "Network activity",
        "Payload delivery"
      ]
    }
  ]
}

For both the type and the category lists, the first item in the list will be the default setting on the interface.

Enable your module in the web interface

For a module to be activated in the MISP web interface it must be enabled in the "Plugin Settings.

Go to "Administration > Server Settings" in the top menu

  • Go to "Plugin Settings" in the top "tab menu bar"
  • Click on the name of the type of module you have created to expand the list of plugins to show your module.
  • Find the name of your plugin's "enabled" value in the Setting Column. "Plugin.[MODULE NAME]_enabled"
  • Double click on its "Value" column
Priority        Setting                         Value   Description                             Error Message
Recommended     Plugin.Import_ocr_enabled       false   Enable or disable the ocr module.       Value not set.
  • Use the drop-down to set the enabled value to 'true'
Priority        Setting                         Value   Description                             Error Message
Recommended     Plugin.Import_ocr_enabled       true   Enable or disable the ocr module.       Value not set.

Set any other required settings for your module

In this same menu set any other plugin settings that are required for testing.

Install misp-module on an offline instance.

First, you need to grab all necessary packages for example like this :

Use pip wheel to create an archive

mkdir misp-modules-offline
pip3 wheel -r REQUIREMENTS shodan --wheel-dir=./misp-modules-offline
tar -cjvf misp-module-bundeled.tar.bz2 ./misp-modules-offline/*

On offline machine :

mkdir misp-modules-bundle
tar xvf misp-module-bundeled.tar.bz2 -C misp-modules-bundle
cd misp-modules-bundle
ls -1|while read line; do sudo pip3 install --force-reinstall --ignore-installed --upgrade --no-index --no-deps ${line};done

Next you can follow standard install procedure.

How to contribute your own module?

Fork the project, add your module, test it and make a pull-request. Modules can be also private as you can add a module in your own MISP installation.

Tips for developers creating modules

Download a pre-built virtual image from the MISP training materials.

  • Create a Host-Only adapter in VirtualBox
  • Set your Misp OVA to that Host-Only adapter
  • Start the virtual machine
  • Get the IP address of the virutal machine
  • SSH into the machine (Login info on training page)
  • Go into the misp-modules directory
cd /usr/local/src/misp-modules

Set the git repo to your fork and checkout your development branch. If you SSH'ed in as the misp user you will have to use sudo.

sudo git remote set-url origin https://github.com/YourRepo/misp-modules.git
sudo git pull
sudo git checkout MyModBranch

Remove the contents of the build directory and re-install misp-modules.

sudo rm -fr build/*
sudo pip3 install --upgrade .

SSH in with a different terminal and run misp-modules with debugging enabled.

sudo killall misp-modules
misp-modules -d

In your original terminal you can now run your tests manually and see any errors that arrive

cd tests/
curl -s http://127.0.0.1:6666/query -H "Content-Type: application/json" --data @MY_TEST_FILE.json -X POST
cd ../

Documentation

In order to provide documentation about some modules that require specific input / output / configuration, the doc directory contains detailed information about the general purpose, requirements, features, input and ouput of each of these modules:

  • *description - quick description of the general purpose of the module, as the one given by the moduleinfo
  • requirements - special libraries needed to make the module work
  • features - description of the way to use the module, with the required MISP features to make the module give the intended result
  • references - link(s) giving additional information about the format concerned in the module
  • input - description of the format of data used in input
  • output - description of the format given as the result of the module execution