Monday, August 25, 2008

The Inventory and The Topology

As of today (or yesterday, depending on your time zone), Zenmap has a couple of hot new features:
  • The network inventory
  • Graphical topology visualization
The network inventory is a new concept that allows you to run many scans from inside one Zenmap window, and view all results as if they were a part of one "big" scan. Each host's information is updated every time a scan targeting it has finished executing. This is done carefully, keeping host information from previous scans if the new scan doesn't discover anything new about the host.

Graphical topology visualization is achieved by integrating RadialNet into Zenmap. Every time you run a traceroute scan (nmap --traceroute ...), the network topology (accessible from the "Topology" tab) gets updated.

To illustrate these powerful concepts, consider the following example: we will run a quick nmap -p80 -PN --traceroute google.com/28 scan to enumerate a couple of Google's web servers. Then, we will run a more aggressive scan on a couple of those machines to illustrate the cumulative nature of the underlying network inventory.

After running nmap -p80 -PN --traceroute google.com/28, we get the following:

Notice that the toolbar and the tab interface have been removed from Zenmap, in an ongoing effort to maximize useful space. Now, if we click on the "Topology" tab, we get the following:

And there it is, the path that your packets have travelled on their way to Google. In the bottom of the screen, you can see a number of nodes connected to the localhost node with a dashed line. This indicates that there's no traceroute information available for these nodes. You can find more details about the visualization at the RadialNet homepage.

Now let's say we want to run two in-depth scans on lm-in-f96.google.com and lm-in-f97.google.com. We'll run a regular scan on f96 and an OS detection scan on f97. So, we enter the first target into the "Target" field, select the "Regular Scan" profile, and run it. Without waiting for the first scan to finish, we enter the second target, select the "Operating System Detection" profile, and run the scan. Clicking on the "Scans" tab will get us the following:

We can see that there are two scans running in the background, plus the finished traceroute scan we ran earlier. Back in the "Nmap output" tab, you can select which scan's output you want to see by selecting it from the dropdown box at the top of the tab.


You can see that lm-in-f97.google.com's icon has changed to a penguin image, indicating that there's now an OS detection result for that host. You can view the details in the usual fashion, by selecting lm-in-f97.google.com in the host list and clicking on "Host Details".

Now, we have acquired the information we need, so we'd like to save it. Since there are three scans in the current inventory, we can choose to either save some (or all) of them individually by hand (Scan -> Save Scan), or we can choose to save the entire inventory to a directory (Scan -> Save to Directory). The former works just as you would expect, saving one scan of choice to a .usr file. The latter saves all scans to a given directory, so that the inventory can later be easily loaded by selecting Scan -> Open -> (from the Open Scan dialog) Open Directory.

Note that Zenmap will refuse to save the inventory to a directory that contains files that are not a part of the inventory. However, you can save the inventory to a directory it has been loaded from, since Zenmap is trying to emulate saving to a file as much as possible. In other words, you can open the inventory from "myinv/", run some scans, and then save the inventory back to "myinv/".

You can append any saved scan to the inventory by selecting "Append scan" from the "Scans" tab. Also, you can remove a scan from the inventory by selecting the scan and clicking on "Remove scan".

These changes are now a part of the main Zenmap branch, so if you want to give them a shot before the next Nmap version is released, fire up your svn:

svn co --username guest --password "" svn://svn.insecure.org/zenmap

cd zenmap
./zenmap &

Have fun!

Thursday, July 10, 2008

Thursday, June 19, 2008

Search interface redesigned

I have completed the search interface redesign. Until the changes are merged into the main branch, you can check out the changes from my zenmap-search branch:

svn co svn://svn.insecure.org/nmap-exp/vladimir/zenmap-search
cd zenmap-search
./zenmap

Thursday, June 5, 2008

Search scenarios and solving them

Since the Search Window overhaul is reaching the "testable by community" phase, here are a couple of real-world search scenarios and their equivalent search strings in Zenmap. I'm assuming that the current date is 2008-06-05, and I'm using full operator names. You can always use aliases if you want a shorter (and quicker to type) search.
  • Find scans performed yesterday.
    date:-1
    or
    date:2008-06-04
  • Find scans performed any time in the last week.
    after:-7
    or
    after:2008-05-29
  • Find scans with hosts that have a given host (12.34.56.78) in their path.
    inroute:12.34.56.78
  • Find all scans containing machines running OpenSSH.
    service:openssh
There are still real-world scenarios that need to be taken into account, which cannot yet be expressed in Zenmap, such as:
  • Find all scans containing Debian and Ubuntu machines.
  • Find all scans containing machines with port 22 open or with a service named ssh.
These two examples both require some form of an or-search, which is not planned for this initial release. At the moment, you can accomplish these queries by making two separate searches.

Monday, May 26, 2008

Search Window TODO

After discussing the future functionality of Zenmap's Search Window on the mailing list, I have assembled the following TODO.

Supported operators and their aliases:
  • profile: (pr:) - Profile used.
  • target: (t:) - Scan target(s). Matches the user-supplied target, or a rDNS result.
  • option: (o:) - Scan options. This includes everything in the command line, except "nmap" and the target list. Options that take arguments can be matched using the following syntax: "opt:option_name(argument)". For example, "opt:version-intensity(9)" matches all scans that have --version-intensity set to 9.
  • date: (d:) - Date when scan was performed. Apart from the standard "date:YYYY-MM-DD" format, it will be possible to perform fuzzy matching using the "~" prefix. For example, "date:2008-12-25~" matches all scans performed from 00:00 on December 24 until 00:00 on December 27 (a span of three days). Using the fuzziness operator twice means the span of five days (in the previous example, 00:00 on December 23 until 00:00 on December 28). The "~" operator can be used anywhere in the date string, since it gets stripped out before parsing the date.
    In addition, it is possible to use the "date:-n" notation which means "n days ago". Basically, it just calculates the date of n days ago, and proceeds with normal date logic. Fuzzy matching is also applicable here.
  • after: (a:) - Matches scans made after the supplied date (YYYY-MM-DD). The "-n" notation can also be used (see above).
  • before (b:) - Matches scans made before the supplied date. The "-n" notation can also be used.
  • os: - Matches all OS-related fields (including vendor, device type, OS details, OS class, OS version, etc.).
  • scanned: (sp:) - Matches a port if it was among those scanned.
  • open: (op:) - Open ports discovered in a scan. For example, "op:22" returns all scans that discovered an open SSH port.
  • closed: (cp:) - Closed ports discovered in a scan.
  • filtered: (fp:) - Filtered ports discovered in scan.
  • unfiltered: (ufp:) - Unfiltered ports found in a scan (using, for example, an ACK scan).
  • open|filtered: (ofp:) - Matches ports in the "open|filtered" state.
  • closed|filtered: (cfp:) - Matches ports in the "closed|filtered" state.
  • service: (s:) - Service discovered running on a port. Matches all service-related fields, where present.
  • inroute: (ir:) - Matches a router in the scan's traceroute output.
Additionally,
  • "Bare" search strings (without an operator) match anything, anywhere in the scan's output or its command string.
  • Searches that contain spaces can be wrapped inside quotation marks.
  • The "and" operator is implicit.

Thursday, May 15, 2008

Tasks

I have nearly finished doing one of my first real tasks, which is to get nmap_command_path to actually work from within Zenmap, with the path to the nmap executable located in the Zenmap.conf file. I should be making my first SVN commit today too for this! Exciting.

Wednesday, May 7, 2008

My 2 cents on code style I would like to avoid

While working on the assignment, I came across some code that took me a while to decipher. For example:
        for result in results:
if results[result][1].is_unsaved():
for i in range(self.scan_notebook.get_n_pages()):
if results[result][0] == "Unsaved " + \
self.scan_notebook.get_nth_page(i).get_tab_label():
self.scan_notebook.set_current_page(i)
else:
page = self._load(parsed_result=results[result][1],
title=results[result][1].scan_name)
page.status.set_search_loaded()
or
        selection = self.result_view.get_selection()
rows = selection.get_selected_rows()
list_store = rows[0]

results = {}
for row in rows[1]:
r = row[0]
results[list_store[r][2]] = self.parsed_results[list_store[r][2]]

return results

This stuff makes perfect sense, but only after a couple of minutes of deciphering (with possible documentation lookups). Also, it has no comments whatsoever. If we are to make Zenmap a better Nmap frontend, we need to start by improving code readability - it makes maintenance easier and allows new developers (like myself) to dig right into the code.

Monday, May 5, 2008

Zenmapper #2

Hi -- I will be working with Vladimir over the summer to improve the Zenmap interface and design for the Google Summer of Code 2008 program. I go to the University of Illinois at Urbana-Champaign, going to start my third year for B.S. in Computer Science soon. This summer should certainly be quite interesting!

Sunday, May 4, 2008

Getting ready for Summer of Code 2008

Hi everyone.

I've started this blog in order to provide a centralized place for information on Zenmap development that will take place during this year's Google Summer Of Code. I will be working on various usability improvements, as well as coding the new Network Mapping mode. I will not be alone - Jurand Nogiec will also be working on improving Zenmap and making it the coolest Nmap frontend ever. :) Our efforts will be coordinated by David Fifield.

I'm currently familiarizing myself with Zenmap code and working on improving the comments on the two source files that David gave me as a small pre-SoC assignment. (I have two exams coming up, so I won't be doing anything big or interesting until after May 18.)

Here's a snapshot of my SoC application, just so you have a picture of what ideas I proposed. (My actual SoC schedule will probably include a lot of work on usability, so these ideas will probably have to wait at least a couple of weeks after coding starts.)

I am planning to integrate RadialNet into Zenmap, and implement the ideas I brought out on the nmap-dev mailing list [http://seclists.org/nmap-dev/2008/q1/0409.html]. The folks from Umit have already done some work on merging RadialNet and Umit, but the only place where it can be seen in action is the YouTube video they posted. It cannot even be checked out from SVN. However, I won't try to redo their work, as my approach as different.

I think a "Network Mapping" mode (working title) should be created. It should be accessible from the toolbar, or from the "Scan" menu. When it is invoked, a new "Network Mapping" window will open, presenting a user with an empty RadialNet workspace, and a command line at the bottom. The command line can be used to run a regular Nmap sweep (or select an existing scan profile from the list), or it can be used to invoke a "network discovery" command.

Both the idea and the mechanism behind the "network discovery" command is explained in my post to the nmap-dev mailing list [http://seclists.org/nmap-dev/2008/q1/0409.html], along with a proof-of-concept code and some ugly screenshots. Of course, it will be modified to utilize Nmap's traceroute functionality.

Now, having browsed through the RadialNet code, it lacks some key features, which I intend to add:

1. Selection tool - currently, nodes cannot be selected on the topology, so that a new scan can be run on them. By adding a new "Select Nodes" tool, it will be possible to *expand* a scan, adding information to the topology, without the need of running a new scan. Without the ability to append scan data to an already existing topology, one would have to create two separate topology graphs, which basically represent the same network but with different scan types / targets.

From the GUI point of view, I think a "Scan further..." button should become available as soon as one or more hosts are selected, presenting a user with a scan profile list, or the option of running a Command Wizard to construct the scan. As for 1337 guys, they can type something like "nmap [options] $selected" into the command line.

2. Two-way communication between the "host application" (Zenmap) and RadialNet - RadialNet currently loads its topology from an .xml file, which is only good if you want to statically interpret the scan results. You cannot do any active interaction with the topology after it's loaded (I don't count zooming and rotating as "active interaction").

A thorough two-way communication must be designed and implemented. I say "two-way", because I think we want to keep the existing Zenmap functionality useful even when running scans from the "Network Mapping" (NM) window. For example, when a first scan is run from the NM window, the Zenmap window should open a new tab which will present regular on-the-fly information. Now, let's say a user selects a few nodes on the topology graph and runs (appends) a new scan from within the NM window - a new tab opens in Zenmap window, presenting us with this scan's progress and results, and so on. Thus, we keep the original Zenmap functionality, but we empower it with RadialNet's goodness.