def test_bayesian(): if not check_pomegranate_installed(): pytest.skip('Pomegranate not installed.') # initialise the harm h = hm.Harm() # create the top layer of the harm # top_layer refers to the top layer of the harm h.top_layer = hm.AttackGraph() # we will create 5 nodes and connect them in some way # first we create some nodes hosts = [hm.Host("Host {}".format(i)) for i in range(5)] # then we will make a basic attack tree for each for host in hosts: # We specify the owner of the AttackTree so that the # AttackTree's values can be directly interfaced from the host host.lower_layer = hm.AttackTree(host=host) # We will make two vulnerabilities and give some metrics vulnerability1 = hm.Vulnerability('CVE-0000', values={ 'risk': 10, 'cost': 4, 'probability': 0.9, 'impact': 12 }) # basic_at creates just one OR gate and puts all vulnerabilites # the children nodes host.lower_layer.basic_at([vulnerability1]) # Now we will create an Attacker. This is not a physical node but it exists to describe # the potential entry points of attackers. attacker = hm.Attacker() # To add edges we simply use the add_edge function # here h[0] refers to the top layer # add_edge(A,B) creates a uni-directional from A -> B. h[0].add_edge(attacker, hosts[0]) h[0].add_edge(hosts[0], hosts[1]) h[0].add_edge(hosts[0], hosts[2]) h[0].add_edge(hosts[1], hosts[3]) h[0].add_edge(hosts[2], hosts[3]) h[0].add_edge(hosts[1], hosts[2]) # Now we set the attacker and target h[0].source = attacker h[0].target = hosts[3] h.flowup() result = h.bayesian_method() epsilon = 1e-4 assert abs(result['total'] - 0.8019) < epsilon assert abs(result['total_ac'] - 13.0491) < epsilon assert abs(result['ag_risk'] - 37.5435) < epsilon assert abs(result['roa'] - 9.9873) < epsilon
def parse_xml(filename): """ Convert an XML file containing the Harm into a harmat Harm object :param filename: :return: Harm """ if not os.path.isfile(filename): raise IOError("File not found") harm = harmat.Harm() harm.top_layer = harmat.AttackGraph() with open(filename, 'rb') as file: tree = ET.parse(file) root = tree.getroot() host_list = [] for root_elements in root: if cut_crap(root_elements) == 'nodes': for node in root_elements: name = node.attrib['name'] if name == 'Attacker': new_host = harmat.Attacker() harm[0].source = new_host else: new_host = harmat.Host(node.attrib['name']) for node_values in node: if cut_crap(node_values) == 'ignorable': new_host.ignorable = strtobool(node_values.text) if cut_crap(node_values) == 'host_values': for key, val in parse_values(node_values).items(): setattr(new_host, key, val) if cut_crap(node_values) == 'vulnerabilities': at = harmat.AttackTree(host=new_host) if node_values is not None: parse_xml_attacktree(node_values[0], at) new_host.lower_layer = at harm.top_layer.add_node(new_host) host_list.append(new_host) elif cut_crap(root_elements) == 'edges': for edge in root_elements: if edge[0] is not None: source = host_list[int(edge[0].text)] target = host_list[int(edge[1].text)] harm.top_layer.add_edge(source, target) return harm
def create_benchmark_harm1(): vul1 = hm.Vulnerability('CVE-TEST', values={ 'risk': 10, 'cost': 10, 'probability': 0.2, 'impact': 10 }) vul2 = hm.Vulnerability('CVE-TEST2', values={ 'risk': 13, 'cost': 12, 'probability': 0.4, 'impact': 12 }) vul3 = hm.Vulnerability('CVE-TEST2', values={ 'risk': 14, 'cost': 18, 'probability': 0.41, 'impact': 12 }) harm = hm.Harm() harm.top_layer = hm.AttackGraph() hosts = [hm.Host(str(i)) for i in range(11)] prev = None for host in hosts: harm.top_layer.add_node(host) host.lower_layer = hm.AttackTree() host.lower_layer.basic_at([vul1, vul2, vul3]) for ohost in hosts: harm.top_layer.add_edge(host, ohost) attacker = hm.Attacker() harm.top_layer.add_node(attacker) harm.top_layer.add_edge(attacker, hosts[0]) harm.top_layer.source = attacker return harm
def tiscovery_parser(filename): if not os.path.isfile(filename): raise IOError("File not found") with open(filename, 'r') as jsonfile: parsed_json = json.loads(jsonfile.read()) h = hm.Harm() h.top_layer = hm.AttackGraph() id_to_host_dict = {} # A dictionary to store id -> host object mapping for node in parsed_json['nodes']: id = node['id'] new_host = hm.Host(id) new_host.impact = node.get('impact', 0) new_host.probability = node.get('probability', 0) new_host.cost = node.get('cost', 1) new_host.risk = node.get('risk', 0) new_host.ignorable = node.get('ignorable', False) new_host.lower_layer = hm.AttackTree(host=new_host) vulns = [] for vuln in node.get('vulnerabilities', {}): for key, val in vuln.items(): harmat_vul = hm.Vulnerability(key, val) if harmat_vul.is_benign(): continue vulns.append(harmat_vul) new_host.lower_layer.basic_at(vulns) id_to_host_dict[id] = new_host h[0].add_node(new_host) for link in parsed_json['links']: source_id = link['source'] target_id = link['target'] # get back the harm objects source = id_to_host_dict[source_id] target = id_to_host_dict[target_id] h[0].add_edge(source, target) return h
import harmat as hm # initialise the harm h = hm.Harm() # create the top layer of the harm # top_layer refers to the top layer of the harm h.top_layer = hm.AttackGraph() # we will create 5 nodes and connect them in some way # first we create some nodes hosts = [hm.Host("Host {}".format(i)) for i in range(4)] # then we will make a basic attack tree for each for host in hosts: host.lower_layer = hm.AttackTree() # We will make two vulnerabilities and give some metrics vulnerability1 = hm.Vulnerability('CVE-0000', values={ 'risk': 9, 'cost': 4, 'probability': 0.2, 'impact': 12 }) vulnerability2 = hm.Vulnerability('CVE-0001', values={ 'risk': 1, 'cost': 5, 'probability': 0.2, 'impact': 2 }) # basic_at creates just one OR gate and puts all vulnerabilites
def main(): #Open a server to communicate with GUI s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind(("localhost", int(sys.argv[1]))) s.listen(1) end = "c" conn, addr = s.accept() datas=[]; #Receive data from the Cient while 1: data = conn.recv(1024) #conn.sendall(data) datas = datas + (data.decode('utf-8').splitlines()) if end in data.decode('utf-8'): break #print(datas) #Set variables numberOfNodes = int(datas[0]) numberOfArcs = int(datas[1]) # initialise the harm h = hm.Harm() # create the top layer of the harm # top_layer refers to the top layer of the harm h.top_layer = hm.AttackGraph() #print(float(datas[4+numberOfNodes*2])) #Create nodes hosts = [hm.Host(str(i)) for i in range(numberOfNodes)] #Make basic attack tree on each node i = 0 for host in hosts: if int(host.name) is int(datas[2]): continue else: host.lower_layer = hm.AttackTree() #Make a vulnerability with some metrics vulnerability1 = hm.Vulnerability('CVE-0000', values = { 'risk' : float(datas[4+numberOfArcs*2 + (i*4)]), 'cost' : float(datas[4+numberOfArcs*2+1 + (i*4)]), 'probability' : float(datas[4+numberOfArcs*2+2 + (i*4)]), 'impact' : float(datas[4+numberOfArcs*2+3 + (i*4)]) }) host.lower_layer.basic_at([vulnerability1]) i+=1 #Set a attacker hosts[int(datas[2])] = hm.Attacker() #Add Arcs between nodes based on the data from the Client for x in range (4, len(datas)-1-(4*numberOfArcs), 2): #print(int(datas[x])) #print(int(datas[x+1])) h[0].add_edge(hosts[int(datas[x])], hosts[int(datas[x+1])]) #Set the attacker and target h[0].source = hosts[int(datas[2])] h[0].target = hosts[int(datas[3])] #Flow up h.flowup() #Run some metrics hm.HarmSummary(h).show() #Send analysis to the Client a = "Number of hosts: " + str(numberOfNodes) + "\n" abytes = a.encode('utf-8') conn.send(abytes) risk = "Risk: " + str(h.risk) + "\n" riskedit = risk.encode('utf-8') conn.send(riskedit) b = "Cost: " + str(h.cost) + "\n" bbytes = b.encode('utf-8') conn.send(bbytes) c = "Mean of attack path lengths: " + str(h[0].mean_path_length()) + "\n" cbytes = c.encode('utf-8') conn.send(cbytes) d = "Mode of attack path lengths: " + str(h[0].mode_path_length()) + "\n" dbytes = d.encode('utf-8') conn.send(dbytes) e = "Shortest attack path length: " + str(h[0].shortest_path_length()) + "\n" ebytes = e.encode('utf-8') conn.send(ebytes) f = "Return of Attack: " + str(h[0].return_on_attack()) + "\n" fbytes = f.encode('utf-8') conn.send(fbytes) g = "Probability of attack success: " + str(h[0].probability_attack_success()) + "\n" gbytes = g.encode('utf-8') conn.send(gbytes) h = "Standard Deviation of attack path lengths: " + str(h[0].stdev_path_length()) + "\n" hbytes = h.encode('utf-8') conn.send(hbytes) conn.close() s.close();
def main(): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind(("localhost", int(sys.argv[1]))) #s.bind(("localhost", 5022)) s.listen(1) end = "c" conn, addr = s.accept() datas = [] while 1: data = conn.recv(1024) #conn.sendall(data) datas = datas + (data.decode('utf-8').splitlines()) if end in data.decode('utf-8'): break #print(data.decode('utf-8')) #dData = data.decode('utf-8').rstrip('\n') #if len(datas[0]) > 3: # print("error"); # datas2 = datas[0].splitlines(); # del datas[0] # datas = datas2 + datas print(datas) numberOfNodes = int(datas[0]) numberOfArcs = int(datas[1]) #numberOfArcs = int(dData[2]) print(numberOfNodes) #for x in range (4, 4+numberOfArcs*2, 3): # print(dData[x]) # print(dData[x+1]) # initialise the harm h = hm.Harm() # create the top layer of the harm # top_layer refers to the top layer of the harm h.top_layer = hm.AttackGraph() print(float(datas[4 + numberOfNodes * 2])) # we will create 5 nodes and connect them in some way # first we create some nodes hosts = [hm.Host(str(i)) for i in range(numberOfNodes)] # then we will make a basic attack tree for each i = 0 for host in hosts: if int(host.name) is int(datas[2]): continue else: host.lower_layer = hm.AttackTree() # We will make two vulnerabilities and give some metrics vulnerability1 = hm.Vulnerability( 'CVE-0000', values={ 'risk': float(datas[4 + numberOfArcs * 2 + (i * 4)]), 'cost': float(datas[4 + numberOfArcs * 2 + 1 + (i * 4)]), 'probability': float(datas[4 + numberOfArcs * 2 + 2 + (i * 4)]), 'impact': float(datas[4 + numberOfArcs * 2 + 3 + (i * 4)]) }) # basic_at creates just one OR gate and puts all vulnerabilites # the children nodes host.lower_layer.basic_at([vulnerability1]) i += 1 hosts[int(datas[2])] = hm.Attacker() # Now we will create an Attacker. This is not a physical node but it exists to describe # the potential entry points of attackers. #attacker = hm.Attacker() for x in range(4, len(datas) - 1 - (4 * numberOfArcs), 2): print(int(datas[x])) print(int(datas[x + 1])) h[0].add_edge(hosts[int(datas[x])], hosts[int(datas[x + 1])]) # To add edges we simply use the add_edge function # here h[0] refers to the top layer # add_edge(A,B) creates a uni-directional from A -> B. # h[0].add_edge(attacker, hosts[0]) # h[0].add_edge(hosts[0], hosts[3]) # h[0].add_edge(hosts[1], hosts[0]) # h[0].add_edge(hosts[0], hosts[2]) # h[0].add_edge(hosts[3], hosts[2]) # Now we set the attacker and target h[0].source = hosts[int(datas[2])] h[0].target = hosts[int(datas[3])] # do some flow up h.flowup() # Now we will run some metrics hm.HarmSummary(h).show() #result = h.bayesian_method() #print(result['total']) #client_socket.send(("Number of hosts: " + str(numberOfNodes) + "\n").encode('utf-8')) #client_socket.send(cedit) a = "Number of hosts: " + str(numberOfNodes) + "\n" abytes = a.encode('utf-8') conn.send(abytes) risk = "Risk: " + str(h.risk) + "\n" riskedit = risk.encode('utf-8') conn.send(riskedit) b = "Cost: " + str(h.cost) + "\n" bbytes = b.encode('utf-8') conn.send(bbytes) c = "Mean of attack path lengths: " + str(h[0].mean_path_length()) + "\n" cbytes = c.encode('utf-8') conn.send(cbytes) d = "Mode of attack path lengths: " + str(h[0].mode_path_length()) + "\n" dbytes = d.encode('utf-8') conn.send(dbytes) e = "Shortest attack path length: " + str( h[0].shortest_path_length()) + "\n" ebytes = e.encode('utf-8') conn.send(ebytes) f = "Return of Attack: " + str(h[0].return_on_attack()) + "\n" fbytes = f.encode('utf-8') conn.send(fbytes) g = "Probability of attack success: " + str( h[0].probability_attack_success()) + "\n" gbytes = g.encode('utf-8') conn.send(gbytes) h = "Standard Deviation of attack path lengths: " + str( h[0].stdev_path_length()) + "\n" hbytes = h.encode('utf-8') conn.send(hbytes) #conn.send("Cost: " + str(h.cost) + "\n") #conn.send("Mean of attack path lengths: " + str(h[0].mean_path_length()) + "\n") #conn.send("Mode of attack path lengths: " + str(h[0].mode_path_length()) + "\n") #conn.send("Shortest attack path length: " + str(h[0].shortest_path_length()) + "\n") #conn.send("Return of Attack: " + str(h[0].return_on_attack()) + "\n") #conn.send("Probability of attack success: " + str(h[0].probability_attack_success()) + "\n") conn.close() s.close()