Friday, March 15, 2013

Defensive Construct Exchange Standard .2

Previously I laid out the need for a graph-based standard to exchange information (here).  After working with Defensive Construct Exchange Standard (DCES) events in my personal projects I want to provide some additional refinement of the standard.  If you want to read they why, read the last post.

As a primer, graphs are made up of nodes and edges.  Nodes are the circles.  Edges are lines that connect them.  All have other names, but we'll use nodes, edges, and graphs for now.  Nodes and edges can have properties, just like properties attached to an object in programming.  DCES events are constructs from other tools.  Where in another tool, the construct may have been a record in a table in a database, the DCES event represents it as a small graph in a JSON compatible format.

Defensive Construct Exchange Standard .2:

  1. All discrete pieces of information within a construct will be given an individual node.  All nodes within the construct have the property "class" of value "attribute".
  2. The actual attribute property will be stored as a JSON object within the node's "metadata" attribute.  The object will have a single {"type":"value"} pair.  All others shall be rejected.
  3. All nodes will be linked to a node containing a construct ID generated by the construct originator.  (It will be recommended that those receiving constructs into their own graphs generate a local construct ID so as to avoid conflicts within their graph.)
  4. The construct ID will be a parent node of all Attributes within the construct.
  5. The nodes and edges will be represented in JSON.  They shall be transmitted in accordance with the JSON format outlined by the gephi graph streaming project (Gephi graph streaming).  In practice, all constructs shall be 'an' (add node) or 'ae' (add edge), with the recipient deciding how to actually handle the information.  All required properties are documented at
  6. Attribute nodes within the construct may have their own attributes.  (I.E. A threat construct's location attribute may have a 'classification' attribute.)
  7. Individual constructs should be contained in a single JSON message represent a single DCES event.  (I.E. {"an":{1:{...}, 2:{...}, 3:{...}}, "ae":{4:{...}, 5:{...}}, "dces_version":"0.2"} could represent a single construct"
  8. The recipient of a DCES event may define it's own response to receipt depending on it's needs. If the sender needs to understand the linkage of the construct in the receipient's attack graph, it is recommended the recipient return the the node ID of the node storing the construct ID in the receipient's graph.
  9. The WAMP standard should be used when the DCES event is transmitted to/from an RPC or pubsub.
  10. The DCES event shall have a "dces_version" property.
  11. "an"s are implicitly anchored to originIDs.  (Because the node doesn't exist in the DB graph yet, there is no dbID to anchor to.)  If any "an"s are present in the event, any "ae"s in that event are explicitly anchored to originIDs to avoid confusion. If an "ae" needs to be referenced to a dbID, add it as a separate event.


This example from the previous post has been updated to present version .2 of the standard.  Graphically, it looks like this:

Parsed into JSON with all properties included, it looks like this:
"ae":{"1":{"source":"A","target":"B","directed":true, "relationship":"describes","start":"2013-03-14T16:57Z"},
"2":{"source":"A","target":"C","directed":true, "relationship":"describes","start":"2013-03-14T16:57Z"},
"3":{"source":"A","target":"D","directed":true, "relationship":"describes","start":"2013-03-14T16:57Z"},
"4":{"source":"D","target":"C","directed":true, "relationship":"describes","start":"2013-03-14T16:57Z"},
"5":{"source":"C","target":"B","directed":true, "relationship":"describes","start":"2013-03-14T16:57Z"},
"6":{"source":"A","target":"E","directed":true, "relationship":"describes","start":"2013-03-14T16:57Z"},
"7":{"source":"A","target":"F","directed":true, "relationship":"describes","start":"2013-03-14T16:57Z"},
"8":{"source":"A","target":"G","directed":true, "relationship":"describes","start":"2013-03-14T16:57Z"},
"9":{"source":"G","target":"F","directed":true, "relationship":"describes","start":"2013-03-14T16:57Z"},
"10":{"source":"F","target":"E","directed":true, "relationship":"describes","start":"2013-03-14T16:57Z"},
"11":{"source":"A","target":"H","directed":true, "relationship":"describes","start":"2013-03-14T16:57Z"},
"12":{"source":"A","target":"I","directed":true, "relationship":"describes","start":"2013-03-14T16:57Z"},
"13":{"source":"A","target":"J","directed":true, "relationship":"describes","start":"2013-03-14T16:57Z"},
"14":{"source":"J","target":"I","directed":true, "relationship":"describes","start":"2013-03-14T16:57Z"},
"15":{"source":"I","target":"H","directed":true, "relationship":"describes","start":"2013-03-14T16:57Z"}},
"an":{"A":{"label":"Construct From X","class":"attribute","metadata":{"id":"<value>"},"start":"2013-03-14T16:57Z","cpt":{"nodeid":"A","index":[true,false],"0":[1,0]}},
"E":{"label":"dns query","class":"attribute","metadata":{"dns query":"<value>"},"start":"2013-03-14T16:57Z","cpt":{"nodeid":"E","index":["A","F",true,false],"0":[0,0,0,1],"1":[0,0,0,1],"2":[0,0,0,1],"3":[1,0,0,0]}},
"F":{"label":"dns record","class":"attribute","metadata":{"dns record":"<value>"},"start":"2013-03-14T16:57Z","cpt":{"nodeid":"F","index":["A","G",true,false],"0":[0,0,0,1],"1":[0,0,0,1],"2":[0,0,0,1],"3":[1,0,0,0]}},
"G":{"label":"dns record type","class":"attribute","metadata":{"record type":"<value>"},"start":"2013-03-14T16:57Z","cpt":{"nodeid":"G","index":["A",true,false],"0":[0,1],"1":[1,0]}},
"H":{"label":"dns query","class":"attribute","metadata":{"dns query":"<value2>"},"start":"2013-03-14T16:57Z","cpt":{"nodeid":"H","index":["A","I",true,false],"0":[0,0,0,1],"1":[0,0,0,1],"2":[0,0,0,1],"3":[1,0,0,0]}},
"I":{"label":"dns record","class":"attribute","metadata":{"dns record":"<value2>"},"start":"2013-03-14T16:57Z","cpt":{"nodeid":"I","index":["A","J",true,false],"0":[0,0,0,1],"1":[0,0,0,1],"2":[0,0,0,1],"3":[1,0,0,0]}},
"J":{"label":"dns record type","class":"attribute","metadata":{"record type":"<value2>"},"start":"2013-03-14T16:57Z","cpt":{"nodeid":"J","index":["A",true,false],"0":[0,1],"1":[1,0]}}}}
However, in practicality, the receiving graph will probably add much of the information.  For edges, "relationship", "directed", and "start" can all be added by the receiver.  For nodes, "class", "start", and "cpt" can be added by the receiver greatly simplifying the sender's job.

Ultimately, this standard will continue to evolve slowly as it is put into use.  While it is another new standard in a sea of standards, it is truly unique and offers clear benefits.


  1. 1. ANs and AEs are explicitly required to be anchored to originIDs, not to the receiving database IDs. This particularly applies to Edges

    1. Should probably be:
      - "an"s are implicitly anchored to originIDs. If any "an"s are present in the event, "ae"s are explicitly anchored to originIDs to avoid confusion. If an "ae" needs to be referenced to a dbID, add it as a separate event.

  2. Going to need to change direction again. Attribute edges need to be "described by" rather than describes. That way they are not a parent of the node they describe.

    This is important for risk calculations. CPTs are based on parents and so edges pointing from attributes to nodes need to have a relationship of "influences" rather than "describes" to make sure CPTs are calculating on the correct edges.

    1. Will need to be changed in DCES 0.3 definition.

  3. Event, Condition, and Actor nodes are considered the same node if the have exactly matching labels.

    Attribute nodes are considered matching if their metadata type and value are exactly the same. (As such, the label property should contain the same dictionary as the metadata property.) (This begs the question if the 'metadata' property is needed or the 'label' will suffice.)

    Edges are considered the same if they have the same source & target.

    Will change in DCES 0.3