This folder contains example OpenC2 commands in two Application Programming Interface (API) formats and three JSON-based message formats. API values are the structured data objects used by a program, e.g., Dictionary and List values for Python applications, Map/WeakMap and Array values for Javascript applications, or Hash and Array values for Ruby applications. Message values are data objects that have been serialized (encoded) for transmission between applications or for storage. The current examples use JSON serializations, but XML and binary serializations are also possible. These messages are encoding alternatives derived from the same abstract syntax; they are not alternative syntax specifications requiring separate development and maintenance.
API and JSON-verbose: Structured data object as used by a Python application, and the direct JSON
serialization of that object as produced by json.dump
. Python literal notation is similar but
not identical to JSON, so the JSON examples shown here would need to be slightly edited for use
as Python literals if they contain boolean or null values.
API Flat: Some developers may find it more convenient to work with flattened data values, e.g.
a dictionary containing only primitive data values instead of a dictionary containing nested complex data.
The JAEN package includes routines flatten
and fluff
to convert between structured and flat Python API values.
JSON-concise: A message format shown primarily to illustrate how positional encoding eliminates the need to transmit dictionary keys with every message. This format produces messages intermediate in size between verbose and minified encodings.
JSON-minified: A message format optimized for minimum bandwidth and storage space, using both positional encoding and by replacing enumerated strings with integer tags. This format produces minimum bandwidth messages for a text-based encoding, although binary encodings would be smaller.
{ "action": "mitigate",
"target": {
"domain_name": {"value": "cdn.badco.org"}}}
{ "action": "mitigate",
"target.domain_name.value": "cdn.badco.org"
}
["mitigate",{"domain_name":["cdn.badco.org"]}]
[32,{"7":["cdn.badco.org"]}]
Command:
{ "action": "query",
"target": {"openc2": {"actions":""}}}
Response
{ "status": "OK",
"results": {
"strings":
["query", "report", "notify", "start", "stop", "set", "delete", "update",
"investigate", "mitigate", "remediate"]}}
Command:
{ "action": "query",
"target": {"openc2": {"schema":""}}}
Response
{ "status": "OK",
"results": {
"string": "{\"meta\": {\"module\": \"openc2\"}, \"types\": [[\"OpenC2Command\", \"Record\", [], \"\", [[1, \"action\", \"Action\", [], \"\"], [2, \"target\", \"Target\", [], \"\"], [3, \"actuator\", \"Actuator\", [\"?\"], \"\"], [4, \"modifiers\", \"Modifiers\", [\"?\"], \"\"]]]]}"}}
{ "action": "contain",
"target": {
"user_account":{
"user_id": "21942",
"account_login": "jsmith",
"is_disabled": true,
"account_last_login": "2017-03-16T07:38:12-04:00"}}}
{ "action": "contain",
"target.user_account.user_id": "21942",
"target.user_account.account_login": "jsmith",
"target.user_account.is_disabled": true,
"target.user_account.account_last_login": "2017-03-16T07:38:12-04:00"
}
[ "contain",{
"user_account":{
"user_id": "21942",
"account_login": "jsmith",
"is_disabled": true,
"account_last_login": "2017-03-16T07:38:12-04:00"}}]
[7,{"19":{"1":"21942","2":"jsmith","8": true,"13":"2017-03-16T07:38:12-04:00"}}]
{ "action": "deny",
"target": {
"ip_connection": {
"src_addr": {"name": {"value": "www.badco.com"}},
"src_port": {"protocol": "https"},
"dst_addr": {"ipv4": {"value": "192.168.1.1"}},
"layer4_protocol": "TCP"
}},
"actuator": {
"network_firewall": {"asset_id": "30"}},
"modifiers": {
"command_ref": "pf17_8675309",
"context": "91",
"datetime": "2016-11-25T08:10:31-04:00",
"duration": "PT2M30S"}}
{ "action": "deny",
"target.ip_connection.src_addr.name.value": "www.badco.com",
"target.ip_connection.src_port.protocol": "https",
"target.ip_connection.dst_addr.ipv4.value": "192.168.1.1",
"target.ip_connection.layer4_protocol": "TCP",
"actuator.network_firewall.asset_id": "30",
"modifiers.command_ref": "pf17_8675309",
"modifiers.context": "91",
"modifiers.datetime": "2016-11-25T08:10:31-04:00",
"modifiers.duration": "PT2M30S"
}
[ "deny",
{"ip_connection": [
{"name": ["www.badco.com"]},
{"protocol": "https"},
{"ipv4": ["192.168.1.1"]},
null,
null,
"TCP"]},
{"network_firewall": [null, "30"]},
{"context": "91",
"datetime": "2016-11-25T08:10:31-04:00",
"duration": "PT2M30S",
"command_ref": "pf17_8675309"}]
[6,{"15":[{"3":["www.badco.com"]},{"2":443},
{"1":["192.168.1.1"]},null,null,6]},{"14":[null,"30"]},
{"1":"91","2":"2016-11-25T08:10:31-04:00","4":"PT2M30S",
"6":"pf17_8675309"}]
{ "action": "scan",
"target": {
"domain_name": {
"value": "www.example.com",
"resolves_to": [
{"ipv4": {"value": "198.51.100.2"}},
{"name": {"value": "ms34.example.com"}}]}}}
{ "action": "scan",
"target.domain_name.value": "www.example.com",
"target.domain_name.resolves_to.0.ipv4.value": "198.51.100.2",
"target.domain_name.resolves_to.1.name.value": "ms34.example.com"
}
[ "scan", {
"domain_name": [
"www.example.com", [
{"ipv4": ["198.51.100.2"]},
{"name": ["ms34.example.com"]}]]}]
[1,{"7":["www.example.com",[{"1":["198.51.100.2"]},{"3":["ms34.example.com"]}]]}]
{ "action": "update",
"target": {
"software": {
"name": "VirusBeGone",
"vendor": "McAfmantec"}},
"actuator": {
"process_remediation_service": {
"device_id": "dns://host03274.example.org"}},
"modifiers": {
"command_id": "474074afb389",
"command_src": "dns://orch.example.org",
"response": "ack",
"source": "https://updates.example.org/win7_x64/patch_201704_0137.cab"}}
{ "action": "update",
"target.software.vendor": "McAfmantec",
"target.software.name": "VirusBeGone",
"actuator.process_remediation_service.device_id": "dns://host03274.example.org",
"modifiers.command_id": "474074afb389",
"modifiers.command_src": "dns://orch.example.org",
"modifiers.response": "ack",
"modifiers.source": "https://updates.example.org/win7_x64/patch_201704_0137.cab"}
[16,{"17":["VirusBeGone",None,None,"McAfmantec"]},{"41":["dns://host03274.example.org"]},
{"10":"https://updates.example.org/win7_x64/patch_201704_0137.cab","8":1,"7":"dns://orch.example.org","6":"474074afb389"}]
{ "status": "Processing",
"statusText": "Updating McAfmantec VirusBeGone ...",
"response_src": "dns://orch.example.org",
"command_id": "474074afb389"}
(Same as API because response syntax has no nested elements)
[102, "Updating McAfmantec VirusBeGone ...", "dns://orch.example.org", "474074afb389"]
Protocol negotiation is a three-message handshake sent using a default protocol stack. This example assumes that JSON is the default serialization. Suitable defaults must also be specified for security and transport layers during negotiation.
Note: this example shows syntactically-correct commands but an invalid negotiation sequence. In step 3, the selected communication option (REST) was not present in the actuator's list of supported options (DXL).
{ "action": "query",
"target": {
"openc2": "comm_supported"},
"actuator": {
"any": {"actuator_id": "https://router7319.example.org"}}
}
{ "status": "OK",
"results": {
"comms": {
"serialization": ["JSON", "JSON-min", "XML", "Protobuf"],
"connection": [{"DXL": {"channel": "c2-channel"}}]}}
}
{ "action": "set",
"target": {
"openc2": {
"comm_selected":{
"serialization": "Protobuf",
"connection": {
"REST": {
"port": {"protocol":"https"}}}}}},
"actuator": {
"any": {"actuator_id": "https://router7319.example.org"}}
}
{ "action": "cancel",
"target": {
"openc2": {"command": "b33cd1d4-aeb4-43a3-bfe9-806f4a84ef79"}}
}
{ "action": "delete",
"target": {
"email_message": {
"subject": "Special Offer!",
"date": "2017-06-07T14:30:31-04:00",
"from": {"value": "[email protected]"}}}
}