Esempio n. 1
0
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
Esempio n. 2
0
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
Esempio n. 3
0
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
Esempio n. 4
0
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
Esempio n. 5
0
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
Esempio n. 6
0
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();
Esempio n. 7
0
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()