29.6.17

Ergebnisse aus NMAP in eine MySQL Datenbank schreiben

Es gibt bei Nmap die Möglichkeit die Ergebnisse von Netzwerkscans in eine XML-Datei zu schreiben. Die Weiterverarbeitung mit Linux-Bordmitteln ist jedoch nicht ganz trivial. Jedenfalls habe ich es mit xmlstartlet nicht so richtig hinbekommen.
Nmap wird z.B. gestartet mit

nmap -Pn 192.168.0178.0/24 -oX output/ZIELDATEI.xml

Mit einem Einzeiler, wie

xmlstarlet sel -t -m '/nmaprun/host' -v 'address[@addrtype="ipv4"]/@addr' -o ":" -v 'ports/port/@portid' -n /var/www/html/netzinfo/output/ZIELDATEI.xml

bekomme ich zwar alle Ports nacheinander angezeigt, doch die Zuordnung von IP Adressen zu den offenen Ports muss noch erfolgen.

Da ich das Ergebnis sowieso noch einmal durchgehen muss und alles in eine MySQL Datenbank eintragen will, habe ich mir das Ganze etwas vereinfacht und eine Sprache genommen, die ich etwas besser beherrsche: PHP.

Die Ausgabedatei habe ich testweise so eingeladen und ausgegeben:

$xml = file_get_contents("output/ZIELDATEI.xml");
$p = \xml_parser_create();
\xml_parse_into_struct($p, $xml, $data, $values);
\xml_parser_free($p);
echo "Index array <br><pre>";
print_r($values);
echo "data array <br><pre>";
print_r($data);
Ausgabe (auszugsweise):
260] => Array
        (
            [tag] => ADDRESS
            [type] => complete
            [level] => 3
            [attributes] => Array
                (
                    [ADDR] => 192.168.178.150
                    [ADDRTYPE] => ipv4
                )

        )

    [261] => Array
        (
            [tag] => HOST
            [value] => 

            [type] => cdata
            [level] => 2
        )

    [262] => Array
        (
            [tag] => ADDRESS
            [type] => complete
            [level] => 3
            [attributes] => Array
                (
                    [ADDR] => 74:75:48:A4:48:A8
                    [ADDRTYPE] => mac
                    [VENDOR] => Amazon Technologies
                )

        )
Auch hier ist es nicht so einfach, eine einwandfrei Zuordnung, von z.B. IP - Adressen zu offenen Ports und Mac-Adressen zu treffen.
Geholfen haben mir die Beispiele auf php.net und zwar die Funktion von efredericksen.

<?php class XmlElement {
  var
$name;
  var
$attributes;
  var
$content;
  var
$children;
};

function
xml_to_object($xml) {
 
$parser = xml_parser_create();
 
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
 
xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
 
xml_parse_into_struct($parser, $xml, $tags);
 
xml_parser_free($parser);

 
$elements = array();  // the currently filling [child] XmlElement array
 
$stack = array();
  foreach (
$tags as $tag) {
   
$index = count($elements);
    if (
$tag['type'] == "complete" || $tag['type'] == "open") {
     
$elements[$index] = new XmlElement;
     
$elements[$index]->name = $tag['tag'];
     
$elements[$index]->attributes = $tag['attributes'];
     
$elements[$index]->content = $tag['value'];
      if (
$tag['type'] == "open") {  // push
       
$elements[$index]->children = array();
       
$stack[count($stack)] = &$elements;
       
$elements = &$elements[$index]->children;
      }
    }
    if (
$tag['type'] == "close") {  // pop
     
$elements = &$stack[count($stack) - 1];
      unset(
$stack[count($stack) - 1]);
    }
  }
  return
$elements[0];  // the single top-level element}
Die Ausgabe ist so, dass ich dann durch alle Ergebnisse der Nmap Ausgabe interieren kann.
Das PHP Script sieht so aus (quick and dirty):


$xml=file_get_contents("output/ZIELDATEI.xml");
$object = \xml_to_object($xml)->children;
// Gehe alle Objekte durch:
$anzahl = count($object);
for($i=0; $i<$anzahl; $i++)
{
    // IP Adresse
    $ip = $object[$i]->children[1]->attributes['addr'];
    if(strlen($ip)<1) continue;
    echo "Adresse: $ip<br>";
    // Rechnername
    $name=$object[$i]->children[3]->children[0]->attributes['name'];
    echo "Name: $name <br>";
    // MAC Adresse
    $mac=$object[$i]->children[2]->attributes['addr'];
    echo "MAC Adresse: $mac <br>";
    $vendor=$object[$i]->children[2]->attributes['vendor'];
    echo "Hersteller: $vendor <br>";
    // Offene Ports
    $anzahlports=count($object[$i]->children[4]->children);
    $port=""; $ports="";
    for($a=0;$a<$anzahlports; $a++)
    {
        $port=$object[$i]->children[4]->children[$a]->attributes['portid'];
        if(strlen($port)>0)
        {
            $ports.= $port . ";";
        }
    }
    echo "Offene Ports: $ports <br>";
}

Mit diesen Daten kann ich nun weiterarbeiten und sie z.B. in eine MySQL Datenbank schreiben.
Vielleicht hat jemand einfachere Lösungen??



Keine Kommentare:

Kommentar veröffentlichen

Openhab und Ecoflow Max - API Anbindung

 Ich wollte die neu erworbene Powerstation in Openhab einbinden, um den aktuellen Status (Ladestand etc.) über Openhab auswerten zu können. ...