MISP/misp-modules

Name: misp-modules

Owner: MISP Project

Description: Modules for expansion services, import and export in MISP

Created: 2016-02-17 15:06:08.0

Updated: 2018-01-12 18:01:57.0

Pushed: 2018-01-08 19:45:59.0

Homepage:

Size: 356

Language: Python

GitHub Committers

UserMost Recent Commit# Commits

Other Committers

UserEmailMost Recent Commit# Commits

README

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
Export modules
Import modules
How to install and start MISP modules?
 apt-get install python3-dev python3-pip libpq5 libjpeg-dev
usr/local/src/
 git clone https://github.com/MISP/misp-modules.git
isp-modules
 pip3 install -I -r REQUIREMENTS
 pip3 install -I .
 vi /etc/rc.local, add this line: `sudo -u www-data misp-modules -s &`
-modules #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:

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


# 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.

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

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.

nfig fields that your code expects from the site admin
leconfig = ["apikey", "event_limit"]

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:

a": {
  "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.

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.

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")}
Returning Binary Data

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

sults": {"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.

sults": {"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:

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:

rl -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:


ostname": "www.foo.be",
odule": "dns"

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

 -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:


esults": [
{
  "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):


esults": [
{
  "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

rity        Setting                         Value   Description                             Error Message
mmended     Plugin.Import_ocr_enabled       false   Enable or disable the ocr module.       Value not set.
rity        Setting                         Value   Description                             Error Message
mmended     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 necessery packages for example like this :

Use pip wheel to create an archive

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

On offline machine :

r misp-modules-bundle
xvf misp-module-bundeled.tar.bz2 -C misp-modules-bundle
isp-modules-bundle
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.

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.

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

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

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

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

 killall misp-modules
-modules -d

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

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

This work is supported by the National Institutes of Health's National Center for Advancing Translational Sciences, Grant Number U24TR002306. This work is solely the responsibility of the creators and does not necessarily represent the official views of the National Institutes of Health.