0

Assume I have a list of hosts I want to scan. For each host I have a list of allowed ports.

192.168.1.2;80,443 
192.168.1.3;3306

The list above reads "1st IP is allowed to have port 80 and 443 open, and the 2nd IP is allowed to have port 3306 open".

I want to run this scan to identify hosts which have ports open except the ones in the allowed list above.

e.g. assume suddenly 192.168.1.3 has also port 80 open, then I want generate an alert like:

Alert: Found forbidden open port(s) on 192.168.1.3: 80 (Expected: 3306)

Question: How can this be achieved efficiently?

Additional question: Is there a word / term for what I am asking for? Had a hard time googling this. I was thinking something like "firewall unit testing" - like Unit-Testing components in source-code, but this time for firewalls.

Christoph
  • 103
  • 4

1 Answers1

0

You can achieve this with a simple bash script and some XSLT processing of nmap's output.

Let's say you put the list of allowed ports in the format you presented in /usr/local/etc/check-ports.conf.

You can create a bash script (/usr/local/bin/check-ports), which will call nmap <host> --excluded-ports <port_list> for each line in your list:

#!/bin/bash
STYLESHEET=/usr/local/share/check-ports/nmap.xslt
cat /usr/local/etc/check-ports.conf |
  while IFS=";" read -a line; do
    options="-oX -"
    if [ "${line[1]}" != "" ]; then
      options="$options --exclude-ports ${line[1]}"
    fi
    /usr/bin/nmap $options ${line[0]} |
      /usr/bin/xsltproc --stringparam expected "${line[1]}" $STYLESHEET -
  done

and you put a simple XSLT stylesheet in /usr/local/share/check-ports/nmap.xslt:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:param name="expected"/>
  <xsl:output method="text" />
  <xsl:template match="/"><xsl:apply-templates select="//host" /></xsl:template>
  <xsl:template match="host">
    <xsl:apply-templates select="//port">
      <xsl:with-param name="host" select="address/@addr" />
    </xsl:apply-templates>
  </xsl:template>
  <xsl:template match="port[state/@state = 'open']">
    <xsl:param name="host" />Alert: Found forbidden open port(s) on <xsl:value-of select="$host" />: <xsl:value-of select="@portid"/> (expected: <xsl:value-of select="$expected" />)
</xsl:template>
</xsl:stylesheet>

to transform nmap's XML output:

<nmaprun ...
  <host starttime="1580679113" endtime="1580679113">
    <address addr="127.0.0.1" addrtype="ipv4"/>
    <ports>
      <port protocol="tcp" portid="22">
        <state state="open" reason="syn-ack" reason_ttl="0"/>
        <service name="ssh" method="table" conf="3"/>
      </port>
...

into the output you gave in the question.

Piotr P. Karwasz
  • 5,292
  • 2
  • 9
  • 20