-
Notifications
You must be signed in to change notification settings - Fork 0
/
Grapher.py
69 lines (60 loc) · 2.81 KB
/
Grapher.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import json
from py2neo import Graph, Node, Relationship
SERVER = "server"
SERVICE = "service"
PORT = "port"
PRODUCT = "product"
VERSION = "version"
CPE = "cpe"
VULNERABILITY = "vulnerability"
CWE = "cwe"
PUBLISHED = "published"
SUMMARY = "summary"
OPEN = "open"
KEY_STATUS = "status"
KEY_ADDRESSES = "addresses"
KEY_VENDOR = "vendor"
KEY_HOSTNAME = "hostname"
KEY_CVE = "id"
KEY_SUMMARY = "summary"
KEY_PUBLISHED = "Published"
KEY_VERSION = "version"
KEY_PRODUCT = "product"
KEY_CPE = "cpe"
KEY_STATE = "state"
KEY_VULNERABILITIES = "vulnerabilities"
HAS = "HAS"
top_keys = [KEY_STATUS, KEY_ADDRESSES, KEY_VENDOR, KEY_HOSTNAME]
SAMPLE_DATA_PATH = "./sample_scan.json"
class Grapher:
def __init__(self):
self.graph = Graph()
"""Accepts a dict of scanning results and adds the server, its ports and vulerabilities in Neo4jDB"""
def plot_scan_results(self, res):
for host in res.keys():
hostname = res[host][KEY_HOSTNAME]
server = Node(SERVER, id=host, address=host, hostname=hostname)
for attr in res[host].keys():
if attr not in top_keys:
for portno in res[host][attr]:
if res[host][attr][portno].get(KEY_STATE, "closed") == OPEN:
product = res[host][attr][portno][KEY_PRODUCT]
version = res[host][attr][portno][KEY_VERSION]
cpe = res[host][attr][portno][KEY_CPE]
vulnerabilities = res[host][attr][portno][KEY_VULNERABILITIES]
port = Node(PORT, id=portno, number=portno, protocol=attr, product=product, version=version, cpe=cpe, state=OPEN)
server_has_port = Relationship(server, HAS, port)
self.graph.create(server_has_port)
for vulnerability in vulnerabilities:
published = vulnerability[KEY_PUBLISHED]
cve = vulnerability[KEY_CVE]
summary = vulnerability[KEY_SUMMARY]
vuln = Node(VULNERABILITY, id=cve, cve=cve, summary=summary, published=published)
port_has_vuln = Relationship(port, HAS, vuln)
self.graph.create(port_has_vuln)
def main():
g = Grapher()
res = json.load(open(SAMPLE_DATA_PATH))
g.plot_scan_results(res)
if __name__ == "__main__":
main()