Networks can be gigantic, period. Scanning from different network vantage points can also be challenging. The more and more I started getting into the weeds of a networking using Masscan and Nmap, the harder it was for me to make visual sense of its topology. Sure, I could use spreadsheets like everyone else but this is 2022 and spreadsheets make my head spin. We have better tools at our disposal to make this information more legible.
The goals are simple which makes the tools simple:
- Gather hosts and their IPs
- Gather all of the ports they have open
- Import them into a Graph Database
- Understand the relationships between hosts and ports discovered
What are Graph Databases?
In its simplest form, a Graph Database contains a collection of ‘nodes’. These ‘nodes’ serve as datapoints containing information. For our example, a node could be a “Host” and contain the host IP and hostname.
The real power of a Graph Database comes in when you’re able to establish relationships between nodes. So if we had a Host node (ip: 10.0.0.6) and a Port node (no: 22), we can establish that relationship, query it, and find other relationships like it.
What is Neo4j?
What’s unique to Neo4j specifically is that it uses a query language called Cypher. While the syntax of “MATCH”ing can be strange at first, it makes sense the more you use it. There are even tutorials and cheat sheets to help you out.
Finally, how do the tools work?
The tools take the greppable output (
-oG) from your nmap or masscan scans and parse them for Neo4j – that’s it! While the scripts parse differently, because nmap and masscan outputs are different, you just need to run them against your Neo4j instance to import the data.
python3 nmap-to-neo4j.py -p password -f nmap.gnmap -b 0.0.0.0
Once the results are imported, you can use Cypher to query for your results. Personally, I like looking for machines with like-ports to help further enumeration and potential attacks. So a query would look like this in Cypher
MATCH (p:Port)-->(h) WHERE p.port = '22' RETURN p,h
The query above tells Neo4j the following:
- to find all Port nodes with the port number “22”
- fetch all relationships those Port nodes have (which is “open”)
- return the Port nodes and whatever relationships they have (as “h”)
What will be returned are some nice bubbles containing your port and host its related to.
-ai/--attacking-ip can allow you to label your attacking host (
-ah/--attacking-host) to better represent the relationships from “where” you were connecting from. The aim is to help testing from different perspectives as it adds an “Attacker” node with a “CONNECTS_TO” relationship.
Really like that spreadsheet output? You can change your return values to help with that.
MATCH (p:Port)-->(h) WHERE p.port = '22' RETURN h.ip
If these tools are of interest to you, please feel free to check them out. I look forward to using them myself and building out improvements as time goes on.