Sunday, April 12, 2015

Dealing with Nmap output

Port scans of multiple hosts typically result in a lot of information that I'd rather have in a spreadsheet. If you use the -oX or -oA Nmap flags, you should theoretically be able to receive XML and use XSLT to transform it into comma-separated variable (CSV) format and load it up in your spreadsheet. When I started using Nmap, I wrote an XSL stylesheet to do that, and recently I've updated it to translate pretty much all the information I'm usually interested in. It goes like this:

<?xml version="1.0" encoding="UTF-8"?>

    <xsl:output method="text" indent="no" encoding="UTF-8"/>

    <xsl:template match="/nmaprun">

        <!-- Headings -->
        <xsl:text>"OS Match",</xsl:text>
        <xsl:text>"OS Type/Vendor/Family/Gen"</xsl:text>

        <!-- Ports -->
        <xsl:for-each select="host/ports/port">
            <xsl:value-of select="../../address/@addr"/>
            <xsl:value-of select="../../hostnames/hostname/@name"/>
            <xsl:value-of select="../../hostnames/hostname/@type"/>
            <xsl:value-of select="../../status/@state"/>
            <xsl:value-of select="@protocol"/>
            <xsl:value-of select="@portid"/>
            <xsl:value-of select="service/@name"/>
            <xsl:value-of select="state/@state"/>
            <xsl:value-of select="service/@product"/>
            <xsl:value-of select="../../os/osmatch/@name"/>
            <xsl:value-of select="../../os/osmatch/osclass/@type"/>
            <xsl:text> / </xsl:text>
            <xsl:value-of select="../../os/osmatch/osclass/@vendor"/>
            <xsl:text> / </xsl:text>
            <xsl:value-of select="../../os/osmatch/osclass/@osfamily"/>
            <xsl:text> / </xsl:text>
            <xsl:value-of select="../../os/osmatch/osclass/@osgen"/>



This stylesheet can be used with Microsoft's XSL command-line transformation utility (msxsl.exe), which can be downloaded directly from Microsoft, here:

The msxsl.exe command line for Windows is:

> msxsl.exe portscan.xml nmap_xml_to_csv.xsl -o portscan.csv

Or you can use xsltproc on Linux:

$ xsltproc nmap_xml_to_csv.xsl portscan.xml --output portscan.csv

Or you can use Python or Perl or whatever. Knock yourself out.

As for how it works, the stylesheet simply uses the xsl:template element to match on the root element of the Nmap output (/nmaprun), the xsl:for-each element to iterate through ports, and Xpath expressions to pull the various host attributes out of the XML. The end result is nice and manageable:

Now you can filter on open ports, sort by host or service, and get a better look at your attack surface.

I haven't tested this with lots and lots of Nmap output, so there could be some corner cases I'm missing, but it's a start. The XSL stylesheet is reproduced in full above, but you can also find it (and other things) on my github:

For more about XSLT, I actually found w3schools to be pretty helpful:

Actually, I find pretty much all of their tutorials to be helpful. You should go and read them all. Enjoy!

No comments:

Post a Comment