Remove a tag from an existing event. Note that removing a tag collection in one go is not possible.
Examples:
curl \
-d '{"event":"1210","tag":"tlp:amber"}' \
-H "Authorization: YOUR API KEY" \
-H "Accept: application/json" \
-H "Content-type: application/json" \
-X POST https://192.168.0.223/events/removeTag
curl \
-d '{"event":"1210","tag":"987"}' \
-H "Authorization: YOUR API KEY" \
-H "Accept: application/json" \
-H "Content-type: application/json" \
-X POST https://192.168.0.223/events/removeTag
Will give an overview of the used attribute types
{
"attachment": "1",
"comment": "1",
"filename": "2",
"float": "2",
"ip-dst": "90",
"ip-dst|port": "3",
"link": "3",
"md5": "16",
"port": "3",
"sha1": "2",
"sha256": "2",
"size-in-bytes": "1",
"ssdeep": "2"
}
curl --header "Authorization: YOUR API KEY " --header "Accept: application/json" --header "Content-Type: application/json" -X GET http://10.50.13.60/attributes/attributeStatistics/
MISP can procedurally describe all attribute types and attribute categories it currently supports including the category - type mappings. To access this information simply send a GET request to:
https://<misp url>/attributes/describeTypes
Depending on the headers passed the returned data will be a JSON object or an XML, with 3 main sections: types, categories, category_type_mappings.
Do not use this function with GET!
{
"returnFormat": "json",
"tags": {
"NOT": [
"tlp:red"
],
"OR": [
"tlp:green"
]
}
}
{
"returnFormat": "json",
"threat_level_id": [1,2]
}
"Event": {
"id": "31",
"orgc_id": "1",
"org_id": "1",
"date": "2021-03-11",
"threat_level_id": "1",
"info": "Correlation 2",
"published": true,
"uuid": "0bfe7bf3-f793-4761-8450-8b30ca9d9964",
"analysis": "0",
"timestamp": "1616972381",
"distribution": "1",
"publish_timestamp": "1616972392",
"sharing_group_id": "0",
"extends_uuid": "",
"Tag": [],
"Orgc": {
"id": "1",
"name": "SHARINGORG",
"uuid": "26867ddf-5a9b-4af0-b552-e4020a913b95",
"local": true
}
}
"warnings": [
{
"match": "10.0.0.0/8",
"value": "10.0.0.1",
"warninglist_name": "List of RFC 5735 CIDR blocks",
"warninglist_id": "46"
},
{
"match": "10.0.0.0/8",
"value": "10.0.0.1",
"warninglist_name": "List of RFC 1918 CIDR blocks",
"warninglist_id": "44"
}
]
{
"returnFormat": "json",
"object_relation": ["malware-sample", "institution-name"]
}
"Sighting": [
{
"id": "1",
"attribute_id": "29",
"event_id": "31",
"org_id": "1",
"date_sighting": "1617017091",
"uuid": "48d21518-6b2a-4615-8c4e-91fbe4f08fe7",
"source": "",
"type": "0",
"attribute_uuid": "b3c25257-7f47-41af-a29b-89188e583b5c",
"Organisation": {
"id": "1",
"uuid": "26867ddf-5a9b-4af0-b552-e4020a913b95",
"name": "SHARINGORG"
}
}
]
"RelatedAttribute": [
{
"id": "31",
"event_id": "30",
"object_id": "0",
"object_relation": null,
"category": "Network activity",
"type": "ip-dst",
"uuid": "f3b54c94-89ff-4fcf-9f47-52f70c6540b8",
"timestamp": "1616961683",
"distribution": "5",
"sharing_group_id": "0",
"to_ids": false,
"comment": "",
"value": "10.0.0.1",
"Event": {
"id": "30",
"uuid": "8cca9f2f-9281-49fd-9b30-e16a8dbf6855",
"threat_level_id": "1",
"analysis": "0",
"info": "Correlation 1",
"extends_uuid": "",
"distribution": "1",
"sharing_group_id": "0",
"published": false,
"date": "2021-03-11",
"orgc_id": "1",
"org_id": "1"
}
}
]
"decay_score": [
{
"score": 77.40239901751683,
"base_score": 80,
"decayed": false,
"DecayingModel": {
"id": "2",
"name": "NIDS Simple Decaying Model"
}
}
],
{
"type": "ip-src",
"tags": ["tlp:%","phishing:%"],
"includeDecayScore": 1,
"excludeDecayed": 1,
"modelOverrides": {
"threshold": 30
}
"decayingModel": [84, 12],
}
curl \
-d '{"returnFormat":"json","value":"foobar"}' \
-H "Authorization: YOUR API KEY" \
-H "Accept: application/json" \
-H "Content-type: application/json" \
-X POST https://192.168.0.220/attributes/restSearch
{"response": {"Attribute": [{"id":"44","event_id":"30","object_id":"0","object_relation":null,"category":"Other","type":"comment","to_ids":false,"uuid":"7a5d856c-048a-4dbd-8e6d-41d1790c5ad0","timestamp":"1617056037","distribution":"5","sharing_group_id":"0","comment":"","deleted":false,"disable_correlation":false,"first_seen":null,"last_seen":null,"value":"foobar","Event":{"org_id":"1","distribution":"1","id":"30","info":"Correlation 1","orgc_id":"1","uuid":"8cca9f2f-9281-49fd-9b30-e16a8dbf6855"}}]}}
Delete an object.
curl \
-d '{}' \
-H "Authorization: YOUR API KEY" \
-H "Accept: application/json" \
-H "Content-type: application/json" \
-X POST https://192.168.0.223/objects/delete/18732/1
{"version":"2.4.85"}
curl --header "Authorization: YOUR API KEY " --header "Accept: application/json" --header "Content-Type: application/json" http://10.50.13.60/servers/getPyMISPVersion.json
{"version":"2.4.85","perm_sync":true}
curl --header "Authorization: YOUR API KEY " --header "Accept: application/json" --header "Content-Type: application/json" http://10.50.13.60/servers/getPyMISPVersion.json
The different sightings types are:
0 => 'sighting',
1 => 'false-positive',
2 => 'expiration'
MISP allows administrators to create and manage users via its REST API
https://<misp url>/admin/users/view/[user id]
To create a new user, send a POST request to:
{
"email":"andras.iklody@circl.lu",
"org\_id":1,
"role\_id":1
}
To view the mandatory and optional fields, use a GET request on the above URL.
{
"name": "\/admin\/users\/add API description",
"description": "POST a User object in JSON format to this API to create a new user.",
"mandatory_fields": [
"email",
"org_id",
"role_id"
],
"optional_fields": [
"password",
"external_auth_required",
"external_auth_key",
"enable_password",
"nids_sid",
"server_id",
"gpgkey",
"certif_public",
"autoalert",
"contactalert",
"disabled",
"change_pw",
"termsaccepted",
"newsread"
],
"url": "\/admin\/users\/add"
}
To edit an existing user send a POST request to:
https://<misp url>/admin/users/edit/[user id]
Only the fields POSTed will be updated, the rest is left intact. To view all possible parameters, simply send a GET request to the above URL.
You can also delete users by POSTing to the below URL, but keep in mind that disabling users (by setting the disabled flag via an edit) is always preferred to keep user associations to events intact.
https://<misp url>/admin/users/delete/[user id]
Will output all users
[
{
"User": {
"id": "1",
"password": "FOOOOOOOOOO",
"org_id": "1",
"server_id": "0",
"email": "admin@admin.test",
"autoalert": false,
"authkey": "YOUR API KEY",
"invited_by": "0",
"gpgkey": null,
"certif_public": "",
"nids_sid": "4000000",
"termsaccepted": true,
"newsread": "0",
"role_id": "1",
"change_pw": "0",
"contactalert": false,
"disabled": false,
"expiration": null,
"current_login": "1515752313",
"last_login": "1515748671",
"force_logout": false,
"date_created": null,
"date_modified": null,
"org_ci": "ORGNAME"
},
"Role": {
"id": "1",
"name": "admin",
"perm_auth": true
},
"Organisation": {
"id": "1",
"name": "ORGNAME"
}
}
]
curl --header "Authorization: YOUR API KEY " --header "Accept: application/json" --header "Content-Type: application/json" -X GET http://10.50.13.60/admin/users
Will return a single user. To view a user simply send a GET request.
{
"User": {
"id": "1",
"password": "*****",
"org_id": "1",
"server_id": "0",
"email": "admin@admin.test",
"autoalert": false,
"authkey": "YOUR API KEY",
"invited_by": "0",
"gpgkey": null,
"certif_public": "",
"nids_sid": "4000000",
"termsaccepted": true,
"newsread": "0",
"role_id": "1",
"change_pw": "0",
"contactalert": false,
"disabled": false,
"expiration": null,
"current_login": "1515752313",
"last_login": "1515748671",
"force_logout": false,
"orgAdmins": []
}
}
curl --header "Authorization: YOUR API KEY " --header "Accept: application/json" --header "Content-Type: application/json" -X GET http://10.50.13.60/admin/users/view/1
If you would like to fetch a discussion thread including all of its posts, simply send a GET request to:
https://<misp url>/threads/view/<thread id>
Using the following headers:
Authorization: [Your auth key]
Content-type: application/json
Accept: application/json
To get all posts related to an event simply send a GET request to:
https://<misp url>/threads/viewEvent/<event id>
MISP allows administrators to create and manage organisations via its REST API
The API is available in JSON format so make sure you use the following headers:
Authorization: [Your auth key]
Content-type: application/json
Accept: application/json
To fetch all organisations send a GET request to:
https://<misp url>/organisations
To view an individual organisation, send a get request to:
https://<misp url>/organisations/view/id
The management of users happens via three apis:
https://<misp url>/admin/organisations/add
https://<misp url>/admin/organisations/edit/[org id]
https://<misp url>/admin/organisations/delete/[org id]
To delete an organisation simply send a POST or DELETE request to the above URL.
For creating or modifying an organisation, simply POST a JSON containing the relevant fields to the appropriate API. The only mandatory field is the organisation name, with a host of optional parameters
An example for a simple organisation object:
{
"name": "Blizzard",
"nationality": "US"
}
Not setting a field will assume the default settings for the given field in the case of a new organisation whilst it would retain the existing setting for existing organisations. The above example would create the following object in MISP:
{
"Organisation": {
"id": "1108",
"name": "Blizzard",
"alias": "",
"anonymise": false,
"date_created": "2017-01-22 17:32:29",
"date_modified": "2017-01-22 17:32:29",
"description": "",
"type": "",
"nationality": "US",
"sector": "",
"created_by": "1",
"uuid": "5884de9d-04f0-4d7d-bf15-0b88c0a83865",
"contacts": "",
"local": true,
"landingpage": ""
}
}
To query the add or edit APIs for the valid parameters, simply send a GET requests to either API. The result currently looks like this (which might change when new fields are added):
{
"name": "\/admin\/organisations\/add API description",
"description": "POST an Organisation object in JSON format to this API to create a new organisation.",
"mandatory_fields": [
"name"
],
"optional_fields": [
"anonymise",
"description",
"type",
"nationality",
"sector",
"uuid",
"contacts",
"local"
],
"url": "\/admin\/organisations\/add"
}
An automatic export of all events and attributes (except file attachments) is available under a custom XML format.
You can configure your tools to automatically download the following file:
https://<misp url>/events/xml/download
If you only want to fetch a specific event append the eventid number:
https://<misp url>/events/xml/download/1
You can post an XML or JSON object containing additional parameters in the JSON query format or XML query format. Query parameters provide a way to filter the output to specific parameters.
The URL is appended with json:
https://<misp url>/events/xml/download.json
The query parameters can be the following:
{"request": {"eventid":["!51","!62"],"withAttachment":false,"tags":["APT1","!OSINT"],"from":false,"to":"2015-02-15"}}
The URL is path is:
https://<misp url>/events/xml/download
The query parameters can be the following:
<request><eventid>!51</eventid><eventid>!62</eventid><withAttachment>false</withAttachment><tags>APT1</tags><tags>!OSINT</tags><from>false</from><to>2015-02-15</to></request>
The XML download also accepts two additional the following optional parameters in the url:
https://<misp url>/events/xml/download/[eventid]/[withattachments]/[tags]/[from]/[to]/[last]
https://<misp url>/events/xml/download/false/true/tag1&&tag2&&!tag3
The keywords false or null should be used for optional empty parameters in the URL. Also check out the User Guide to read about the REST API.
An automatic export of attributes is available as CSV. Only attributes that are flagged "to_ids" will get exported.
You can configure your tools to automatically download the following file:
https://<misp url>/events/csv/download
This will download all the valid attributes in your MISP instance (might take some time).
You can also configure your tools to download the attributes from a specific event. Here is the old legacy CSV export that will work like exporting all attributes:
https://<misp url>/events/csv/download/<event-id>
You can specify additional flags for CSV exports as follows:
POST to:
https://<misp url>/events/csv/download
Headers:
Authorization: <your auth key>
Content-type: application/json
Body:
{"parameter1":"value1", "parameter2":1, "parameter3":["value3", "value4", "!value5"]}
For example, to only download a csv generated of the "domain" type and the "Network activity" category attributes all events except for the one and further restricting it to events that are tagged "tag1" or "tag2" but not "tag3", only allowing attributes that are IDS flagged use the following syntax:
POST to:
https://<misp url>/events/csv/download
Headers:
Authorization: <your auth key>
Content-type: application/json
Body:
{"tags":["tag1", "tag2", "!tag3"], "category":"Network activity", "type": "domain"}
Alternatively you can fall back to the deprecated syntax of passing parameters in a GET request via the URL, however this is discouraged:
https://<misp url>/events/csv/download/[eventid]/[ignore]/[tags]/[category]/[type]/[includeContext]/[from]/[to]/[last]
If you use the deprecated URL parameter method, keep in mind that the keywords false or null should be used for optional empty parameters. To export the attributes of all events that are of the type "domain", use the following syntax:
https://<misp url>/events/csv/download/false/false/false/false/domain
Since version 2.4.82, the new export format allows to select more columns using the following query format:
https://<misp-instance>/events/csv/download/<event-id>?attributes=timestamp,type,uuid,value
The order of columns will be honoured including those related to object level information.
To select object level columns, simply prepend the given object column's name by object_, such as:
https://<misp-instance>/events/csv/download/<event-id>?attributes=timestamp,type,uuid,value&object_attributes=uuid,name
The following columns will be returned (all columns related to objects will be prefixed with object_):
timestamp,type,uuid,value,object_uuid,object_name
includeContext option includes the tags for the event for each line.
You can export RPZ zone files for DNS level firewall by using the RPZ export functionality of MISP. The file generated will include all of the IDS flagged domain, hostname and IP-src/IP-dst attribute values that you have access to.
It is possible to further restrict the exported values using the following filters:
MISP will inject header values into the zone file as well as define the action taken for each of the values that can all be overwritten. By default these values are either the default values shipped with the application, or ones that are overwritten by your site administrator. The values are as follows:
| Value name | Default value |
|---|---|
| RPZ_policy | DROP |
| RPZ_walled_garden | 127.0.0.1 |
| RPZ_serial | $date00 |
| RPZ_refresh | 2h |
| RPZ_retry | 30m |
| RPZ_expiry | 30d |
| RPZ_minimum_ttl | 1h |
| RPZ_ttl | 1w |
| RPZ_ns | localhost. |
| RPZ_ns_alt | |
| RPZ_email | root.localhost |
To override the above values, either use the URL parameters as described below:
https://<misp url>/attributes/rpz/download/[tags]/[eventId]/[from]/[to]/[policy]/[walled_garden]/[ns]/[ns_alt]/[email]/[serial]/[refresh]/[retry]/[expiry]/[minim
um_ttl]/[ttl]
Or POST an XML or JSON object with the above listed options:
<request><tags>OSINT&&!OUTDATED</tags><policy>walled-garden</policy><walled_garden>teamliquid.net</walled_garden><refresh>5h</refresh></request>
{"request": {"tags": ["OSINT", "!OUTDATED"], "policy": "walled-garden", "walled_garden": "teamliquid.net", "refresh": "5h"}
An export of all attributes of a specific type to a plain text file. By default only published and IDS flagged attributes are exported.
You can configure your tools to automatically download the following files:
https://<misp url>/attributes/text/download/md5
https://<misp url>/attributes/text/download/sha1
https://<misp url>/attributes/text/download/sha256
https://<misp url>/attributes/text/download/filename
https://<misp url>/attributes/text/download/filename|md5
https://<misp url>/attributes/text/download/filename|sha1
https://<misp url>/attributes/text/download/filename|sha256
https://<misp url>/attributes/text/download/ip-src
https://<misp url>/attributes/text/download/ip-dst
https://<misp url>/attributes/text/download/hostname
https://<misp url>/attributes/text/download/domain
https://<misp url>/attributes/text/download/email-src
https://<misp url>/attributes/text/download/email-dst
https://<misp url>/attributes/text/download/email-subject
https://<misp url>/attributes/text/download/email-attachment
https://<misp url>/attributes/text/download/url
https://<misp url>/attributes/text/download/http-method
https://<misp url>/attributes/text/download/user-agent
https://<misp url>/attributes/text/download/regkey
https://<misp url>/attributes/text/download/regkey|value
https://<misp url>/attributes/text/download/AS
https://<misp url>/attributes/text/download/snort
https://<misp url>/attributes/text/download/pattern-in-file
https://<misp url>/attributes/text/download/pattern-in-traffic
https://<misp url>/attributes/text/download/pattern-in-memory
https://<misp url>/attributes/text/download/yara
https://<misp url>/attributes/text/download/vulnerability
https://<misp url>/attributes/text/download/attachment
https://<misp url>/attributes/text/download/malware-sample
https://<misp url>/attributes/text/download/link
https://<misp url>/attributes/text/download/comment
https://<misp url>/attributes/text/download/text
https://<misp url>/attributes/text/download/other
https://<misp url>/attributes/text/download/named pipe
https://<misp url>/attributes/text/download/mutex
https://<misp url>/attributes/text/download/target-user
https://<misp url>/attributes/text/download/target-email
https://<misp url>/attributes/text/download/target-machine
https://<misp url>/attributes/text/download/target-org
https://<misp url>/attributes/text/download/target-location
https://<misp url>/attributes/text/download/target-external
To restrict the results by tags, use the usual syntax. Please be aware the colons (:) cannot be used in the tag search. Use semicolons instead (the search will automatically search for colons instead). To get ip-src values from events tagged tag1 but not tag2 use:
https://<misp url>/attributes/text/download/ip-src/tag1&&
It is possible to restrict the text exports on additional flags. The first allows the user to restrict based on event ID, whilst the second is a boolean switch allowing non IDS flagged attributes to be exported. Additionally, choosing "all" in the type field will return all eligible attributes.
https://<misp url>/attributes/text/download/[type]/[tags]/[event_id]/[allowNonIDS]/[from]/[to]/[last]
For example, to include tag1 and tag2 but exclude tag3 you would use:
https://<misp url>/attributes/text/download/all/tag1&&tag2&&!tag3
The keywords false or null should be used for optional empty parameters in the URL.
For example, to retrieve all attributes for event #5, including non IDS marked attributes too, use the following line:
https://<misp url>/attributes/text/download/all/null/5/true
It is possible to search the database for attributes based on a list of criteria.
To return an event with all of its attributes, relations, shadowAttributes, use the following syntax:
https://<misp url>/events/restSearch/download/[value]/[type]/[category]/[org]/[tag]/[quickfilter]/[from]/[to]/[last]/[eventid]/[withAttachments]/[metadata]/[uuid]
For example, to include tag1 and tag2 but exclude tag3 you would use:
https://<misp url>/events/restSearch/download/null/null/null/null/tag1&&tag2&&!tag3
The keywords false or null should be used for optional empty parameters in the URL.
For example, to find any event with the term "red october" mentioned, use the following syntax (the example is shown as a POST request instead of a GET, which is highly recommended):
POST to:
https://<misp url>/events/restSearch/download
POST message payload (XML):
<request><value>red october</value><searchall>1</searchall><eventid>!15</eventid></request>
POST message payload (JSON):
{"request": {"value":"red october","searchall":1,"eventid":"!15"}}
To just return a list of attributes, use the following syntax:
The keywords false or null should be used for optional empty parameters in the URL.
https://<misp url>/attributes/restSearch/download/[value]/[type]/[category]/[org]/[tag]/[from]/[to]/[last]/[eventid]/[withattachments]/[uuid]
Value, type, category and org are optional. It is possible to search for several terms in each category by joining them with the '&&' operator. It is also possible to negate a term with the '!' operator. Please be aware the colons (:) cannot be used in the tag search. Use semicolons instead (the search will automatically search for colons instead). For example, in order to search for all attributes created by your organisation that contain 192.168 or 127.0 but not 0.1 and are of the type ip-src, excluding the events that were tagged tag1 use the following syntax:
https://<misp url>/attributes/restSearch/download/192.168&&127.0&&!0.1/ip-src/false/CIRCL/!tag1
You can also use search for IP addresses using CIDR. Make sure that you use '|' (pipe) instead of '/' (slashes). Please be aware the colons (:) cannot be used in the tag search. Use semicolons instead (the search will automatically search for colons instead). See below for an example:
https://<misp url>/attributes/restSearch/download/192.168.1.1|16/ip-src/null/CIRCL
If you want to export all attributes of a pre-defined type that belong to an event, use the following syntax:
https://<misp url>/attributes/returnAttributes/download/[id]/[type]/[sigOnly]
sigOnly is an optional flag that will block all attributes from being exported that don't have the IDS flag turned on. It is possible to search for several types with the '&&' operator and to exclude values with the '!' operator. For example, to get all IDS signature attributes of type md5 and sha256, but not filename|md5 and filename|sha256 from event 25, use the following:
https://<misp url>/attributes/returnAttributes/download/25/md5&&sha256&&!filename/true
As described in the REST section, it is possible to retrieve a list of events along with their metadata by sending a GET request to the /events API. However, this API in particular is a bit more versatile. You can pass search parameters along to search among the events on various fields and retrieve a list of matching events (along with their metadata). Use the following URL:
https://<misp url>/events/index
POST a JSON object with the desired lookup fields and values to receive a JSON back. An example for a valid lookup:
Authorization: <your API key>
Accept: application/json
Content-type: application/json
Body:
{"searchinfo":"Locky", "searchpublished":1, "searchdistribution":0}
The list of valid parameters:
If you know the attribute ID of a malware-sample or an attachment, you can download it with the following syntax:
https://<misp url>/attributes/downloadAttachment/download/[Attribute_id]
You can also download samples by knowing its MD5 hash. Simply pass the hash along as a JSON/XML object or in the URL (with the URL having overruling the passed objects) to receive a JSON/XML object back with the zipped sample base64 encoded along with some contextual information.
You can also use this API to get all samples from events that contain the passed hash. For this functionality, just pass the "allSamples" flag along. Note that if you are getting all samples from matching events, you can use all supported hash types (md5, sha1, sha256) for the lookup.
You can also get all the samples from an event with a given event ID, by passing along the eventID parameter. Make sure that either an event ID or a hash is passed along, otherwise an error message will be returned. Also, if no hash is set, the allSamples flag will get set automatically.
https://
POST message payload (XML):
<request><hash>7c12772809c1c0c3deda6103b10fdfa0</hash><allSamples>1</allSamples><eventID>13</eventID</request>
POST message payload (json):
{"request": {"hash": "7c12772809c1c0c3deda6103b10fdfa0", "allSamples": 1, "eventID": 13}}
A description of all the parameters in the passed object:
https://<misp url>/events/upload_sample/[Event_id]
This API will allow you to populate an event that you have modify rights to with malware samples (and all related hashes). Alternatively, if you do not supply an event ID, it will create a new event for you.
The files have to be base64 encoded and POSTed as explained below. All samples will be zipped and password protected (with the password being "infected"). The hashes of the original file will be captured as additional attributes.
For sample upload (for objects in general) there is no check for duplicates.
The event ID is optional. MISP will accept either a JSON or an XML object posted to the above URL.
The general structure of the expected objects is as follows:
{"request": {"files": [{"filename": filename1, "data": base64encodedfile1}, {"filename": filename2, "data": base64encodedfile2}],
"optional_parameter1", "optional_parameter2", "optional_parameter3"}}
JSON:
{"request":{"files": [{"filename": "test1.txt", "data": "dGVzdA=="}, {"filename": "test2.txt", "data": "dGVzdDI="}], "distribution": 1, "info" : "test", "event_id": 15}}
XML:
<request><files><filename>test3.txt</filename><data>dGVzdA==</data></files><files><filename>test4.txt</filename><data>dGVzdDI=</data></files><info>test</info><distribution>1</distribution><event_id>15</event_id></request>
The following optional parameters are expected:
The threat_level_id is mapped as such:
0 = high
1 = medium
2 = low
3 = undefined
You can interact with the proposals via the API directly since version 2.3.148.
| HTTP | URL | Explanation | Expected Payload | Response |
|---|---|---|---|---|
| GET | /shadow_attributes/view/[proposal_id] | View a proposal | N/A | ShadowAttribute object |
| POST | /shadow_attributes/add/[event_id] | Propose a new attribute to an event | ShadowAttribute object | ShadowAttribute object |
| POST | /shadow_attributes/edit/[attribute_id] | Propose an edit to an attribute | ShadowAttribute object | ShadowAttribute object |
| POST | /shadow_attributes/accept/[proposal_id] | Accept a proposal | N/A | Message |
| POST | /shadow_attributes/discard/[proposal_id] | Discard a proposal | N/A | Message |
When posting a shadow attribute object, use the following format
JSON:
{"request": {"ShadowAttribute": {"value": "5.5.5.5", "to_ids": false, "type": "ip-dst", "category": "Network activity"}}}
XML:
<request><ShadowAttribute><value>5.5.5.5</value><to_ids>0</to_ids><type>ip-src</type><category>Network activity</category></ShadowAttribute></request>
None of the above fields are mandatory, but at least one of them has to be provided.
MISP allows sharing groups to be retrieved via the API.
https://<misp url>/sharing_groups/index.json
Based on the API key used, the list of visible sharing groups will be returned in a JSON file. The JSON includes the organization parts of a given sharing group along with the associated server.
The MISP feeds can be enabled via the API.
A feed can be enabled by POSTing on the following URL (feed_id is the id of the feed):
/feeds/enable/feed_id
A feed can be disabled by POSTing on the following URL (feed_id is the id of the feed):
/feeds/disable/feed_id
All feeds can cached via the API:
/feeds/cacheFeeds/all
or you can replace all by the feed format to fetch like misp or freetext. all can be replaced
with the id value of the feed to fetch a specific feed.
To fetch a feed or all feeds:
/feeds/fetchFromFeed/feed_id
/feeds/fetchFromAllFeeds
This API can be also used to download feeds at regular interval via cronjobs or alike.
MISP allows Sightings data to be conveyed in several ways.
The most basic way is to POST a blank message to the Sightings API with the attribute ID or attribute UUID. This will create a sightings entry with the creation of the entry as the timestamp for the organisation of the authenticated user.
https://<misp url>/sightings/add/[attribute_id]
https://<misp url>/sightings/add/[attribute_uuid]
Alternatively, it is possible to POST a JSON object and gain additional granularity. The following fields are recognised by the API:
Some examples:
To create a sighting for attribute #9001:
{"id":"9001"}
To create a sighting for any attribute with the value being teamliquid.net or 173.231.136.216 with the time of sighting being :
{"values":["teamliquid.net", "173.231.136.216"], "timestamp":1460558710}
It is also possible to POST a STIX indicator with sighting data to the following URL (keep in mind that the content type has to be XML):
https://<misp url>/sightings/add/stix
MISP will use the sightings related observables to gather all values and create sightings for each attribute that matches any of the values. If no related observables are provided in the Sighting object, then MISP will fall back to the Indicator itself and use its observables' values to create the sightings. The time of the sighting is the current time, unless the timestamp attribute is set on the Sightings object, in which case that is taken.
An example STIX sightings document:
<stix:STIX_Package
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:stix="http://stix.mitre.org/stix-1"
xmlns:indicator="http://stix.mitre.org/Indicator-2"
xmlns:stixCommon="http://stix.mitre.org/common-1"
xmlns:cybox="http://cybox.mitre.org/cybox-2"
xmlns:AddressObject="http://cybox.mitre.org/objects#AddressObject-2"
xmlns:DomainNameObj="http://cybox.mitre.org/objects#DomainNameObject-1"
xmlns:cyboxVocabs="http://cybox.mitre.org/default_vocabularies-2"
xmlns:stixVocabs="http://stix.mitre.org/default_vocabularies-1"
xmlns:example="http://example.com/"
xsi:schemaLocation="
http://stix.mitre.org/stix-1 ../stix_core.xsd
http://stix.mitre.org/Indicator-2 ../indicator.xsd
http://cybox.mitre.org/objects#DomainNameObject-1 http://cybox.mitre.org/XMLSchema/objects/Domain_Name/1.0/Domain_Name_Object.xsd
http://stix.mitre.org/common-1 http://stix.mitre.org/XMLSchema/common/1.1.1/stix_common.xsd
http://cybox.mitre.org/default_vocabularies-2 ../cybox/cybox_default_vocabularies.xsd
http://stix.mitre.org/default_vocabularies-1 ../stix_default_vocabularies.xsd
http://cybox.mitre.org/objects#AddressObject-2 ../cybox/objects/Address_Object.xsd"
id="example:STIXPackage-33fe3b22-0201-47cf-85d0-97c02164528d"
timestamp="2014-05-08T09:00:00.000000Z"
version="1.1.1"
>
<stix:STIX_Header>
<stix:Title>Example watchlist that contains IP information.</stix:Title>
<stix:Package_Intent xsi:type="stixVocabs:PackageIntentVocab-1.0">Indicators - Watchlist</stix:Package_Intent>
</stix:STIX_Header>
<stix:Indicators>
<stix:Indicator xsi:type="indicator:IndicatorType" id="example:Indicator-2e20c5b2-56fa-46cd-9662-8f199c69d2c9" timestamp="2014-05-08T09:00:00.000000Z">
<indicator:Type xsi:type="stixVocabs:IndicatorTypeVocab-1.1">Domain Watchlist</indicator:Type>
<indicator:Observable id="example:Observable-87c9a5bb-d005-4b3e-8081-99f720fad62b">
<cybox:Object id="example:Object-12c760ba-cd2c-4f5d-a37d-18212eac7928">
<cybox:Properties xsi:type="DomainNameObj:DomainNameObjectType" type="FQDN">
<DomainNameObj:Value condition="Equals" apply_condition="ANY">malicious1.example.com##comma##malicious2.example.com##comma##malicious3.example.com</DomainNameObj:Value>
</cybox:Properties>
</cybox:Object>
</indicator:Observable>
<indicator:Sightings>
<indicator:Sighting timestamp="2014-05-08T09:00:00.000000Z">
<indicator:Source>
<stixCommon:Identity>
<stixCommon:Name>FooBar Inc.</stixCommon:Name>
</stixCommon:Identity>
</indicator:Source>
<indicator:Related_Observables>
<indicator:Related_Observable>
<stixCommon:Observable id="example:Observable-45b3acdf-1888-4bcc-89a9-6d9f8116fede">
<cybox:Object id="example:Object-a3d36250-42fa-4653-9172-87b87598390c">
<cybox:Properties xsi:type="DomainNameObj:DomainNameObjectType" type="FQDN">
<DomainNameObj:Value>malicious2.example.com</DomainNameObj:Value>
</cybox:Properties>
</cybox:Object>
</stixCommon:Observable>
</indicator:Related_Observable>
</indicator:Related_Observables>
</indicator:Sighting>
</indicator:Sightings>
</stix:Indicator>
</stix:Indicators>
</stix:STIX_Package>
POSTing this as the message's body to MISP will sight any attributes visible to the user with he value "malicious2.example.com". For composite types, a match on a component will also trigger a sighting (so for example for attributes of type domain|ip a domain match would be sufficient).
If no Related observables are set in the Sighting itself, MISP will fall back to the observable directly contained in the indicator. So in the following example:
<stix:STIX_Package
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:stix="http://stix.mitre.org/stix-1"
xmlns:indicator="http://stix.mitre.org/Indicator-2"
xmlns:stixCommon="http://stix.mitre.org/common-1"
xmlns:cybox="http://cybox.mitre.org/cybox-2"
xmlns:AddressObject="http://cybox.mitre.org/objects#AddressObject-2"
xmlns:DomainNameObj="http://cybox.mitre.org/objects#DomainNameObject-1"
xmlns:cyboxVocabs="http://cybox.mitre.org/default_vocabularies-2"
xmlns:stixVocabs="http://stix.mitre.org/default_vocabularies-1"
xmlns:example="http://example.com/"
xsi:schemaLocation="
http://stix.mitre.org/stix-1 ../stix_core.xsd
http://stix.mitre.org/Indicator-2 ../indicator.xsd
http://cybox.mitre.org/objects#DomainNameObject-1 http://cybox.mitre.org/XMLSchema/objects/Domain_Name/1.0/Domain_Name_Object.xsd
http://stix.mitre.org/common-1 http://stix.mitre.org/XMLSchema/common/1.1.1/stix_common.xsd
http://cybox.mitre.org/default_vocabularies-2 ../cybox/cybox_default_vocabularies.xsd
http://stix.mitre.org/default_vocabularies-1 ../stix_default_vocabularies.xsd
http://cybox.mitre.org/objects#AddressObject-2 ../cybox/objects/Address_Object.xsd"
id="example:STIXPackage-33fe3b22-0201-47cf-85d0-97c02164528d"
timestamp="2014-05-08T09:00:00.000000Z"
version="1.1.1"
>
<stix:STIX_Header>
<stix:Title>Example watchlist that contains IP information.</stix:Title>
<stix:Package_Intent xsi:type="stixVocabs:PackageIntentVocab-1.0">Indicators - Watchlist</stix:Package_Intent>
</stix:STIX_Header>
<stix:Indicators>
<stix:Indicator xsi:type="indicator:IndicatorType" id="example:Indicator-2e20c5b2-56fa-46cd-9662-8f199c69d2c9" timestamp="2014-05-08T09:00:00.000000Z">
<indicator:Type xsi:type="stixVocabs:IndicatorTypeVocab-1.1">Domain Watchlist</indicator:Type>
<indicator:Observable id="example:Observable-87c9a5bb-d005-4b3e-8081-99f720fad62b">
<cybox:Object id="example:Object-12c760ba-cd2c-4f5d-a37d-18212eac7928">
<cybox:Properties xsi:type="DomainNameObj:DomainNameObjectType" type="FQDN">
<DomainNameObj:Value condition="Equals" apply_condition="ANY">malicious1.example.com##comma##malicious2.example.com##comma##malicious3.example.com</DomainNameObj:Value>
</cybox:Properties>
</cybox:Object>
</indicator:Observable>
<indicator:Sightings>
<indicator:Sighting timestamp="2014-05-08T09:00:00.000000Z">
<indicator:Source>
<stixCommon:Identity>
<stixCommon:Name>FooBar Inc.</stixCommon:Name>
</stixCommon:Identity>
</indicator:Source>
</indicator:Sighting>
</indicator:Sightings>
</stix:Indicator>
</stix:Indicators>
</stix:STIX_Package>
MISP would create sightings for attributes matching any of the following: malicious1.example.com, malicious2.example.com, malicious3.example.com
Return the index of warninglists enabled on the MISP instance
...
{"Warninglists":[{"Warninglist":{"id":"17","name":"List of known Office 365 URLs and IP address ranges","type":"string","description":"Office 365 URLs and IP address ranges","version":"20170212","enabled":true,"warninglist_entry_count":"1516","valid_attributes":"ip-src, ip-dst, domain|ip, hostname"}},{"Warninglist":{"id":"16","name":"List of known google domains","type":"string","description":"Event contains one or more entries of known google domains","version":"3","enabled":true,"warninglist_entry_count":"665","valid_attributes":"domain, hostname, domain|ip"}},{"Warninglist":{"id":"15","name":"List of hashes for EICAR test virus","type":"string","description":"Event contains one or more entries based on hashes for EICAR test virus","version":"1","enabled":true,"warninglist_entry_count":"15","valid_attributes":"md5, sha1, sha256, sha512, filename|md5, filename|sha1, filename|sha256, filename|sha512"}},{"Warninglist":{"id":"14","name":"Top 1000 website from Alexa","type":"string","description":"Event contains one or more entries from the top 1000 of the most used website (Alexa).","version":"20170212","enabled":true,"warninglist_entry_count":"1000","valid_attributes":"hostname, domain"}},{"Warninglist":{"id":"13","name":"TLDs as known by IANA","type":"string","description":"Event contains one or more TLDs as attribute with an IDS flag set","version":"2","enabled":true,"warninglist_entry_count":"1290","valid_attributes":"hostname, domain, domain|ip"}},{"Warninglist":{"id":"12","name":"Second level TLDs as known by Mozilla Foundation","type":"string","description":"Event contains one or more second level TLDs as attribute with an IDS flag set","version":"2","enabled":true,"warninglist_entry_count":"6462","valid_attributes":"hostname, domain, domain|ip"}},{"Warninglist":{"id":"11","name":"List of RFC 5735 CIDR blocks","type":"cidr","description":"Event contains one or more entries part of the RFC 5735 CIDR blocks - Special Use IPv4 Addresses","version":"2","enabled":true,"warninglist_entry_count":"15","valid_attributes":"ip-src, ip-dst, domain|ip"}},{"Warninglist":{"id":"10","name":"List of RFC 3849 CIDR blocks","type":"cidr","description":"Event contains one or more entries part of the IPv6 documentation prefix (RFC 3849)","version":"2","enabled":true,"warninglist_entry_count":"1","valid_attributes":"ip-src, ip-dst, domain|ip"}},{"Warninglist":{"id":"9","name":"List of RFC 1918 CIDR blocks","type":"cidr","description":"Event contains one or more entries part of the RFC 1918 CIDR blocks","version":"2","enabled":true,"warninglist_entry_count":"3","valid_attributes":"ip-src, ip-dst, domain|ip"}},{"Warninglist":{"id":"8","name":"List of known IPv6 public DNS resolvers","type":"string","description":"Event contains one or more public IPv6 DNS resolvers as attribute with an IDS flag set","version":"20160803","enabled":true,"warninglist_entry_count":"172","valid_attributes":"ALL"}},{"Warninglist":{"id":"7","name":"List of known IPv4 public DNS resolvers","type":"string","description":"Event contains one or more public IPv4 DNS resolvers as attribute with an IDS flag set","version":"20160803","enabled":true,"warninglist_entry_count":"77857","valid_attributes":"ALL"}},{"Warninglist":{"id":"6","name":"List of RFC 5771 multicast CIDR blocks","type":"cidr","description":"Event contains one or more entries part of the RFC 5771 multicast CIDR blocks","version":"2","enabled":true,"warninglist_entry_count":"16","valid_attributes":"ip-src, ip-dst, domain|ip"}},{"Warninglist":{"id":"5","name":"List of known microsoft domains","type":"string","description":"Event contains one or more entries of known microsoft domains","version":"1","enabled":true,"warninglist_entry_count":"152","valid_attributes":"domain, hostname, domain|ip"}},{"Warninglist":{"id":"4","name":"List of IPv6 link local blocks","type":"cidr","description":"Event contains one or more entries part of the IPv6 link local prefix (RFC 4291)","version":"1","enabled":true,"warninglist_entry_count":"1","valid_attributes":"ip-src, ip-dst, domain|ip"}}
....
curl --header "Authorization: YOUR API KEY " --header "Accept: application/json" --header "Content-Type: application/json" -X "GET" https://10.50.13.60/warninglists/index
Return the a warninglist by id
to long
curl --header "Authorization: YOUR API KEY " --header "Accept: application/json" --header "Content-Type: application/json" -X "GET" https://10.50.13.60/warninglists/view/17
If you are interested in the attribute type or attribute category data distribution on your instance, MISP offers an API that will create an aggregates list. To access the API, simple sent a GET request to:
https://<misp url>/attributes/attributeStatistics/[context]/[percentage]
Where the following parameters can be set:
The results are always returned as JSON.
Sample output of the types in percentages from CIRCL's MISP instance:
{
"AS": "0.015%",
"attachment": "0.177%",
"btc": "0.005%",
"campaign-name": "0.005%",
"comment": "1.47%",
"domain": "15.992%",
"domain|ip": "0.005%",
"email-attachment": "0.207%",
"email-dst": "0.121%",
"email-src": "0.192%",
"email-subject": "0.146%",
"filename": "3.698%",
"filename|md5": "0.349%",
"filename|sha1": "0.894%",
"filename|sha256": "0.652%",
"hostname": "17.558%",
"http-method": "0.045%",
"ip-dst": "7.087%",
"ip-src": "2.707%",
"link": "5.748%",
"malware-sample": "0.702%",
"malware-type": "0.005%",
"md5": "21.064%",
"mutex": "0.278%",
"named pipe": "0.03%",
"other": "1.495%",
"pattern-in-file": "0.192%",
"pattern-in-memory": "0.303%",
"pattern-in-traffic": "0.051%",
"regkey": "0.126%",
"regkey|value": "0.187%",
"sha1": "8.921%",
"sha256": "5.597%",
"snort": "0.045%",
"target-machine": "0.248%",
"target-org": "0.01%",
"target-user": "0.106%",
"text": "0.934%",
"threat-actor": "0.005%",
"url": "2.258%",
"user-agent": "0.081%",
"vulnerability": "0.182%",
"whois-registrant-email": "0.01%",
"x509-fingerprint-sha1": "0.01%",
"yara": "0.086%"
}
Additional statistics are available as JSON which are the statistics also usable via the user interface. A ".json" can be appended to the following URLs:
- https://<misp url>/users/statistics/tags.json
- https://<misp url>/users/statistics.json
- https://<misp url>/users/statistics/attributehistogram.json
- https://<misp url>/users/statistics/orgs.json
An example output of https://
{
"stats": {
"event_count": 5233,
"event_count_month": 21,
"attribute_count": 645498,
"attribute_count_month": 723,
"correlation_count": 207152,
"proposal_count": 48944,
"user_count": 1073,
"org_count": 587,
"thread_count": 191,
"thread_count_month": 0,
"post_count": 337,
"post_count_month": 0
}
}
It is possible call misp-modules directly from API. If the module needs credentials, API will get the information directly from MISP configuration.
Retrieve a list of all modules enabled.
curl --header "Authorization: <APIKEY> " --header "Accept: application/json" --header "Content-Type: application/json" -X GET http://<MISP>/modules/
[
{
"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"
}
}
]
Call any enabled module.
Content of dns.json
{
"hostname": "www.foo.be",
"module": "dns"
}
Query using MISP API
curl --header "Authorization: <APIKEY> " --header "Accept: application/json" --header "Content-Type: application/json" --data @dns.json -X POST http://<MISP>/modules/queryEnrichment
The output will be following JSON:
{
"results": [
{
"types": [
"ip-src",
"ip-dst"
],
"values": [
"188.65.217.78"
]
}
]
}