Skip to content

Instantly share code, notes, and snippets.

@ImpostorKeanu
Created January 23, 2021 19:06
Show Gist options
  • Save ImpostorKeanu/0d8f1442b7b634fbeb1f8a4852ce41db to your computer and use it in GitHub Desktop.
Save ImpostorKeanu/0d8f1442b7b634fbeb1f8a4852ce41db to your computer and use it in GitHub Desktop.
XSL file to limit hosts and ports only to those that are responsive/open in NMap XML documents
<!--
Quick and dirty XSL file to lessen the size of large NMap
XML files. Below is an example using the lxml library in Python.
Observed to reduce size of a 300MB XML IP protocol scan to 19MB
in less than a minute.
from lxml import etree as ET
document = ET.parse('to_transform.xml')
xslt = ET.parse('nmap_open_only.xsl')
transform = ET.XSLT(xslt)
with open('transformed.xml', 'wb+') as outfile:
outfile.write(
ET.tostring(transform(document), pretty_print=True))
-->
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="/nmaprun">
<nmaprun>
<xsl:copy-of select="@*|b/@*"/>
<xsl:copy-of select="/nmaprun/scaninfo"/>
<xsl:copy-of select="/nmaprun/taskbegin"/>
<xsl:copy-of select="/nmaprun/taskend"/>
<xsl:if test="/nmaprun/taskbegin[@task='Ping Scan']">
<xsl:for-each select="//host/status[@state='up']">
<xsl:copy-of select=".."/>
</xsl:for-each>
</xsl:if>
<xsl:if test="/nmaprun/taskbegin[@task!='Ping Scan']">
<xsl:for-each select="//host">
<xsl:choose>
<xsl:when test="./ports/port/state[@state='open']">
<xsl:copy select=".">
<xsl:copy-of select="@*"/>
<xsl:copy-of select="./status"/>
<xsl:copy-of select="./address"/>
<xsl:copy-of select="./hostnames"/>
<xsl:copy-of select="./times"/>
<xsl:for-each select="./ports/port/state[@state='open']">
<ports>
<xsl:copy-of select="../../extraports"/>
<xsl:for-each select="..">
<xsl:copy-of select="."/>
</xsl:for-each>
</ports>
</xsl:for-each>
</xsl:copy>
</xsl:when>
<xsl:when test=".//hostname">
<xsl:copy select="../..">
<xsl:copy-of select="@*"/>
<!-- Set to up to ensure that hostnames are captured -->
<status state="up" reason="user-set" reason_ttl="0"/>
<xsl:copy-of select="./address"/>
<xsl:copy-of select="./hostnames"/>
<xsl:copy-of select="./times"/>
<ports/>
</xsl:copy>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:if>
</nmaprun>
</xsl:template>
</xsl:stylesheet>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment