I had a great time talking about graph theory and infosec at Derbycon 3.0. Derbycon is an incredible gathering and I am honored to have been a part of it. Other than a few technical glitches, the presentation went great (even the demo worked) and the room was packed. If you weren't able to make it, you can either watch the video when it's posted or, if there's enough interest, I'll see if I can give it at another conference. I'd love to have a 50 minute time slot to give the talk so I can give a bit more love to each of the slides. If you want the charts or any of the links from my presentation, you can see them here. Again, I'm so thankful to have both attended and spoke at Derbycon. Thank you to everyone who's taken the time to speak with me here. I'll see you at ISSA, Skydogcon, or BsidesNash!
UPDATE: If you want watch my derbycon talk, you see it on: irongeek.com.
UPDATE: You can also listen to my first podcast with Rafal Los at: his podcast.
Sunday, September 29, 2013
Monday, July 29, 2013
Cyber Attack Graph Schema (CAGS) 1.0
While the concept of
attack graphs has been discussed, once thing that is lacking is a standard
definition for an attack graph. This
blog hopes to resolve that by presenting a new standard: the Cyber Attack Graph
Schema (CAGS) 1.0
1.
All property names must be lower
case
2.
Nodes must have the following
properties:
1.
"class": May be
"actor", "event", "condition",
"attribute"
2.
"cpt": must be a JSON
string in the format defined at
http://infosecanalytics.blogspot.com/2013/03/conditional-probability-tables-in-json.html
3.
"start": The time the node
is created. Time should be in ISO 8601 combined date and time format (e.g.
2013-03-14T16:57Z)
4.
"id": Assigned by
database.
3.
Nodes must have property
"label".
4.
The "label" property of
nodes of "class" "event", "condition", or
"actor" will contain a string holding a narrative describing the
actor, event, or condition
5.
The "label" property of
nodes of "class" "attribute" must contain a JSON formatted
string with a single "{'type':'value'}" pair. Type is the type/name
of the attribute and value the value.
6.
Nodes of any class MAY have property
"comments" providing additional narrative on the node
7.
Nodes of any class MAY have property
"finish" providing a finish time for the node. Time should be in ISO
8601 combined date and time format (e.g. 2013-03-14T16:57Z)
8.
Edges must have the following
properties:
1.
"source": the id of the
source node
2.
"target": the id of the
target node
3.
"id": id assigned by the
database
4.
"relationship":
1.
Value of "influence" if
"source" property "class" is "attribute" and
"target" property "class" is "event" or
"condition". Value of "leads to" if "source"
property "class" is "event", "threat"
2.
Value of "influence" if
"condition" and "target" property "class" is
"actor", "event", or "condition"
3.
Value of "described by" if
"source" property "class" is "event",
"condition", or "actor" and "target" property
"class" is "attribute"
4.
Value of "described by" if
both "source" and "target" property "class" are
"attribute"
5.
"directed": value of
"True"
9.
Edges may have a property
"confidence" with an integer value from 0 to 100 representing the
percent confidence
10.
Edges must be directed
11.
Nodes and Edges may have additional
properties, however they will not be validated and may be ignored by the attack
graph.
12.
Nodes and Edges missing values may
still be accepted if the value can be filled in.
Friday, July 12, 2013
Disincentivizing Delaying Risk Mitigation
There is an ongoing issue in infosec: the never-ending risk. This is a risk that infosec has identified but the project would rather not mitigate. The project cannot refuse to address the risk, but they can do the next best thing: agree to mitigate the risk, but never actually implement the mitigation.
This cycle normally starts with the infosec review and the project agreeing to mitigate the risk, hopefully in a set amount of time. That time rolls around and infosec conducts a review of the progress in implementing the mitigation. This is where things start to fall apart. Rather than answering that they have followed the plan and mitigated the risk, the project indicates that they've made little to no progress. Infosec has no choice but to accept a new mitgation schedule and meet months later. Infosec can't spend its valuable resources following the schedule week to week so another period of time passes and nothing has been accomplished. The cycle continues.
The primary driver of this cycle is that infosec cannot say 'no'. It can't say no initially (or maybe put its foot down on a few issues which did get fixed) and it gets harder to say 'no' as time passes. If the risk was acceptable for the last 6 months, it becomes harder and harder to justify to senior leadership why it won't be acceptable for the next 6 months.
There is an option though. You don't have to say know, you have to say "yes but". Think of it as saying, "yes, you can do whatever it was that you wanted to do, but only while you hop on one foot while patting your belly, rubbing your head, and singing Yankee Doodle." In reality, this may be, "yes, you may use FTP, however each file must be encrypted individually and the password snail mailed to the receiver". The goal is to both reduce risk and disincentivize delaying implementing a real mitigation (such as using SFTP).
An alternate is to decrease the time frame for review. If the project doesn't know when they will have it mitigated, approve use for only 1 month. At the renewal, they should be required to provide the mitigation plan. If they don't know how long it will take to come up with a mitigation plan, give approval for 1 week. At 1 week they should have a schedule for creating the mitigation plan (effectively a schedule to create a schedule).
This only works if they have to prepare significantly more for a renewal than you do. There should be assessments, forms, plans, briefing charts, etc that they have to prepare for the renewal and that you only have to read. The goal is to make renewals more time consuming for them than for you. That way increasing the number of renewals is burdensome on them and not on you, again disincentivizing delaying a mitigation.
Regardless of which way you go, it must be tied to risk. If you cannot show that the reason you are requiring the extra work or quicker turns is to help minimize risk, you really are simply generating make-work which will not be tolerated at your level or at upper levels. Also, you must be absolutely responsive. You once they decide to mitigate the risk you must help and support their solution so that you do not impede the work.
Ultimately, while it sounds harsh to disincentivize delaying mitigation through additional work, in many cases it, is unfortunately necessary. Unless the project is benevolent, they will do what they are incentivized to do and most of the time; only infosec is incentivized to mitigate risk before it is realized. By disincentivising delaying mitigation, you are simply balancing the scales to help ensure a quality product.
This cycle normally starts with the infosec review and the project agreeing to mitigate the risk, hopefully in a set amount of time. That time rolls around and infosec conducts a review of the progress in implementing the mitigation. This is where things start to fall apart. Rather than answering that they have followed the plan and mitigated the risk, the project indicates that they've made little to no progress. Infosec has no choice but to accept a new mitgation schedule and meet months later. Infosec can't spend its valuable resources following the schedule week to week so another period of time passes and nothing has been accomplished. The cycle continues.
The primary driver of this cycle is that infosec cannot say 'no'. It can't say no initially (or maybe put its foot down on a few issues which did get fixed) and it gets harder to say 'no' as time passes. If the risk was acceptable for the last 6 months, it becomes harder and harder to justify to senior leadership why it won't be acceptable for the next 6 months.
There is an option though. You don't have to say know, you have to say "yes but". Think of it as saying, "yes, you can do whatever it was that you wanted to do, but only while you hop on one foot while patting your belly, rubbing your head, and singing Yankee Doodle." In reality, this may be, "yes, you may use FTP, however each file must be encrypted individually and the password snail mailed to the receiver". The goal is to both reduce risk and disincentivize delaying implementing a real mitigation (such as using SFTP).
An alternate is to decrease the time frame for review. If the project doesn't know when they will have it mitigated, approve use for only 1 month. At the renewal, they should be required to provide the mitigation plan. If they don't know how long it will take to come up with a mitigation plan, give approval for 1 week. At 1 week they should have a schedule for creating the mitigation plan (effectively a schedule to create a schedule).
This only works if they have to prepare significantly more for a renewal than you do. There should be assessments, forms, plans, briefing charts, etc that they have to prepare for the renewal and that you only have to read. The goal is to make renewals more time consuming for them than for you. That way increasing the number of renewals is burdensome on them and not on you, again disincentivizing delaying a mitigation.
Regardless of which way you go, it must be tied to risk. If you cannot show that the reason you are requiring the extra work or quicker turns is to help minimize risk, you really are simply generating make-work which will not be tolerated at your level or at upper levels. Also, you must be absolutely responsive. You once they decide to mitigate the risk you must help and support their solution so that you do not impede the work.
Ultimately, while it sounds harsh to disincentivize delaying mitigation through additional work, in many cases it, is unfortunately necessary. Unless the project is benevolent, they will do what they are incentivized to do and most of the time; only infosec is incentivized to mitigate risk before it is realized. By disincentivising delaying mitigation, you are simply balancing the scales to help ensure a quality product.
Friday, June 21, 2013
Tied in Silk Ropes - A subtler way to infosec
After reading the Infosec Jerk's Problem blog, I wanted to suggest another way of dealing with the constant struggle between infosec and the rest of the organization. It's a method I've used to great effectiveness in multiple situations and it normally leaves all parties happy, (or at least not unhappy with you).
Lets take an example, department X comes by with a new requirement to open ports between Y and Z. The standard infosec answer is 'no'. The normal resolution is "how big an issue is X willing to make this to get what they want"? Can they push it high enough that they can overwride infosec?
Compassionately, you could listen to their arguements, try to see it from their point of view, maybe consider different design options. Many times though, they won't want to change the design and even if you understand their view, your view is still what your view was.
I have a different approach. In true Mafia style, I do you a favor; maybe you do me a favor one day. Rather than make their life harder, request something in return that they don't care about. In the above example, ask them to install a suite of monitoring equipment. You didn't tell them 'no'. You didn't even change their design. You might even have provided the equipment yourself. Instead, you simply asked that they return the favor of you allowing them to do what they wanted by them helping you do what you wanted. It's mutually beneficial.
However, you're going to pick your side of the favor wisely. Your goal is not to solve this one-off problem but create a change in how business is done. If you ask EVERY person who wants to open ports to install that monitoring suite, well, that suite has now become standard for boundaries. If every time someone asks to plug A into B, even temporarily, you request they simply put in a firewall (even if it has almost no rules), eventually, a firewall becomes standard for connecting things.
What about when people ask you to agree to not raising a fuss when they want to do something that causes security risk, (and we're speaking relatively minor)? You say, "yes, that's fine, but I need you to fill out this risk form. I'll analyze it and accept it." You've now created a risk acceptance and tracking program. The next step is to say "Well yes, I'll sign the risk form, but I need to include when you DO plan on patching." Now you have them generating mitigation plans. You'll follow with, "Ok, but I want an update when you do mitigate it. If I don't get one, I'll check up and potentially rescind the acceptance". Now you have continuious oversight. Finally, you'll get to the point where you can say, "gee, I don't think this risk is acceptable. We should elevate." In effect you've established a risk program without ever having to force fight anyone to get it.
This works for many things. It can be installing new systems, allowing vulnerabilities to persist, making new connections, opening ports, etc. You can get all sorts of things out of it: firewalls, IDSs, policies, procedures, authority, and more. And the people will love you for doing it. You'll be tieing the binds of security tight, but you'll be doing it softly and slowly with silk ropes. In the end the ties that bind will be just as tight and secure as if you'd tried to force them on people, but you'll have done it without having to have a single fight.
Lets take an example, department X comes by with a new requirement to open ports between Y and Z. The standard infosec answer is 'no'. The normal resolution is "how big an issue is X willing to make this to get what they want"? Can they push it high enough that they can overwride infosec?
Compassionately, you could listen to their arguements, try to see it from their point of view, maybe consider different design options. Many times though, they won't want to change the design and even if you understand their view, your view is still what your view was.
I have a different approach. In true Mafia style, I do you a favor; maybe you do me a favor one day. Rather than make their life harder, request something in return that they don't care about. In the above example, ask them to install a suite of monitoring equipment. You didn't tell them 'no'. You didn't even change their design. You might even have provided the equipment yourself. Instead, you simply asked that they return the favor of you allowing them to do what they wanted by them helping you do what you wanted. It's mutually beneficial.
However, you're going to pick your side of the favor wisely. Your goal is not to solve this one-off problem but create a change in how business is done. If you ask EVERY person who wants to open ports to install that monitoring suite, well, that suite has now become standard for boundaries. If every time someone asks to plug A into B, even temporarily, you request they simply put in a firewall (even if it has almost no rules), eventually, a firewall becomes standard for connecting things.
What about when people ask you to agree to not raising a fuss when they want to do something that causes security risk, (and we're speaking relatively minor)? You say, "yes, that's fine, but I need you to fill out this risk form. I'll analyze it and accept it." You've now created a risk acceptance and tracking program. The next step is to say "Well yes, I'll sign the risk form, but I need to include when you DO plan on patching." Now you have them generating mitigation plans. You'll follow with, "Ok, but I want an update when you do mitigate it. If I don't get one, I'll check up and potentially rescind the acceptance". Now you have continuious oversight. Finally, you'll get to the point where you can say, "gee, I don't think this risk is acceptable. We should elevate." In effect you've established a risk program without ever having to force fight anyone to get it.
This works for many things. It can be installing new systems, allowing vulnerabilities to persist, making new connections, opening ports, etc. You can get all sorts of things out of it: firewalls, IDSs, policies, procedures, authority, and more. And the people will love you for doing it. You'll be tieing the binds of security tight, but you'll be doing it softly and slowly with silk ropes. In the end the ties that bind will be just as tight and secure as if you'd tried to force them on people, but you'll have done it without having to have a single fight.
Tuesday, June 11, 2013
When Educating Doesn't Work
I used to sell computers at Circuit City. Their hiring test said I'd be great at it. I wasn't, for one reason: I tried to educate people. I would try to teach them why one computer was different from another, and how certain characteristics were better for one use then another. I'd even leave them with a simple choice: "buy X for gaming, buy Y for business stuff.”
That was too much. It wasn't until much later that I realized they wanted to tell me what they wanted to do, then have me point to a single computer and tell them to buy it. Why did I make this mistake? I'm a highly cerebral intellectual. I want to know about the man behind the curtain. And, erroneously, I assume others do as well.
This is a problem we face in information security today. While less technical people – the sales person at your local mattress firm, say – may not really try and educate, but simply settle for influencing you, we try to educate on the honest belief that educated people will make the right decision. However, that’s not how it works. People buy what they want first, then (maybe) what they think they need second.
What we should do is try to influence them. Our job is to make them want what they need and think it's their idea. This doesn't mean giving them what they ask for. That would be the exact opposite of influencing. Instead, we want to change what they want, in order to align with what is best for them from an infosec standpoint.
The next time you’re trying to get a client or customer to take a certain action, don’t forget to influence. At the end of the day, you may even be able to influence them to want to be educated. But the first task is to do what is right by them and that will probably require influencing them first.
That was too much. It wasn't until much later that I realized they wanted to tell me what they wanted to do, then have me point to a single computer and tell them to buy it. Why did I make this mistake? I'm a highly cerebral intellectual. I want to know about the man behind the curtain. And, erroneously, I assume others do as well.
This is a problem we face in information security today. While less technical people – the sales person at your local mattress firm, say – may not really try and educate, but simply settle for influencing you, we try to educate on the honest belief that educated people will make the right decision. However, that’s not how it works. People buy what they want first, then (maybe) what they think they need second.
What we should do is try to influence them. Our job is to make them want what they need and think it's their idea. This doesn't mean giving them what they ask for. That would be the exact opposite of influencing. Instead, we want to change what they want, in order to align with what is best for them from an infosec standpoint.
The next time you’re trying to get a client or customer to take a certain action, don’t forget to influence. At the end of the day, you may even be able to influence them to want to be educated. But the first task is to do what is right by them and that will probably require influencing them first.
Thursday, April 11, 2013
Weaving the Tools of Infosec Defense Together
I’m very excited to finally be able to talk about a technology that I've been working on for some time. I have figured out how to connect all aspects of defense: architecting and securing systems (I'll call it 'engineering'), gathering intelligence on what attackers are doing, and detecting and responding to incidents (I'll call this 'operations'). But let’s start at the beginning.
I’ve assessed risk for years and it has never felt 'right'. At a fundamental level, I'm not sure we even knew what risk we were assessing. A vulnerability wasn't a risk. A control definitely wasn't a risk. Additionally, nothing quite seemed right when it came to determining risk likelihood. I've seen every approach under the sun. Many were repeatable, but simply obscured analysts’ decisions behind various weights and 'classifications' (like calling a vulnerability exploitable by outsiders or insiders).
I came to realize risk was a path, as I've previously blogged. Others have come to this conclusion as well, sometimes referring to these paths as kill chains. I make the path distinction since, as a coworker and Lockheed pointed out, kill chains tend to be a specific number of steps. Attack paths are fairly flexible and arbitrary. A kill chain is an attack path, but not necessarily vice versa.
The next question becomes how to aggregate these paths. The Lockheed paper begins to address it, but a much better approach is the use of graph theory! I won't claim to be the first to use graph theory for this. Many have, and I intend to publish a research paper giving full credit to all those whose works I built upon. However, what I am doing is fundamentally different.
By combining attack paths from analysts with graph theory, we now have something that closely resembles how we think about risks happening. An attacker can do A, then B, then C to cause us consequences. And if we block B, they still have the option of doing D in it's place. By using Bayesian math, the combination of risk can be aggregated. Additionally, risk can be tied to threats and their specific attributes. (The explanation of this is something that'll have to wait for the research paper.)
Here's where it gets interesting
Once you have aggregated your attack paths, you don't just have a way of assessing risk, you have a representation of your entire Infosec Posture! It not only shows you what your current risk posture is, but also allows you to combine your gathered intelligence in such a way as to see how it influences your risk. It furthermore allows you to add hypothetical vulnerabilities (which are just likely conditions) as well as adding mitigations and controls (which are unlikely conditions) to see how they affect your posture. You can also add your operational sensor events (IDS, FW, log files, etc) to see if they match any attack paths, threats, or consequences in your graph. And incident handlers can use it to collect and share information about an incident.
From this single graph, you can manage your entire defensive infosec posture. While I'm in no way a coder, I've started to write a tool to realize this capability: Moirai. Named after the Greek Fates – mythological goddesses that wove people's lives – Moirai weaves together the defense of an information system. I am licensing this tool as open source in the hopes that it will help us bring our defensive tools together. At its most fundamental level, Moirai operates as a pubsub and RPC server for graphs using autobahn and neo4j. It does four specific things: 1. It receives state changes to the Infosec Posture stored in a graph. 2. It validates them, fixing them as needed. 3. It stores the changes, and 4. It shares the Infosec Posture, including sharing state changes. The rules for validating an update to the graph are can be found here.
It does this using the Defensive Construct Exchange Standard. Because the standard uses graph theory rather than records to send information, it can represent and connect records of any existing type together. It is my hope that this will allow all defensive tools to share information without the need to support any specific record format.
Currently, Moirai has reached Milestone 1. This represents basic functionality, but there is still much to do, in functionality, security, and robustness. DCES has achieved a basic, functional baseline as well.
It is time that we, as defensive security experts, have at our disposal a method for coordinating our network defense activities. Moirai is the way to do that.
Tuesday, March 26, 2013
Defensive Construct Exchange Standard 0.3
This is the last update of the Defense Construct Exchange Standard (DCES) before implementation of milestone 1 of Moirai. You can read more about the previous version 0.1 and version 0.2.
The major changes in this version are:
The major changes in this version are:
- Attribute edges need to be "described by" rather than describes. This will change the direction of the edges in the construct to the standard in version 0.1. This way edges 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.
- Attributes no longer require a "metadata" property. Instead, the dictionary containing the single {type:value} dictionary will be stored in the "label" of the attributes
- Event, Condition, and Actor nodes are considered the same node if the have exactly matching labels.
- Edges are considered the same if they have the same source & target.
Defensive Construct Exchange Standard 0.3:
Mandatory Statements:
- All discrete pieces of information within a construct shall be given an individual node.
- All nodes within the construct shall have the property "class" of value "attribute".
- The actual attribute property shall be stored as a JSON object within the node's "label" property. The object shall have a single {"type":"value"} pair. All other type:value pares shall be rejected.
- All nodes shall be linked to a node containing a construct ID generated by the construct originator. (It is recommended that those receiving constructs into their own graphs generate a local construct ID so as to avoid conflicts within their graph.)
- The construct ID shall be a child node of all Attributes within the construct.
- The nodes and edges shall 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 https://github.com/gdbassett/moirai/blob/dev-ms1/protocol_definitions.txt
- The DCES event shall have a "dces_version" property.
- The WAMP standard should be used when the DCES event is transmitted to/from an RPC or pubsub.
Optional Statements to facilitate usage:
- Attribute nodes within the construct may have their own attributes. (I.E. A threat construct's location attribute may have a 'classification' attribute.)
- 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.3"} could represent a single construct". While it is possible to create a construct in the receiving graph with multiple messages, it is unnecessarily complex.
- 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 recipient's attack graph, it is recommended the recipient return the the node ID of the node storing the construct ID in the recipient's graph.
- "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
- Event, Condition, and Actor nodes are considered the same node if the have exactly matching labels.
- Edges are considered the same if they have the same source & target.
Example:
This example, used previosuly has been updated to be a DCES version 0.3 compliant construct transmitted in a single event. Graphically, it can be represented as:
This produces the following Object which can be dumped to json. (Please note, as the CPT for the construct ID is quite large, I have left it out.)
{"dces_version":"0.3",
"ae":{"1":{"source":"B","target":"A","directed":true, "relationship":"describes","start":"2013-03-14T16:57Z"},
"2":{"source":"C","target":"A","directed":true, "relationship":"described by","start":"2013-03-14T16:57Z"},
"3":{"source":"D","target":"A","directed":true, "relationship":"described by","start":"2013-03-14T16:57Z"},
"4":{"source":"C","target":"D","directed":true, "relationship":"described by","start":"2013-03-14T16:57Z"},
"5":{"source":"B","target":"C","directed":true, "relationship":"described by","start":"2013-03-14T16:57Z"},
"6":{"source":"E","target":"A","directed":true, "relationship":"described by","start":"2013-03-14T16:57Z"},
"7":{"source":"F","target":"A","directed":true, "relationship":"described by","start":"2013-03-14T16:57Z"},
"8":{"source":"G","target":"A","directed":true, "relationship":"described by","start":"2013-03-14T16:57Z"},
"9":{"source":"F","target":"G","directed":true, "relationship":"described by","start":"2013-03-14T16:57Z"},
"10":{"source":"E","target":"F","directed":true, "relationship":"described by","start":"2013-03-14T16:57Z"},
"11":{"source":"H","target":"A","directed":true, "relationship":"described by","start":"2013-03-14T16:57Z"},
"12":{"source":"I","target":"A","directed":true, "relationship":"described by","start":"2013-03-14T16:57Z"},
"13":{"source":"J","target":"A","directed":true, "relationship":"described by","start":"2013-03-14T16:57Z"},
"14":{"source":"I","target":"J","directed":true, "relationship":"described by","start":"2013-03-14T16:57Z"},
"15":{"source":"H","target":"I","directed":true, "relationship":"described by","start":"2013-03-14T16:57Z"}},
"an":{"A":{"label":{"id":"<value>"},"start":"2013-03-14T16:57Z","cpt":{"nodeid":"A"}},
"B":{"label":{"url":"<value>"},"start":"2013-03-14T16:57Z","cpt":{"nodeid":"B","index":["C",true,false],"0":[0,1,0],"1":[1,1,0]}},
"C":{"label":{"domain":"<value>"},"start":"2013-03-14T16:57Z","cpt":{"nodeid":"C","index":["D",true,false],"0":[0,1,0],"1":[1,1,0]}},
"D":{"label":{"whois":"<value>"},"start":"2013-03-14T16:57Z","cpt":{"nodeid":"D","index":[true,false],"0":[1,0]}},
"E":{"label":{"dns query":"<value>"},"start":"2013-03-14T16:57Z","cpt":{"nodeid":"E","index":["F",true,false],"0":[0,1,0],"1":[1,1,0]}},
"F":{"label":{"dns record":"<value>"},"start":"2013-03-14T16:57Z","cpt":{"nodeid":"F","index":["G",true,false],"0":[0,1,0],"1":[1,1,0]}},
"G":{"label":{"record type":"<value>"},"start":"2013-03-14T16:57Z","cpt":{"nodeid":"G","index":[true,false],"0":[1,0]}},
"H":{"label":{"dns query":"<value2>"},"start":"2013-03-14T16:57Z","cpt":{"nodeid":"H","index":["I",true,false],"0":[0,1,0],"1":[1,1,0]}},
"I":{"label":{"dns record":"<value2>"},"start":"2013-03-14T16:57Z","cpt":{"nodeid":"I","index":["J",true,false],"0":[0,1,0],"1":[1,1,0]}},
"J":{"label":{"record type":"<value2>"},"start":"2013-03-14T16:57Z","cpt":{"nodeid":"J","index":[true,false],"0":[1,0]}}}}
This version of the DCES standard will be used for Moirai Milestone 1. For those interested, the following python code can reproduce the CPT for node A. .
d = {}
d["nodeid"] = "A"
d["index"] = ["B", "C", "D", "E", "F", "G", "H", "I", "J", true, false]
parents = len(d["index"]) - 2
for i in range(0,2**parents):
k = [int(x) for x in list('{0:0b}'.format(i))]
for l in range(0, parents - len(k)):
k.insert(0,0)
k.append(1)
k.append(0)
d[i] = k
Subscribe to:
Posts (Atom)
