diff --git a/docs/tutorial/PyMISP_tutorial.ipynb b/docs/tutorial/PyMISP_tutorial.ipynb new file mode 100644 index 0000000..7fc32a1 --- /dev/null +++ b/docs/tutorial/PyMISP_tutorial.ipynb @@ -0,0 +1,364 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# PyMISP - An interactive tutorial: Basics" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Connecting to MISP\n", + "### Your configuration" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# The URL of the MISP instance to connect to\n", + "misp_url = 'http://127.0.0.1:9090/'\n", + "# Can be found in the MISP web interface under \n", + "# http://+MISP_URL+/users/view/me -> Authkey\n", + "misp_key = 'btm3o1j6SzKUEsHiNz0vTMYzPfcc5eIKpfaWFADj'\n", + "# Should PyMISP verify the MISP certificate\n", + "misp_verifycert = False" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from pymisp import PyMISP\n", + "\n", + "misp = PyMISP(misp_url, misp_key, misp_verifycert)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Creating a MISP Event" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Directly" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "event = misp.new_event(distribution=1,\n", + " threat_level_id=1,\n", + " analysis=1,\n", + " info=\"Event from notebook\")\n", + "print(\"Event id: %s\" % event['Event']['id'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Using the MISPEvent constructor" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from pymisp import MISPEvent\n", + "\n", + "event_obj = MISPEvent()\n", + "event_obj.distribution = 1\n", + "event_obj.threat_level_id = 1\n", + "event_obj.analysis = 1\n", + "event_obj.info = \"Event from notebook 2\"\n", + "event = misp.add_event(event_obj)\n", + "event_id = event['Event']['id']\n", + "print(\"Event id: %s\" % event_id)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Fetching a MISP Event" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Fetch by ID\n", + "event = misp.get_event(event_id)\n", + "print(event)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Adding Attribute to an event" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Adding directly" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "attr_type = \"ip-src\"\n", + "value = \"8.8.8.8\"\n", + "category = \"Network activity\"\n", + "to_ids = False\n", + "proposal = False\n", + "updated_event = misp.add_named_attribute(event,\n", + " attr_type,\n", + " value,\n", + " category=category,\n", + " to_ids=to_ids,\n", + " proposal=proposal)\n", + "print(updated_event)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Using the MISPAttribute constructor" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from pymisp import MISPAttribute\n", + "\n", + "# Attribute data already defined\n", + "attribute = MISPAttribute()\n", + "attribute.type = attr_type\n", + "attribute.value = value\n", + "attribute.category = category\n", + "attribute.proposal = proposal\n", + "print(attribute)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# An attribute can also be loaded directly from a JSON\n", + "json = '''{\n", + " \"type\": \"ip-dst\",\n", + " \"value\": \"127.0.0.1\",\n", + " \"category\": \"Network activity\",\n", + " \"to_ids\": false,\n", + " \"proposal\": false\n", + " }'''\n", + "\n", + "attribute = MISPAttribute()\n", + "attribute.from_json(json)\n", + "print(attribute)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### And then, update the event" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "# Add the attribute to the event\n", + "## Fetch the event from MISP\n", + "event_dict = misp.get(event_id)['Event']\n", + "\n", + "## Convert it to a PyMISP Event\n", + "event = MISPEvent()\n", + "event.from_dict(**event_dict)\n", + "## Let MISP update the timestamp. Otherwise, MISP will compare the two timestamps \n", + "## (which are equals) and reject the the update\n", + "del event.timestamp\n", + "\n", + "## Add the attribute to the event\n", + "event.attributes.append(attribute)\n", + "\n", + "## Push the updated event to MISP\n", + "event_dict = misp.update(event)\n", + "print(event_dict)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Performing search" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Events by their info fields" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "results = misp.search_index(eventinfo='notebook')\n", + "# The data is stored in the field 'response'\n", + "results = results['response']\n", + "\n", + "for event in results:\n", + " print(event['id'], ':', event['info'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Attributes by their values" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Search in all attributes" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "# Search attributes (specified in controller) where the attribute type is 'ip-src'\n", + "# And the to_ids flag is set\n", + "response = misp.search(controller='attributes', type_attribute='ip-src', to_ids=False)\n", + "# The data is stored in the field 'response'\n", + "results = response['response']\n", + "\n", + "# Get all related event\n", + "attributes = results['Attribute']\n", + "event_ids = set()\n", + "for attr in attributes:\n", + " event_ids.add(event_id)\n", + "\n", + "# Fetch all related events\n", + "for event_id in event_ids:\n", + " event = misp.get_event(event_id)\n", + " print(event['Event']['info'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Creating and adding a MISP Object" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from pymisp import MISPObject\n", + "\n", + "object_name = 'email'\n", + "object_data = {\n", + " 'from': 'admin@admin.test',\n", + " 'to': 'admin@foo.bar',\n", + " 'subject': 'An email',\n", + "}\n", + "\n", + "# Retreive the template ID from the object's name\n", + "## Fetch all templates\n", + "templates = misp.get_object_templates_list()\n", + "## Get the template matching with the object's name\n", + "template_id = None\n", + "for template in templates:\n", + " cur_name = template['ObjectTemplate']['name']\n", + " cur_id = template['ObjectTemplate']['id']\n", + " if cur_name == object_name:\n", + " template_id = cur_id\n", + " break \n", + "if template_id is None:\n", + " raise Exception('No matching template')\n", + "\n", + "# Create the MISP Object\n", + "misp_obj = MISPObject(object_name)\n", + "for obj_relation, value in object_data.items():\n", + " misp_obj.add_attribute(obj_relation, **{'value': value})\n", + "\n", + "# Add the object to MISP\n", + "response = misp.add_object(event_id,\n", + " template_id,\n", + " misp_obj)\n", + "print(response)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/tutorial/install_notebook.sh b/docs/tutorial/install_notebook.sh new file mode 100644 index 0000000..cd5f670 --- /dev/null +++ b/docs/tutorial/install_notebook.sh @@ -0,0 +1,2 @@ +pip3 install --upgrade pip +pip3 install jupyter