From 79ae90e80fa16e69229fd0eab994f7b51a6907f3 Mon Sep 17 00:00:00 2001 From: david Date: Fri, 29 Apr 2011 03:56:03 +0000 Subject: [PATCH] Add nmaprun information to Ndiff output. Patch by Daniel Miller. --- CHANGELOG | 3 +++ ndiff/docs/ndiff.dtd | 9 ++++++++- ndiff/ndiff | 48 ++++++++++++++++++++++++++++++++++++++++++-- ndiff/ndifftest.py | 8 ++++++++ 4 files changed, 65 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index f5d9f84b5..957c8b90d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,8 @@ # Nmap Changelog ($Id$); -*-text-*- +o [Ndiff] Added nmaprun element information to the diff. [Daniel + Miller] + o Added a GKrellM service probe from Toni Ruottu. o [NSE] Removed the nmap.get_interface_link function, which was diff --git a/ndiff/docs/ndiff.dtd b/ndiff/docs/ndiff.dtd index 0b074cec6..087ab3375 100644 --- a/ndiff/docs/ndiff.dtd +++ b/ndiff/docs/ndiff.dtd @@ -73,6 +73,13 @@ version 0, which was rather different. --> + + @@ -127,6 +134,6 @@ version 0, which was rather different. --> - + diff --git a/ndiff/ndiff b/ndiff/ndiff index b9a0dbebf..c84be65c3 100755 --- a/ndiff/ndiff +++ b/ndiff/ndiff @@ -30,7 +30,9 @@ class Scan(object): container for a list of hosts. It also has utility methods to load itself from an Nmap XML file.""" def __init__(self): + self.scanner = None self.version = None + self.args = None self.start_date = None self.end_date = None self.hosts = [] @@ -59,6 +61,21 @@ class Scan(object): finally: f.close() + def nmaprun_to_dom_fragment(self, document): + frag = document.createDocumentFragment() + elem = document.createElement(u"nmaprun") + if self.scanner is not None: + elem.setAttribute(u"scanner", self.scanner) + if self.args is not None: + elem.setAttribute(u"args", self.args) + if self.start_date is not None: + elem.setAttribute(u"start", "%d" % time.mktime(self.start_date.timetuple())) + elem.setAttribute(u"startstr", self.start_date.strftime("%a %b %d %H:%M:%S %Y")) + if self.version is not None: + elem.setAttribute(u"version", self.version) + frag.appendChild(elem) + return frag + class Host(object): """A single host, with a state, addresses, host names, a dict mapping port specs to Ports, and a list of OS matches. Host states are strings, or None @@ -383,11 +400,17 @@ class ScriptResult(object): def format_banner(scan): """Format a startup banner more or less like Nmap does.""" - parts = [u"Nmap"] + scanner = u"Nmap" + if scan.scanner is not None and scan.scanner != u"nmap": + scanner = scan.scanner + parts = [ scanner ] if scan.version is not None: parts.append(scan.version) + parts.append(u"scan") if scan.start_date is not None: - parts.append(u"at %s" % scan.start_date.strftime("%Y-%m-%d %H:%M")) + parts.append(u"initiated %s" % scan.start_date.strftime("%a %b %d %H:%M:%S %Y")) + if scan.args is not None: + parts.append(u"as: %s" % scan.args) return u" ".join(parts) def print_script_result_diffs_text(title, script_results_a, script_results_b, @@ -482,6 +505,16 @@ class ScanDiff(object): self.scan_a.post_script_results, self.scan_b.post_script_results, self.post_script_result_diffs) + def nmaprun_to_dom_fragment(self, document): + frag = document.createDocumentFragment() + a_elem = document.createElement(u"a") + a_elem.appendChild(self.scan_a.nmaprun_to_dom_fragment(document)) + frag.appendChild(a_elem) + b_elem = document.createElement(u"b") + b_elem.appendChild(self.scan_b.nmaprun_to_dom_fragment(document)) + frag.appendChild(b_elem) + return frag + def print_xml(self, f = sys.stdout): impl = xml.dom.minidom.getDOMImplementation() document = impl.createDocument(None, u"nmapdiff", None) @@ -490,6 +523,15 @@ class ScanDiff(object): scandiff_elem = document.createElement(u"scandiff") root.appendChild(scandiff_elem) + # nmaprun changes + if ( verbose or + self.scan_a.scanner != self.scan_b.scanner or + self.scan_a.version != self.scan_b.version or + self.scan_a.args != self.scan_b.args or + self.scan_a.start_date != self.scan_b.start_date or + self.scan_a.end_date != self.scan_b.end_date ): + scandiff_elem.appendChild(self.nmaprun_to_dom_fragment(document)) + # prerule script changes. if len(self.pre_script_result_diffs) > 0 or verbose: prescript_elem = document.createElement(u"prescript") @@ -1052,6 +1094,8 @@ class NmapContentHandler(xml.sax.handler.ContentHandler): if attrs.has_key(u"start"): start_timestamp = int(attrs.get(u"start")) self.scan.start_date = datetime.datetime.fromtimestamp(start_timestamp) + self.scan.scanner = attrs.get(u"scanner") + self.scan.args = attrs.get(u"args") self.scan.version = attrs.get(u"version") elif name == u"host": assert self.parent_element() == u"nmaprun" diff --git a/ndiff/ndifftest.py b/ndiff/ndifftest.py index 994e18ee9..a875dd5dd 100755 --- a/ndiff/ndifftest.py +++ b/ndiff/ndifftest.py @@ -48,6 +48,14 @@ class scan_test(unittest.TestCase): self.assertEqual(len(host.ports), 6) self.assertEqual(set(host.extraports.items()), set([("filtered", 95), ("open|filtered", 99)])) + def test_nmaprun(self): + """Test that nmaprun information is recorded.""" + scan = Scan() + scan.load_from_file("test-scans/empty.xml") + self.assertEqual(scan.scanner, u"nmap") + self.assertEqual(scan.version, u"4.90RC2") + self.assertEqual(scan.args, u"nmap -oX empty.xml -p 1-100") + def test_addresses(self): """Test that addresses are recorded.""" scan = Scan()