Benutzer-Werkzeuge

Webseiten-Werkzeuge


kismet_auf_dem_pi

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

kismet_auf_dem_pi [2015/06/02 19:57] (aktuell)
admin angelegt
Zeile 1: Zeile 1:
 +====== Kismet auf dem Pi ======
 +Kismet soll auf dem Pi nicht zum "​war-drive"​ zum Einsatz kommen, sondern ein wenig Überblick über die gewünschten und ggfls. auch unerwünschten Besucher im heimischen Umfeld geben.
 +====== Voraussetzungen ======
 +Ein paar Pakete und dev-Pakete sind für's kompilieren und für den "​Betrieb"​ notwendig. Außerdem gibt es ein paar Tools, die einem den Umgang mit dem System erleichtern.
 +<code bash>
 +# Voraussetzungen
 +apt-get install build-essential wireshark libncurses5-dev libcap-dev \
 +libpcre3-dev libnl-3-dev libnl-genl-3-dev
 +# Tools
 +apt-get install vim rcconf
 +</​code>​
  
 +====== Kismet kompilieren ======
 +<code bash>
 +wget http://​www.kismetwireless.net/​code/​kismet-2013-03-R1b.tar.gz
 +tar xvf kismet-2013-03-R1b.tar.gz ​
 +cd kismet-2013-03-R1b/​
 +./configure --with-suidgroup=pi --prefix=/​usr/​local/​kismet --sysconfdir=/​etc/​kismet
 +##########################​ OUTPUT
 +# ...
 +Configuration complete: ​
 +         ​Compiling for: linux-gnueabihf (armv6l)
 +           C++ Library: stdc++
 +   ​Installing as group: root
 +    Man pages owned by: man
 +       ​Installing into: /​usr/​local/​kismet
 +          Setuid group: pi
 +      Terminal Control: ncurses
 +   Linux WEXT capture : yes
 +   ​OSX/​Darwin capture : n/a (only OSX/Darwin)
 +   PCRE Regex Filters : yes
 +          pcap capture: yes
 +       ​airpcap control: n/a (only Cygwin/​Win32)
 +        PPI log format: yes
 +LibCapability (enhanced
 +   ​privilege dropping): no
 +         Linux Netlink: yes (mac80211 VAP creation) - libnl-3.0 libnl-genl-3.0
 +
 +# ...
 +###########################################################​
 +
 +make
 +make suidinstall
 +</​code>​
 +
 +====== Konfigurieren ======
 +
 +<code bash>
 +# vi /​etc/​kismet/​kismet.conf
 +# ... 
 +logprefix=/​var/​log/​kismet
 +# ...
 +ncsource=wlan0:​type=rt73,​forcevap=false,​validatefcs=true
 +# ...
 +#​ouifile=/​etc/​manuf
 +ouifile=/​etc/​kismet/​manuf
 +# ...
 +gps=false
 +# ...
 +</​code>​
 +
 +Eine aktuelle Manufacture (manuf) Datei holen:
 +<code bash>
 +cd /​etc/​kismet/​
 +wget http://​anonsvn.wireshark.org/​wireshark/​trunk/​manuf
 +</​code>​
 +
 +<code bash>
 +# vi /​etc/​default/​ifplugd ​
 +# ...
 +#​INTERFACES="​auto"​
 +INTERFACES="​eth0"​
 +#​HOTPLUG_INTERFACES="​all"​
 +HOTPLUG_INTERFACES=""​
 +# ...
 +</​code>​
 +
 +===== Startskript =====
 +Aus dem Skeleton-Skript (/​etc/​init.d/​skeleton) lässt sich "auf die Schnelle"​ ein Startskript bauen, damit der kismet_server automatisch startet. Mit Hilfe von "​rcconf"​ lässt sich dies dann auch in die entsprechende Systemkonfiguration einfügen.
 +
 +<code bash kismet_server>​
 +#! /bin/sh
 +### BEGIN INIT INFO
 +# Provides: ​         skeleton
 +# Required-Start: ​   $remote_fs $syslog
 +# Required-Stop: ​    ​$remote_fs $syslog
 +# Default-Start: ​    2 3 4 5
 +# Default-Stop: ​     0 1 6
 +# Short-Description:​ Example initscript
 +# Description: ​      This file should be used to construct scripts to be
 +#                    placed in /​etc/​init.d.
 +### END INIT INFO
 +
 +# Author: Foo Bar <​foobar@baz.org>​
 +#
 +# Please remove the "​Author"​ lines above and replace them
 +# with your own name if you copy and modify this script.
 +
 +# Do NOT "set -e"
 +
 +# PATH should only include /usr/* if it runs after the mountnfs.sh script
 +PATH=/​sbin:/​usr/​sbin:/​bin:/​usr/​bin:/​usr/​local/​kismet/​bin
 +DESC="​Kismet Server"​
 +NAME=kismet_server
 +DAEMON=/​usr/​local/​kismet/​bin/​kismet_server
 +DAEMON_ARGS="​--daemonize"​
 +PIDFILE=/​var/​run/​$NAME.pid
 +SCRIPTNAME=/​etc/​init.d/​$NAME
 +
 +# Exit if the package is not installed
 +[ -x "​$DAEMON"​ ] || exit 0
 +
 +# Read configuration variable file if it is present
 +[ -r /​etc/​default/​$NAME ] && . /​etc/​default/​$NAME
 +
 +# Load the VERBOSE setting and other rcS variables
 +. /​lib/​init/​vars.sh
 +
 +# Define LSB log_* functions.
 +# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
 +# and status_of_proc is working.
 +. /​lib/​lsb/​init-functions
 +
 +#
 +# Function that starts the daemon/​service
 +#
 +do_start()
 +{
 +        # Return
 +        #   0 if daemon has been started
 +        #   1 if daemon was already running
 +        #   2 if daemon could not be started
 +        start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
 +                || return 1
 +        start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
 +                $DAEMON_ARGS \
 +                || return 2
 +        # Add code here, if necessary, that waits for the process to be ready
 +        # to handle requests from services started subsequently which depend
 +        # on this one.  As a last resort, sleep for some time.
 +}
 +
 +#
 +# Function that stops the daemon/​service
 +#
 +do_stop()
 +{
 +        # Return
 +        #   0 if daemon has been stopped
 +        #   1 if daemon was already stopped
 +        #   2 if daemon could not be stopped
 +        #   other if a failure occurred
 +        start-stop-daemon --stop --quiet --retry=TERM/​30/​KILL/​5 --pidfile $PIDFILE --name $NAME
 +        RETVAL="​$?"​
 +        [ "​$RETVAL"​ = 2 ] && return 2
 +        # Wait for children to finish too if this is a daemon that forks
 +        # and if the daemon is only ever run from this initscript.
 +        # If the above conditions are not satisfied then add some other code
 +        # that waits for the process to drop all resources that could be
 +        # needed by services started subsequently. ​ A last resort is to
 +        # sleep for some time.
 +        start-stop-daemon --stop --quiet --oknodo --retry=0/​30/​KILL/​5 --exec $DAEMON
 +        [ "​$?"​ = 2 ] && return 2
 +        # Many daemons don't delete their pidfiles when they exit.
 +        rm -f $PIDFILE
 +        return "​$RETVAL"​
 +}
 +
 +#
 +# Function that sends a SIGHUP to the daemon/​service
 +#
 +do_reload() {
 +        #
 +        # If the daemon can reload its configuration without
 +        # restarting (for example, when it is sent a SIGHUP),
 +        # then implement that here.
 +        #
 +        start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
 +        return 0
 +}
 +
 +case "​$1"​ in
 +  start)
 +        [ "​$VERBOSE"​ != no ] && log_daemon_msg "​Starting $DESC" "​$NAME"​
 +        do_start
 +        case "​$?"​ in
 +                0|1) [ "​$VERBOSE"​ != no ] && log_end_msg 0 ;;
 +                2) [ "​$VERBOSE"​ != no ] && log_end_msg 1 ;;
 +        esac
 +        ;;
 +  stop)
 +        [ "​$VERBOSE"​ != no ] && log_daemon_msg "​Stopping $DESC" "​$NAME"​
 +        do_stop
 +        case "​$?"​ in
 +                0|1) [ "​$VERBOSE"​ != no ] && log_end_msg 0 ;;
 +                2) [ "​$VERBOSE"​ != no ] && log_end_msg 1 ;;
 +        esac
 +        ;;
 +  status)
 +        status_of_proc "​$DAEMON"​ "​$NAME"​ && exit 0 || exit $?
 +        ;;
 +  #​reload|force-reload)
 +        #
 +        # If do_reload() is not implemented then leave this commented out
 +        # and leave '​force-reload'​ as an alias for '​restart'​.
 +        #
 +        #​log_daemon_msg "​Reloading $DESC" "​$NAME"​
 +        #do_reload
 +        #​log_end_msg $?
 +        #;;
 +  restart|force-reload)
 +        #
 +        # If the "​reload"​ option is implemented then remove the
 +        # '​force-reload'​ alias
 +        #
 +        log_daemon_msg "​Restarting $DESC" "​$NAME"​
 +        do_stop
 +        case "​$?"​ in
 +          0|1)
 +                do_start
 +                case "​$?"​ in
 +                        0) log_end_msg 0 ;;
 +                        1) log_end_msg 1 ;; # Old process is still running
 +                        *) log_end_msg 1 ;; # Failed to start
 +                esac
 +                ;;
 +          *)
 +                # Failed to stop
 +                log_end_msg 1
 +                ;;
 +        esac
 +        ;;
 +  *)
 +        #echo "​Usage:​ $SCRIPTNAME {start|stop|restart|reload|force-reload}"​ >&2
 +        echo "​Usage:​ $SCRIPTNAME {start|stop|status|restart|force-reload}"​ >&2
 +        exit 3
 +        ;;
 +esac
 +
 +</​code>​
 +
 +
 +====== plugins ======
 +Die Plugins werden im Source-Code mitgeliefert,​ müssen aber noch kompiliert werden.
 +Man kann alle Plugins "auf ein Mal" kompilieren:​
 +<code bash>
 +cd /​install/​kismet-2013-03-R1b ​
 +make plugins
 +make plugins-install
 +</​code>​
 +
 +Benötigt werden für dieses "​Projekt"​ aber nur das '​plugin-syslog'​ und das '​plugin-btscan'​.
 +===== plugin-syslog =====
 +Explizites Kompilieren des plugin-syslog
 +<code bash>
 +cd /​install/​kismet-2013-03-R1b/​plugin-syslog
 +export KIS_SRC_DIR=/​install/​kismet-2013-03-R1b ​  # Pfad zu den Kismet-Sourcen mitgeben
 +export KIS_DEST_DIR=/​usr/​local/​kismet/​plugins ​   # Installations-Ziel
 +# funktioniert so nicht. ​
 +# Plugins werden nach /​usr/​local/​kismet/​lib/​kismet installiert
 +make
 +make install
 +</​code>​
 +
 +===== config =====
 +In der kismet.conf
 +<code bash>
 +# vi /​etc/​kismet/​kismet.conf
 +# ...
 +# servername=Kismet Server
 +servername=kismet
 +# => hiermit wird der Syslog-Tag gefüllt. Wenn nichts angegeben wird, 
 +#    wird der Hostname genommen, der eh schon im Syslog steht.
 +# ...
 +# JB NEW ->
 +# Syslog log types can be:
 +#        all          All messages from Kismet are logged
 +#        none         No messages from Kismet are logged
 +#        info         ​INFO-class messages
 +#        error        ERROR-class messages
 +#        fatal        FATAL-class messages
 +#        alert        ALERT-class messages
 +syslogtype=all
 +# <- JB NEW
 +# ...
 +#​logtypes=pcapdump,​gpsxml,​netxml,​nettxt,​alert
 +logtypes=alerts
 +# wenn das plugin-syslog benutzt wird, kann auf die meissten logs verzichtet werden.
 +</​code>​
 +
 +===== plugin-btscan =====
 +Bluetooth-Erkennung
 +<code bash>
 +apt-get install bluetooth libbluetooth-dev
 +cd /​install/​kismet-2013-03-R1b/​plugin-btscan
 +export KIS_SRC_DIR=/​install/​kismet-2013-03-R1b ​  # Pfad zu den Kismet-Sourcen mitgeben
 +make
 +make install
 +</​code>​
 +====== Weiterverarbeitung / WhoIsWho ======
 +Zur Weiterverarbeitung sollen die Syslog-Meldungen in eine MySQL-DB geschrieben werden. Wir nutzen dazu das rsyslog-MySQL Modul und lassen den rsyslog direkt passend filtern.
 +
 +<code bash>
 +apt-get install rsyslog-mysql
 +# ...
 +# dbconfig-common
 +# Konfigurieren der Datenbank für rsyslog-mysql mit dbconfig-common?​ <​Nein>​
 +</​code>​
 +
 +Die automatische Konfiguration wird abgelehnt, da eine DB auf einem anderen System genutzt werden soll und weil zusätzliche Tabellen benötigt werden.
 +
 +===== rsyslog =====
 +Die vom MySQL-Modul mitgebrachte /​etc/​rsyslog.d/​mysql.conf kann gelöscht werden.
 +<code bash kismet.conf>​
 +# vi /​etc/​rsyslog.d/​kismet.conf
 +# MySQL Modul
 +$ModLoad ommysql
 +# 1 Tabelle - alles vom Kismet
 +if $syslogtag startswith '​kismet:'​ then :​ommysql:​192.168.11.11,​kismet,​kismet,​password
 +# zweite Tabelle - nur Netzwerke und clients
 +$template SystemEventsKismet,"​insert into Incoming (FromHost, Facility, Priority, Message, DeviceReportedTime,​ ReceivedAt, InfoUnitID, SyslogTag ) values ('​%HOSTNAME%',​ ' %syslogfacility%',​ '​%syslogpriority%',​ '​%msg%',​ '​%timereported:::​date-mysql%',​ '​%timegenerated:::​date-mysql%', ​ %iut%, '​%syslogtag%'​)",​SQL
 +#if $syslogtag startswith '​kismet:'​ then :​ommysql:​192.168.11.11,​kismet,​kismet,​password;​SystemEventsKismet
 +:​msg,​contains,"​new managed network"​ :​ommysql:​192.168.11.11,​kismet,​kismet,​password;​SystemEventsKismet
 +:​msg,​contains,"​new probe network"​ :​ommysql:​192.168.11.11,​kismet,​kismet,​password;​SystemEventsKismet
 +:​msg,​contains,"​new data network"​ :​ommysql:​192.168.11.11,​kismet,​kismet,​password;​SystemEventsKismet
 +:​msg,​contains,"​new ad-hoc network"​ :​ommysql:​192.168.11.11,​kismet,​kismet,​password;​SystemEventsKismet
 +</​code>​
 +
 +
 +===== Datenbank =====
 +Für die Datenbank brauchen wir, falls noch nicht vorhanden, einen MySQL-Server und sinnvollerweise PHPMyAdmin für die Verwaltung.
 +<code bash>
 +apt-get install mysql-server
 +apt-get install phpmyadmin
 +</​code>​
 +
 +Die entsprechende Datenbank kann dann über den Reiter "​SQL"​ im PHPMyAdmin angelegt werden. Bitte vorher "​mypassword"​ durch etwas sinnvolles ersetzen.
 +
 +==== whoiswho.sql ====
 +
 +<code sql whoiswho.sql>​
 +--
 +-- Anlegen der DB und eines entsprechenden Users
 +--
 +CREATE USER '​kismet'​@'​%'​ IDENTIFIED BY '​mypassword';​
 +GRANT USAGE ON * . * TO '​kismet'​@'​%'​ IDENTIFIED BY '​mypassword'​ WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;
 +CREATE DATABASE IF NOT EXISTS `kismet` ;
 +GRANT ALL PRIVILEGES ON `kismet` . * TO '​kismet'​@'​%';​
 +
 +-- --------------------------------------------------------
 +
 +--
 +-- Tabellenstruktur für Tabelle `Incoming`
 +--
 +
 +CREATE TABLE IF NOT EXISTS `Incoming` (
 +  `ID` int(10) unsigned NOT NULL AUTO_INCREMENT,​
 +  `CustomerID` bigint(20) DEFAULT NULL,
 +  `ReceivedAt` datetime DEFAULT NULL,
 +  `DeviceReportedTime` datetime DEFAULT NULL,
 +  `Facility` smallint(6) DEFAULT NULL,
 +  `Priority` smallint(6) DEFAULT NULL,
 +  `FromHost` varchar(60) DEFAULT NULL,
 +  `Message` text,
 +  `NTSeverity` int(11) DEFAULT NULL,
 +  `Importance` int(11) DEFAULT NULL,
 +  `EventSource` varchar(60) DEFAULT NULL,
 +  `EventUser` varchar(60) DEFAULT NULL,
 +  `EventCategory` int(11) DEFAULT NULL,
 +  `EventID` int(11) DEFAULT NULL,
 +  `EventBinaryData` text,
 +  `MaxAvailable` int(11) DEFAULT NULL,
 +  `CurrUsage` int(11) DEFAULT NULL,
 +  `MinUsage` int(11) DEFAULT NULL,
 +  `MaxUsage` int(11) DEFAULT NULL,
 +  `InfoUnitID` int(11) DEFAULT NULL,
 +  `SysLogTag` varchar(60) DEFAULT NULL,
 +  `EventLogType` varchar(60) DEFAULT NULL,
 +  `GenericFileName` varchar(60) DEFAULT NULL,
 +  `SystemID` int(11) DEFAULT NULL,
 +  `processid` varchar(60) NOT NULL DEFAULT '',​
 +  `checksum` int(11) unsigned NOT NULL DEFAULT '​0',​
 +  PRIMARY KEY (`ID`),
 +  KEY `FromHost` (`FromHost`),​
 +  KEY `checksum` (`checksum`),​
 +  KEY `DeviceReportedTime` (`DeviceReportedTime`),​
 +  KEY `EventID` (`EventID`),​
 +  KEY `InfoUnitID` (`InfoUnitID`)
 +) ENGINE=InnoDB ​ DEFAULT CHARSET=latin1 AUTO_INCREMENT=33 ;
 +
 +-- --------------------------------------------------------
 +
 +--
 +-- Tabellenstruktur für Tabelle `Manufacturer`
 +--
 +
 +CREATE TABLE IF NOT EXISTS `Manufacturer` (
 +  `MAC` varchar(20) NOT NULL,
 +  `ShortDescription` varchar(20) NOT NULL,
 +  `Description` text NOT NULL,
 +  PRIMARY KEY (`MAC`)
 +) ENGINE=InnoDB DEFAULT CHARSET=latin1;​
 +
 +-- --------------------------------------------------------
 +
 +--
 +-- Tabellenstruktur für Tabelle `Seen`
 +--
 +
 +CREATE TABLE IF NOT EXISTS `Seen` (
 +  `ID` int(11) NOT NULL AUTO_INCREMENT,​
 +  `SyslogID` int(11) NOT NULL,
 +  `MAC` varchar(20) NOT NULL,
 +  `Time` datetime NOT NULL,
 +  `Name` varchar(50) NOT NULL,
 +  `Type` varchar(20) NOT NULL,
 +  `Encryption` varchar(10) NOT NULL,
 +  `Channel` int(3) NOT NULL,
 +  `BitRate` int(8) NOT NULL,
 +  PRIMARY KEY (`ID`)
 +) ENGINE=InnoDB ​ DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
 +
 +
 +-- --------------------------------------------------------
 +
 +--
 +-- Tabellenstruktur für Tabelle `SystemEvents`
 +--
 +
 +CREATE TABLE IF NOT EXISTS `SystemEvents` (
 +  `ID` int(10) unsigned NOT NULL AUTO_INCREMENT,​
 +  `CustomerID` bigint(20) DEFAULT NULL,
 +  `ReceivedAt` datetime DEFAULT NULL,
 +  `DeviceReportedTime` datetime DEFAULT NULL,
 +  `Facility` smallint(6) DEFAULT NULL,
 +  `Priority` smallint(6) DEFAULT NULL,
 +  `FromHost` varchar(60) DEFAULT NULL,
 +  `Message` text,
 +  `NTSeverity` int(11) DEFAULT NULL,
 +  `Importance` int(11) DEFAULT NULL,
 +  `EventSource` varchar(60) DEFAULT NULL,
 +  `EventUser` varchar(60) DEFAULT NULL,
 +  `EventCategory` int(11) DEFAULT NULL,
 +  `EventID` int(11) DEFAULT NULL,
 +  `EventBinaryData` text,
 +  `MaxAvailable` int(11) DEFAULT NULL,
 +  `CurrUsage` int(11) DEFAULT NULL,
 +  `MinUsage` int(11) DEFAULT NULL,
 +  `MaxUsage` int(11) DEFAULT NULL,
 +  `InfoUnitID` int(11) DEFAULT NULL,
 +  `SysLogTag` varchar(60) DEFAULT NULL,
 +  `EventLogType` varchar(60) DEFAULT NULL,
 +  `GenericFileName` varchar(60) DEFAULT NULL,
 +  `SystemID` int(11) DEFAULT NULL,
 +  `processid` varchar(60) NOT NULL DEFAULT '',​
 +  `checksum` int(11) unsigned NOT NULL DEFAULT '​0',​
 +  PRIMARY KEY (`ID`),
 +  KEY `FromHost` (`FromHost`),​
 +  KEY `checksum` (`checksum`),​
 +  KEY `DeviceReportedTime` (`DeviceReportedTime`),​
 +  KEY `EventID` (`EventID`),​
 +  KEY `InfoUnitID` (`InfoUnitID`)
 +) ENGINE=InnoDB ​ DEFAULT CHARSET=latin1 AUTO_INCREMENT=288 ;
 +
 +-- --------------------------------------------------------
 +
 +--
 +-- Tabellenstruktur für Tabelle `WellKnown`
 +--
 +
 +CREATE TABLE IF NOT EXISTS `WellKnown` (
 +  `MAC` varchar(20) NOT NULL,
 +  `Comment` text NOT NULL,
 +  PRIMARY KEY (`MAC`)
 +) ENGINE=InnoDB DEFAULT CHARSET=latin1;​
 +
 +
 +</​code>​
 +
 +===== Webfrontend =====
 +<code bash>
 +apt-get install apache2 php5 php5-mysql
 +</​code>​
 +
 +Ein einfaches Webfront-End lässt sich schnell mit PHP erstellen. Natürlich braucht der Apache dafür noch eine entsprechende Config.
 +
 +<code apache>
 +# vi /​etc/​apache2/​conf.d/​whoiswho.conf
 +Alias /whoiswho "/​usr/​local/​whoiswho"​
 +
 +<​Directory "/​usr/​local/​whoiswho">​
 +   ​Options +FollowSymLinks
 +   ​AllowOverride None
 +#   ​AuthName "​WhoIsWho Access"​
 +#   ​AuthType Basic
 +#   ​AuthUserFile /​usr/​local/​whoiswho/​etc/​htpasswd.users
 +#   ​Require valid-user
 +</​Directory>​
 +</​code>​
 +
 +Unter /​usr/​local/​whoiswho wird die eigentliche Webseite angelegt.
 +<code bash>
 +mkdir /​usr/​local/​whoiswho
 +mkdir /​usr/​local/​whoiswho/​cron
 +mkdir /​usr/​local/​whoiswho/​etc
 +mkdir /​usr/​local/​whoiswho/​include
 +#mkdir /​usr/​local/​whoiswho/​images # noch nicht benötigt
 +</​code>​
 +
 +==== index.php ====
 +
 +<code php index.php>​
 +<!-- vi /​usr/​local/​whoiswho/​index.php -->
 +<?php
 +#  SESSION_NAME("​WHOISWHO"​);​
 +#  SESSION_START();​
 +  require_once("​etc/​whoiswho.conf.php"​);​
 +  require_once("​include/​mysql.inc.php"​);​
 +  require_once("​include/​tools.inc.php"​);​
 +  if (isset($_GET['​col'​]) && is_numeric($_GET['​col'​]) ) {
 +    //isset prüft, ob eine Variable gesetzt ist
 +    if ($_GET['​col'​] >= 0 && $_GET['​col'​] < 5) {
 +    //​Validitätsprüfung,​ nur Spalten 0..4 erlaubt
 +      $sort_column = $_GET['​col'​];​
 +    } else {
 +      echo "<​H1>​HANDS OFF MY URL!!!</​H1>";​
 +      $sort_column = 0;
 +    }
 +  } else {
 +    $sort_column = 0;
 +  };
 +  if (isset($_GET['​group'​]))
 +  { $group = $_GET['​group'​];​ } else { $group = "​no";​ };
 +  #​error_log("​INDEX.PHP GROUP: $group"​);​
 +  $title = "Who are my '​wireless'​ visitors";​
 +  $db = dbconnect();​
 +  $table = SEENTABLE;
 +  switch($sort_column)
 +  {
 +    case '​0':​
 +      $sql = "​SELECT * FROM $table ORDER BY ID DESC";
 +      $title = $title."​ (sort by ID)";
 +    break;
 +    case '​1':​
 +      $sql = "​SELECT * FROM $table ORDER BY TIME DESC";
 +      $title = $title."​ (sort by Time)";​
 +    break;
 +    case '​2':​
 +      if ($group == "​yes"​)
 +      {
 +        $sql = "​SELECT * FROM $table GROUP BY MAC ASC";
 +        $title = $title."​ (grouped by MAC)";
 +      } else {
 +        $sql = "​SELECT * FROM $table ORDER BY MAC ASC";
 +        $title = $title."​ (sort by MAC)";
 +      };
 +    break;
 +    case '​3':​
 +     if ($group == "​yes"​)
 +      {
 +        $sql = "​SELECT * FROM $table GROUP BY Name DESC";
 +        $title = $title."​ (grouped by Network name)";​
 +      } else {
 +        $sql = "​SELECT * FROM $table ORDER BY Name DESC";
 +        $title = $title."​ (sort by Network name)";​
 +      };
 +    break;
 +    case '​4':​
 +      $sql = "​SELECT * FROM $table ORDER BY Type DESC";
 +      $title = $title."​ (sort by Network type)";​
 +    break;
 +    default:
 +      $sql = "​SELECT * FROM $table ORDER BY Time DESC;";​
 +      $title = $title."​ (sort by Time)";​
 +  }
 +?>
 +
 +<​html>​
 +  <​head>​
 +     <​title>'​WhoIsWho'</​title>​
 +     <​meta charset="​utf-8">​
 +     <​link rel="​stylesheet"​ type="​text/​css"​ href="​whoiswho.css">​
 +     <​meta http-equiv="​refresh"​ content="​60">​
 +  </​head>​
 +
 +<​body>​
 +<table width=1000><​caption><?​=$title;?></​caption>​
 +<​thead>​
 +        <th style='​width:​50px'><​a href="​index.php?​col=0">​ID</​a></​th>​
 +        <th style='​width:​150px'><​a href="​index.php?​col=1">​Time</​a></​th>​
 +        <th style='​width:​150px'><​a href="​index.php?​col=2">​MAC</​a>​ &nbsp; <a href="​index.php?​col=2&​group=yes">​(group)</​a></​th>​
 +        <th style='​width:​200px'><​a href="​index.php?​col=3">​Network name</​a>​ &nbsp; <a href="​index.php?​col=3&​group=yes">​(group)</​a></​th>​
 +        <th style='​width:​100px'><​a href="​index.php?​col=4">​Network type</​a></​th>​
 +        <th style='​width:​400px'>​Comment</​th>​
 +</​thead>​
 +<​tbody>​
 +
 +<?php
 +  $sth = $db->​query($sql);​
 +  while ($row = $sth->​fetch())
 +    {
 +      $comment = lookup_mac($row['​MAC'​]);​
 +      ?>
 +        <tr>
 +        <​td><?​=$row['​ID'​];?></​td>​
 +        <​td><?​=$row['​Time'​];?></​td>​
 +        <​td><​a href="#"​ onclick='​window.open("​macinfo.php?​mac=<?​=$row['​MAC'​];?>&​comment=<?​=$comment;?>","​WhoIsWho MAC-Info","​directories=0,​titlebar=0,​toolbar=0,​location=0,​status=0,​menubar=0,​scrollbars=yes,​resizable=no,​width=650,​height=350"​);​ return false;'><?​=$row['​MAC'​];?></​a></​td>​
 +        <​td><​a href="#"​ onclick='​window.open("​netinfo.php?​net=<?​=$row['​Name'​];?>","​WhoIsWho Network-Info","​directories=0,​titlebar=0,​toolbar=0,​location=0,​status=0,​menubar=0,​scrollbars=yes,​resizable=no,​width=950,​height=350"​);​ return false;'><?​=$row['​Name'​];?></​a></​td>​
 +        <​td><?​=$row['​Type'​];?></​td>​
 +        <​td><?​=$comment;?></​td>​
 +        </tr>
 +      <?php
 +    }
 +?>
 +</​tbody>​
 +</​thead>​
 +</​body>​
 +</​html>​
 +
 +</​code>​
 +
 +==== whoiswho.css ====
 +<code css whoiswho.css>​
 +<!-- vi /​usr/​local/​whoiswho/​whoiswho.css -->
 +table {
 +        margin:0;
 +        padding:0;
 +        font-family:​ arial, verdana, serif;
 +        color: black;
 +        font-size: 11px;
 +}
 +
 +table, tr, th, td {
 +        border-collapse:​ collapse;
 +}
 +
 +caption {
 +margin:0;
 +        padding:0;
 +        background: #f0f0f0;
 +        height: 25px;
 +        line-height:​ 25px;
 +        text-indent:​ 5px;
 +        font-family:​ arial, verdana, serif;
 +        font-weight:​ bold;
 +        color: black;
 +        font-size: 13px;
 +        text-align: left;
 +        /​*letter-spacing:​ 3px;*/
 +        border: solid 1px #c0c0c0;
 +}
 +
 +thead th {
 +        height: 22px;
 +        line-height:​ 20px;
 +        text-align: left;
 +        color: black;
 +        font-size: 13px;
 +        background: #A2A2A2;
 +}
 +
 +tbody tr {
 +        background: white;
 +        padding: 3px;
 +}
 +
 +tbody tr:hover {
 +        background: #d0d0d0;
 +        /​*text-decoration:​ underline;​*/​
 +}
 +
 +table a {
 +        /*color: #2c3763;*/
 +        color: black;
 +        text-decoration:​ none;
 +        font-size: 11px;
 +        font-weight:​ bold;
 +        border-bottom:​ solid 1px black;
 +}
 +
 +table a:hover {
 +        /*color: #2c3763;*/
 +        color: black;
 +        font-weight:​ bold;
 +        text-decoration:​ underline;
 +        border-bottom:​ none;
 +}
 +
 +table a:visited {
 +        /*color: #2c3763;*/
 +        color: black;
 +        font-weight:​ bold;
 +}
 +</​code>​
 +
 +==== macinfo.php ====
 +<code php macinfo.php>​
 +<!-- vi /​usr/​local/​whoiswho/​macinfo.php -->
 +<?php
 +  require_once("​etc/​whoiswho.conf.php"​);​
 +  require_once("​include/​mysql.inc.php"​);​
 +  require_once("​include/​tools.inc.php"​);​
 +  if (isset($_GET['​mac'​]))
 +    {
 +      $mac = $_GET['​mac'​];​
 +      // Prüfen ob MAC-Aufbau
 +      // preg_grep('/​([a-fA-F0-9]{2}[:​|\-]?​){6}/',​ $msg)
 +    } else {
 +      $mac = "​unkown";​
 +    };
 +
 +  if (isset($_GET['​comment'​]))
 +    {
 +      $comment = $_GET['​comment'​];​
 +    } else {
 +      $comment = "​unkown";​
 +    };
 +
 +  $db = dbconnect();​
 +  $table = SEENTABLE;
 +  $title = "MAC Info for $mac - $comment";​
 +?>
 +
 +<​html>​
 +  <​head>​
 +     <​title>'​WhoIsWho - MAC Info'</​title>​
 +     <​meta charset="​utf-8">​
 +     <​link rel="​stylesheet"​ type="​text/​css"​ href="​whoiswho.css">​
 +<​!-- ​    <​meta http-equiv="​refresh"​ content="​60"> ​ -->
 +  </​head>​
 +
 +<​body>​
 +<table width=620><​caption><?​=$title;?></​caption>​
 +<​thead>​
 +        <th style='​width:​120px'>​Time</​th>​
 +        <th style='​width:​100px'>​Network name</​th>​
 +        <th style='​width:​100px'>​Network type</​th>​
 +        <th style='​width:​100px'>​Encryption</​th>​
 +        <th style='​width:​100px'>​Channel</​th>​
 +        <th style='​width:​100px'>​BitRate</​th>​
 +</​thead>​
 +<​tbody>​
 +
 +<?php
 +  $sql = "​SELECT * FROM $table WHERE MAC='​$mac'​ ORDER BY Time DESC;";​
 +  $sth = $db->​query($sql);​
 +  $sql_rc = $db->​errorCode();​
 +  error_log("​$sql_rc\n"​);​
 +
 +  while ($row = $sth->​fetch())
 +  {
 +    ?>
 +      <tr>
 +      <​td><?​=$row['​Time'​];?></​td>​
 +      <​td><​a href="#"​ onclick='​window.open("​netinfo.php?​net=<?​=$row['​Name'​];?>","​WhoIsWho Network-Info","​directories=0,​titlebar=0,​toolbar=0,​location=0,​status=0,​menubar=0,​scrollbars=yes,​resizable=no,​width=950,​height=350"​);​ return false;'><?​=$row['​Name'​];?></​a></​td>​
 +      <​td><?​=$row['​Type'​];?></​td>​
 +      <​td><?​=$row['​Encryption'​];?></​td>​
 +      <​td><?​=$row['​Channel'​];?></​td>​
 +      <​td><?​=$row['​BitRate'​];?></​td>​
 +    <?php
 +  }
 +?>
 +</​tbody>​
 +</​thead>​
 +</​body>​
 +</​html>​
 +</​code>​
 +
 +==== netinfo.php ====
 +<code php netinfo.php>​
 +<!-- vi /​usr/​local/​whoiswho/​netinfo.php -->
 +<?php
 +  require_once("​etc/​whoiswho.conf.php"​);​
 +  require_once("​include/​mysql.inc.php"​);​
 +  require_once("​include/​tools.inc.php"​);​
 +  if (isset($_GET['​net'​]))
 +    {
 +      $net = $_GET['​net'​];​
 +    } else {
 +      $net = "​unkown";​
 +    };
 +
 +  $db = dbconnect();​
 +  $table = SEENTABLE;
 +  $title = "More Info for $net";
 +?>
 +
 +<​html>​
 +  <​head>​
 +     <​title>'​WhoIsWho - Network Info'</​title>​
 +     <​meta charset="​utf-8">​
 +     <​link rel="​stylesheet"​ type="​text/​css"​ href="​whoiswho.css">​
 +<​!-- ​    <​meta http-equiv="​refresh"​ content="​60"> ​ -->
 +  </​head>​
 +
 +<​body>​
 +<table width=920><​caption><?​=$title;?></​caption>​
 +<​thead>​
 +        <th style='​width:​120px'>​Time</​th>​
 +        <th style='​width:​100px'>​MAC</​th>​
 +        <th style='​width:​100px'>​Network type</​th>​
 +        <th style='​width:​100px'>​Encryption</​th>​
 +        <th style='​width:​100px'>​Channel</​th>​
 +        <th style='​width:​100px'>​BitRate</​th>​
 +        <th style='​width:​300px'>​Comment</​th>​
 +</​thead>​
 +<​tbody>​
 +
 +<?php
 +  $sql = "​SELECT * FROM $table WHERE Name='​$net'​ ORDER BY Time DESC;";​
 +  $sth = $db->​query($sql);​
 +  $sql_rc = $db->​errorCode();​
 +  error_log("​$sql_rc\n"​);​
 +
 +  while ($row = $sth->​fetch())
 +  {
 +    $comment = lookup_mac($row['​MAC'​]);​
 +    ?>
 +      <tr>
 +      <​td><?​=$row['​Time'​];?></​td>​
 +      <​td><​a href="#"​ onclick='​window.open("​macinfo.php?​mac=<?​=$row['​MAC'​];?>&​comment=<?​=$comment;?>","​WhoIsWho MAC-Info","​directories=0,​titlebar=0,​toolbar=0,​location=0,​status=0,​menubar=0,​scrollbars=yes,​resizable=no,​width=650,​height=350"​);​ return false;'><?​=$row['​MAC'​];?></​a></​td>​
 +      <​td><?​=$row['​Type'​];?></​td>​
 +      <​td><?​=$row['​Encryption'​];?></​td>​
 +      <​td><?​=$row['​Channel'​];?></​td>​
 +      <​td><?​=$row['​BitRate'​];?></​td>​
 +      <​td><?​=$comment;?></​td>​
 +    <?php
 +  }
 +?>
 +</​tbody>​
 +</​thead>​
 +</​body>​
 +</​html>​
 +</​code>​
 +
 +==== import-manuf.php ====
 +
 +Auf dem Pi ist der I/O nicht wirklich schnell, weshalb es zu empfehlen ist, die "​manuf"​-Datei in eine entsprechende Tabelle der Datenbank zu importieren.
 +
 +Eine aktuelle "​manuf"​-Datei gibts unter https://​code.wireshark.org/​review/​gitweb?​p=wireshark.git;​a=blob_plain;​f=manuf;​hb=HEAD ... abgelegt wird diese unter /​usr/​local/​whoiswho/​etc/​.
 +
 +<code php import-manuf.php>​
 +<!-- vi /​usr/​local/​whoiswho/​import-manuf.php>​
 +<?php
 +  require_once("​etc/​whoiswho.conf.php"​);​
 +  require_once("​include/​mysql.inc.php"​);​
 +  $manuf = file("/​usr/​local/​whoiswho/​etc/​manuf"​);​
 +  $i = 0;
 +  $db = dbconnect();​
 +  $table = MANUFTABLE;
 +  # clear table before start
 +  $truncsql = "​truncate $table;";​
 +  $truncsth = $db->​query($truncsql);​
 +  $sql_rc = $db->​errorCode();​
 +  print "​$truncsql ...";
 +  print "​$sql_rc\n";​
 +  print "​starting import...\n";​
 +  foreach ($manuf AS $manuf_row)
 +  {
 +    #if (preg_match("/​([a-fA-F0-9]{2}[:​|\-]?​){3}/",​$manuf_row))
 +    if (preg_match("/​([a-fA-F0-9]{2}[:​]?​){3}/",​$manuf_row))
 +    {
 +      $i++;
 +      $mac = substr($manuf_row,​0,​8);​
 +      # eliminate multiple blanks
 +      #$text = preg_replace('/​\s{2,​}/','​ ',​$manuf_row);​
 +      $manuf_row = preg_replace('/​\040{1,​}/','​ ',​$manuf_row);​
 +      # eliminate tabs
 +      $manuf_row = str_replace("​\t",​ " ", $manuf_row);​
 +      # elimate Carriage Return and Line Feed
 +      $manuf_row = rtrim($manuf_row);​
 +      $row_presplit = explode("#",​ $manuf_row);​
 +      $row_split = explode("​ ", $row_presplit[0]);​
 +      $shortdescr = $row_split[1];​
 +      if (isset($row_presplit[1]))
 +      {
 +        $descr = ltrim($row_presplit[1]);​
 +      } else
 +      {
 +        $descr = "​none";​
 +      };
 +      print "​$mac;​$shortdescr;​$descr \n";
 +      $sql = "​INSERT INTO $table (MAC,​ShortDescription,​Description) values ('​$mac','​$shortdescr','​$descr'​);";​
 +      print $sql;
 +      $sth = $db->​query($sql);​
 +  $sql_rc = $db->​errorCode();​
 +  print "​$sql_rc\n";​
 +    }
 +  }
 +  print "$i rows imported!!\n";​
 +?>
 +
 +</​code>​
 +
 +==== process_incoming.php ====
 +Die eingehenden Meldungen werden über PHP-Skript in die "​SEEN"​-Tabelle übernommen. Das PHP-Skript wird über CRON gesteuert.
 +
 +<code php process_incoming.php>​
 +<?php
 +  require_once("​../​etc/​whoiswho.conf.php"​);​
 +  require_once("​../​include/​mysql.inc.php"​);​
 +  $i = 0;
 +  $db = dbconnect();​
 +  $table = INCOMINGTABLE;​
 +  $sql = "​SELECT * FROM $table;";​
 +  $sth = $db->​query($sql);​
 +  while ($row = $sth->​fetch())
 +    {
 +      $i++;
 +      print "​Processing Message: Time: "​.$row['​DeviceReportedTime'​]."​ Message: "​.$row['​Message'​]."​\n";​
 +      # ID
 +      $id = $row['​ID'​];​
 +      # Time
 +      $time = $row['​DeviceReportedTime'​];​
 +      # WLAN name
 +      $msg = explode(",",​ $row['​Message'​]);​
 +      $msgpart = ltrim($msg[0]);​
 +      preg_match('/"​[^"​]*"/',​ $msgpart, $netnamemsg);​
 +      $netnamemsg = str_replace(['"','<','>'​],​ '',​ $netnamemsg);​
 +      $netname = $netnamemsg[0];​
 +      # getting MAC
 +      $macmsg = explode("​ ", ltrim($msg[1]));​
 +      $mac = implode(preg_grep('/​([a-fA-F0-9]{2}[:​|\-]?​){6}/',​ $macmsg));
 +      $mac = str_replace(",",​ "",​ $mac);
 +      $mac = str_replace("​-",​ ":",​ $mac);
 +      $mac = strtoupper($mac);​
 +      # network type
 +      switch (true)
 +      {
 +        case (preg_grep('/​new managed network/',​ $msg)):
 +          $type="​access point";​
 +        break;
 +        case (preg_grep('/​new probe network/',​ $msg)):
 +          $type="​client";​
 +        break;
 +        case (preg_grep('/​new ad-hoc network/',​ $msg)):
 +          $type="​ad-hoc";​
 +        break;
 +        case (preg_grep('/​new data network/',​ $msg)):
 +          $type="​data";​
 +        break;
 +        default:
 +          $type="​unknown";​
 +      }
 +      # encryption
 +      $encmsg = explode("​ ", $msg[2]);
 +      $enc = $encmsg[2];
 +      # channel
 +      $channelmsg = explode("​ ", $msg[3]);
 +      $channel = $channelmsg[2];​
 +      # bit rate
 +      $bitratemsg = explode("​ ", $msg[4]);
 +      $bitrate = $bitratemsg[1];​
 +      # insert into SEEN Table
 +      $inserttable = SEENTABLE;
 +      $insertsql = "​INSERT INTO $inserttable (SyslogID,​MAC,​Time,​Name,​Type,​Encryption,​Channel,​BitRate) values('​$id','​$mac','​$time','​$netname','​$type','​$enc','​$channel','​$bitrate'​);";​
 +      $insertsth = $db->​query($insertsql);​
 +      $sql_rc = $db->​errorCode();​
 +      #print "​$insertsql ...";
 +      #print "​$sql_rc\n";​
 +      # delete from INCOMING
 +      $delsql = "​DELETE FROM $table WHERE ID ='​$id';";​
 +      $delsth = $db->​query($delsql);​
 +    }
 +  print "$i messages processed.\n";​
 +?>
 +
 +</​code>​
 +
 +<code bash>
 +# vi /​etc/​cron.hourly/​whoiswho
 +#!/bin/bash
 +#
 +cd /​usr/​local/​whoiswho/​cron/​
 +/​usr/​bin/​php process_incoming.php
 +cd -
 +</​code>​
 +
 +==== whoiswho.conf.php ====
 +<code php whoiswho.conf.php>​
 +<!-- vi /​usr/​local/​whoiswho/​etc/​whoiswho.conf.php -->
 +<?php
 +# database connection
 +define('​DBDRIVER',​ '​mysql'​);​
 +define('​DBHOST',​ '​192.168.11.11'​);​
 +define('​DBNAME',​ '​kismet'​);​
 +define('​DBUSER',​ '​kismet'​);​
 +define('​DBPASS',​ '​password'​);​
 +define('​WELLKNOWNTABLE',​ '​WellKnown'​);​
 +define('​INCOMINGTABLE',​ '​Incoming'​);​
 +define('​SEENTABLE',​ '​Seen'​);​
 +define('​MANUFTABLE',​ '​Manufacturer'​);​
 +
 +</​code>​
 +
 +==== mysql.inc.php ====
 +<code php mysql.inc.php>​
 +<!-- vi /​usr/​local/​whoiswho/​include/​mysql.inc.php -->
 +<?php
 +
 +function dbconnect()
 +{
 +  /*$opt = array(
 +    PDO::​MYSQL_ATTR_INIT_COMMAND => "SET NAMES '​UTF8'", ​
 +    PDO::​ATTR_ERRMODE => PDO::​ERRMODE_EXCEPTION
 +  );*/
 +  $opt = array(
 +    PDO::​MYSQL_ATTR_INIT_COMMAND => "SET NAMES '​UTF8'"​
 +  );
 +  $dsn = sprintf('​%s:​host=%s;​dbname=%s',​ DBDRIVER, DBHOST, DBNAME);
 +  #​error_log("​Connect with " . $dsn);
 +  $db = new PDO($dsn, DBUSER, DBPASS, $opt);
 +  return $db;
 +}
 +
 +</​code>​
 +
 +==== tools.inc.php ====
 +<code php tools.inc.php>​
 +<!-- vi /​usr/​local/​whoiswho/​include/​tools.inc.php -->
 +<?php
 +function lookup_manuf_file($mac)
 +{
 +  $manuf = file("/​usr/​local/​whoiswho/​etc/​manuf"​);​
 +  foreach ($manuf AS $manuf_row)
 +  {
 +    if (substr($mac,​0,​8) == substr($manuf_row,​0,​8))
 +    {
 +      # eliminate multiple blanks
 +      #$text = preg_replace('/​\s{2,​}/','​ ',​$manuf_row);​
 +      $manuf_row = preg_replace('/​\040{1,​}/','​ ',​$manuf_row);​
 +      # eliminate tabs
 +      $manuf_row = str_replace("​\t",​ " ", $manuf_row);​
 +      $row_presplit = explode("#",​ $manuf_row);​
 +      $row_split = explode("​ ", $row_presplit[0]);​
 +      $shortdescr = $row_split[1];​
 +      if (isset($row_presplit[1]))
 +      {
 +        $descr = ltrim($row_presplit[1]);​
 +      } else
 +      {
 +        $descr = "​none";​
 +      };
 +    }
 +  }
 +if (isset($shortdescr) && isset($descr)) return array($shortdescr,​$descr);​
 +}
 +
 +function lookup_manuf_db($mac)
 +{
 +  $db = dbconnect();​
 +  $table = MANUFTABLE;
 +  $searchmac = substr($mac,​0,​8);​
 +  $sql = "​SELECT * FROM $table WHERE MAC='​$searchmac'​ LIMIT 1;";
 +  #​error_log("​LOOKUP_MANUF_DB:​ "​.$sql);​
 +  $sth = $db->​query($sql);​
 +  while ($row = $sth->​fetch(PDO::​FETCH_ASSOC)){
 +    (isset($row['​ShortDescription'​])) ? $shortdescr = $row['​ShortDescription'​] : $shortdesc = "​none";​
 +    (isset($row['​Description'​])) ? $descr = $row['​Description'​] : $descr = "​none";​
 +  }
 +if (isset($shortdescr) && isset($descr)) return array($shortdescr,​$descr);​
 +}
 +
 +function lookup_mac($mac)
 +{
 +  $db = dbconnect();​
 +  $table = WELLKNOWNTABLE;​
 +  $sql = "​SELECT * from $table WHERE MAC='​$mac';";​
 +  $sth = $db->​query($sql);​
 +  while ($row = $sth->​fetch(PDO::​FETCH_ASSOC))
 +    {
 +      $comment = "<​B>"​.$row['​Comment'​]."</​B>";​
 +    }
 +    if (!isset($comment))
 +    {
 +      #​list($shortdescr,​$descr) = lookup_manuf_file($mac);​
 +      list($shortdescr,​$descr) = lookup_manuf_db($mac);​
 +      if (isset($shortdescr))
 +      {
 +        if ($descr == "​none"​)
 +        {
 +          $comment = $shortdescr;​
 +        } else
 +        {
 +        $comment = $shortdescr."​ ("​.$descr."​)";​
 +        }
 +      } else $comment = "<​i>​unknown</​i>";​
 +    }
 +  return $comment;
 +}
 +
 +?>
 +
 +</​code>​
kismet_auf_dem_pi.txt · Zuletzt geändert: 2015/06/02 19:57 von admin