snort ist ein sogn. Intrusion Detection System (kurz IDS), dasz in der Lage ist, den gesamten Netzwerkverkehr online zu analysieren und aufzuzeichnen. Es kann ebenso zur Protollanalyse verwendet werden, als auch dazu, im Strom der netzwerkdaten nach Inhalten zu suchen und entsprechende Pakete samt Inhalt zu prtokollieren. Durch die Verwendung von inhaltssensitiven Regeln kann Snort dazu eingesetzt werden, eine Vielzahl von Angriffen und Scans (wie z. B.: Buffer Overflow, Steathl-Port-Scan, CGI-Attacken, SMB-Sondierungen und aktives Fingerprinting) zu erkennen und den Verwalter zu benachrichtigen. snort kann (wenn er mit --enable-flexresp konfiguriert wurde) sogar auf eingehende Pakete antworten, indem RST-Pakete geschickt werden, welche die Verbindung wieder schlieszen sollen. Diese Benachrichtigung kann ueber syslog(), eine Datei, einen Unix Domain Socket oder smbclient in Form einer WinPopup Requesters erfolgen. snort kann mit allen dazu benoetigten Dateien ueber https://www.snort.org/ bezogen werden.

Was braucht man

Snort basiert auf libpcap, der Paket Capturing Libary. Diese erhaelt man bei www.tcpdump.org . Bei Verwendung von --enable-flexresp ist die Installation der libnet - Bibliothek von www.netfactory/libnet erforderlich. Letztendlich werden auch noch die Regeln benoetig. Die gibts auch bei www.snort.org (unter Rule Database). Man sollte sie nach /etc/snort.conf kopieren, da diese praktisch die "Konfiguration" von snort darstellen.

Was sollte man beachten

Diese Regeln basieren auf sog. Signaturen, die im Voraus schon bekannt sein mueszen. Somit birgt unser IDS das Risiko von falschen Alarmen. Dabei mueszen zwischen zwei Arten von Fehlermeldungen unterschieden werden:

  • false positives: Normale Netzwerkaktivitaet wird als Angriff klassifiziert

  • false negatives: Ein echter Angriff wird uebersehen

Daher werden immer noch Menschen benoetigt, die die Meldung eingehenderen Untersuchungen unterziehen. false negatives sind gefaehrlicher als als false positives, da sie dem User ein falsche Masz an Sicherheit vermitteln. Ebenso kann snort selbst zu einem DoS - Angriff benutzt werden, indem z. B. die Logdateien (und somit die HD’s) ueberquellen.

Was musz evtl. geaendert werden

In den Regeln, die man unter /etc/snort.conf installiert hat, mueszen einige Aenderungen vorgenommen werden. In der Zeile

preprozessor portscan: 10.0.0.1/8 \ 7 1 /var/log/snort/portscan.log

wird angegeben, wieviele Verbindungen (hier waeren es 7) pro Zeiteinheit (hier 1 Sekunde) auf welche Zieladressen (das gesamte 10.x.x.x Netz) als Portscan klassifiziert werden. Der Portscan wird in /var/log/snort/portscan.log aufgezeichnet und protokolliert. In der Zeile

HOME_NET 10.0.0.1/24

musz das lokale, als vertrauenswuerdig geltende Netzwerk eingetragen werden. Viele Regeln unterscheiden naemlich zwischen Maschinen innerhalb und auszerhalb des HOME_NET. Hier ist die 10.0.0.x. Ein einzelner Host 10.0.0.1 waere folgllich 10.0.0.1/32. In der Zeile

preprozessor portscan-ignorehosts: 10.0.0.1/30

kann eingetragen werden, von welchen Hosts Portscans ignoriert werden sollen. Dort koennte man z. B. dieselben Einstellungen wie fuer HOME_NET verwenden.

Wie kann man snort starten

Es empfiehlt sich, snort ueber ein Startscript (z.B. /sbin/init.d/snort) beim Wechsel eines Runlevels mit Netzwerkunterstuetzung zu aktivieren. Ich starte snort aus /sbin/init.d/snort mit den Parametern

$ snort -u snort -q snort -D -d -b -s -c /etc/snort.conf -l /var/log/snort

Die Logdateien sind auf den ersten Blick ziemlich unuebersichtlich; aber es existieren viele Logfile-Analyser, die dem Verwalter die "Bedrohung" statistisch aufarbeiten.

Die Regeln

Das genaue Format der Regeldatei is schon unter www.snort.org/writing_snort_rules.htm beschrieben und wird hier deshalb nicht mehr aufgefuehrt. Die Regel fuer unser Beispiel sieht folgendermaszen aus:

alert icmp $HOME_NET any -> !$HOME_NET any (msg:"IDS191 - DDoS - \ Stacheldraht server-respones"; content: ,, | 6699 63 6B 65 6E | ``; itype: 0; icmp_id: 667;)

Rule Header

Jede Regel beginnt mit einem rule header; er besteht aus mehreren Feldern:

alert icmp $HOME_NET any -> !$HOME_NET any

rule action

alert

Ein Paket generiert einen Alarm und wird geloggt

log

Das Paket wird nur geloggt.

pass

Das Paket wird ignoriert.

In dem oben genannten Beispiel wird also ein Alarm erzeugt, wobei es nur um ein ICMP-Paket ging.

IP-Adressen

Die IP-Adressen werde in der Form w.x.y.z/n angegeben, wobei w.x.y.z eine IP-Adresse und /n ein CIDR-Block ist. So spezifiziert 10.0.0.0/8 das gesamte 10er Class-A Subnetz, und 10.0.0.0/24 lediglich alle Hosts von 10.0.0.1 bis 10.0.0.254. Als Operator steht der Negations-Operator ! zur Verfuegung. In diesem Beispiel geht es um Pakete, doe aus $HOME_NET kommen.

Ports

Ports koennen als einzelne Ports, Bereiche oder Negationen angegeben werden. Dabei steht das Schluesselwort nay fuer einen beliebigen Port:

  • 1 entspricht Port 1

  • 1024: Alle Ports ueber Port 1024 (einschlieszlich 1024)

  • :1024 Alle Ports unter Port 1024 (auch wieder einschlieszlich 1024)

In unserem Beispiel gehts um ICMP-Pakete. ICMP kennt gar keine Ports, also wird any benutzt.

Der Richtungsoperator

Der Richtungsoperaotr gibt an, in welche Richtung die Regeln gueltig sind:


Auf der linke Seite von befindet sich die Quelle, auf derrechten Seite das Ziel.

<>

Der bidirektionale Operator. Netzwerkverkehr in beide Richtungen wird erfaszt.

In unserem Beispiel wird die Regel aus alls ICMP-Pakete angewandt, die unser Netz verlassen.

Rule Options

Nach dem Rule Header folgen die Optionen fuer die Regel:

(msg:"IDS191 - DDoS -Stacheldraht server-response"; content: \ ,, | 6699 63 6B 65 6E | ``; itype: 0; icmp_id: 667;)

In diesem Beispiel wird eine Warnung erzeugt (msg:"IDS191 - DDoS -Stacheldraht server-response";), wenn der Inhalt des Paketes irgendwo die oben genannte Folge von Bytes enthaelt (content: \ ,, | 6699 63 6B 65 6E | ) und der ICMP-Type 0 ist (; itype: 0) und das ICMP-Echo-ID-Feld den Wert 667 hat ( icmp_id: 667;).

Praeprozessoren

In snort existieren einige Praeprozessoren, die vor den Regeln zur Anwendung kommen; es gibt da:

preprocessor minfrag: 128

Dieser Praeprozessor erkennt fragmentierte Pakete unter der hier angegebenen Fragment-Size (hier also 128). Normalerweise werden Pakete auf ihrem Weg von der Quelle zum Ziel durch Router fragmentiert. Man kann aber davon ausgehen, dasz keine Hardware Fragmente kleiner als 512 Bytes erzeugt. Also ist alles kleinere kuenstlich erzeugt worden.

preprocessor http_decode: 80 8080

Damit koennen HTTP URL’s in Klartext-ASCII umgewandelt werden.

preprocessor portscan: 192.168.1.0/24 Ports Time /var/log /portscan.log

Mehr als Ports Verbindungen waehrend des Zeitraums von Time Sekunden auf das netzwerk 192.168.1.0/24. Jetzt kommt ein Auszug aus der Log-Datei, wie snort einen "Angriff" aufzeichnet und protokolliert.

Jan 15 22:45:37 snort[11597]: spp_portscan:               PORTSCAN DECETED from xxx.xxx.xx.123
Jan 15 22:45:37 snort[11597]: SCAN-SYN FIN:        xxx.yyy.86.226:53 -> xxx.yyy.106.18:53
Jan 15 22:45:37 snort[11597]: SCNA-SYN FIN:        xxx.yyy.86.226:53 -> xxx.yyy.106.23:53
Jan 15 22:45:39 snort[11597]: SCNA-SYN FIN:        xxx.yyy.86.226:53 -> xxx.yyy.106.25:53
Jan 15 22:45:41 snort[11597]: IDS227 - Named Iquery Probe: xxx.yyy.86.226:1565 -> xxx.yyy.106.18:53
Jan 15 22:45:41 snort[11597]: IDS227 - Named Iquery Probe: xxx.yyy.86.226:1568 -> xxx.yyy.106.25:53
Jan 15 22:45:43 snort[11597]: MISC-DNS-version-query: xxx.yyy.86.226:1568 -> xxx.yyy.106.18:53
Jan 15 22:45:43 snort[11597]: MISC-DNS-version-query: xxx.yyy.86.226:1568 -> xxx.yyy.106.25:53
Jan 15 22:47:26 snort[11597]: spp_portscan: portscan status from xxx.yyy.86.226: 7 connections across 3 hosts: TCP(5), UDP(2) STEATHL
Jan 15 22:49:31 snort[11597]: spp_portscan: End of Portscan from xxx.yyy.86.225

Jetzt ne kleine Erklaerung dazu: Am Jan 15 um 22:45:37 hat xxx.yyy.86.226 den Scan begonnen; da die maximale Anzahl von Verbindungen uebertreten wurde, hat snort diese Verbindungen als Portscan charakterisiert. Der Portscan-Praeprozessor haette aber mit etwa mehr Gedul hintergangen werden koennen. nmap bietet z. B. eine "timing"- Option fuer die Geschwindigkeit eines Portscans an: nmap -Z Paranoid oder nmap -T Sneaky haette den Praeprozessor evtl. gar nicht getriggert. Aufgrund dieser Logdatei kann man annehmen, dasz der Scan mit nmap durchgefuehrt worden ist.

  • hat der Scan nur wenige Sekunden gedauert und

  • weisz ich es, weil ich ihm gesagt hab, er soll mich mit nmap scannen

Der Scan erfolgte mit SYN-FIN Paketen auf die Ports 53 von xxx.yyy.106.18 und xxx.yyy.106.23; die Regel, die dies erfaszt hat ist:

alert tcp !$HOME_NET any -> $HOME_NET any (msg:"SCAN-SYN FIN"; flags:SF;)

Danach wurde fuer beide Maschinen getestet, ob die Nameserver inverse queries unterstuetzten:

alert udp !$HOME_NET any -> $HOME_NET 53 (msg:"IDS227 - Named Iquery \ Probe"; content: ,, | 0980 0000 0001 0000 0000 |"; offset: ,,2"; depth: ,,16";)

Das weiszt darauf hin, das irgenwer versucht hat, einen BufferOverflow in BIND auszunutzen, der ihm root- Rechte beschert. Damit dieser funktioniert, musz der betreffende Server die fake-iquery Option aktiviert haben. Letztendlich wurde noch die BIND-Version abgefragt:

alert udp !$HOME_NET any -> %HOME_NET 52 (msg:"IDS278 - Named Version \ Probe"; content: ,,|07|version|04|bind|00 0010 0008|"; nocase; offset: ,,13";depth:,,32";)

Der oben genannte BufferOverflow kann nur auf BIND Nameservern mit Versionsnummern kleiner als BIND4.9.7 (Version 4) und BIND 8.1.2 (Version 8) ausgenutzt werden. Um 22:47:26 gibt snort dann einen Status ueber den portscan; es wurden 7 Verbindungn (oder Verbindungsversuche), verteilt auf 3 Rechner des Subnetztes gemacht, davon 5 TCP und 2 UDP.

BIND und Nameserver

BIND sollte (wenn ueberhaupt) immer in der aktuellsten Version installiert sein. Der Nameserver sollte nur Anfragen aus dem lokalen Netz beantworten (und natuerlich alle Anfragen, die primary und secondary Zones betreffen); deswegen sollte in der /etc/named.conf folgendes stehen:

acl ,,trusted" {    134.169.0.0/16; localhost;     };
acl ,,bogon"   {    0.0.0.0/8;    // Null address
                    1.0.0.0/0;    // IANA reserved, popular fakes
                    .0.0.0/8; 192.0.2.0/24;    // Test address
                    224.0.0.0/3;  //  Multicast addresses
                    //  The folowing Enterprise networks may or may be not be bogus.
                    10.0.0.0/8; 172.16.0.0/12; 192.168.0.0/16; };
options {    allow-query
        {    trusted;  // nur Anfragen von "trusted" hosts
        };
allow-recursion {    trusted;    // keiner darf meine Zonen haben..
                };
blackhole {    bogin;
          ;}
;

Dann kann man noch die Ausgabe von version.bind verbieten (dig @server version.bind CHAOS.txt) was (angesichsts der bereits vorhandenen Exploits) wirklich ueberlegenswert ist.

zone ,,bind" chaos {
    type master;
    file ,,master/bind";
};

und das Zonefile master/bind nich vergessen

$ORIGIN bind.
$TTL 1W
           1                ; serial
           3H            ; refresh
           1H            ; retry
           1W           ; expiry
           1D )         ; minimum

 CHAOS NS     localhost

Man koennte die Zone auch mi falschen Daten fuellen um irgendwelche Kiddies zu aergern. Das Problem dabei ist nur, dasz selbst die groeszten Scriptkiddies mal einen Glueckstreffer landen. Alternativ kann man aber auch andere Nameserver einsetzen, die wesentlich sicherer sind (tinydns http://www.djbdns.org ).

Die Parameter von snort

Hier eine Auflistung der wichtigsten Parameter:

-t /snort-chroot Man kann snort ganz aehnlich zu BIND-8.x in Verbindung mit chroot laufen lessen, um das Risiko bei einer Kompromottierung von snort minimieren zu koennen. Dazu empfiehlt es sich, snort statisch zu linken (LDFLAGS=@LDFLAGS@ -s -static im Makefile). Logischerweise macht das nur Sinn, wenn snort nicht root-Privilegien besitzt:

-u snort

um snort mit der User-ID "snort" zu starten. Da snort Daten aus dem Netzwerk verarbeitet, wollen wir logischerweise nicht, dasz es root-Privilegien hat (ein Exploit von snort koennte zu einem root-Compromise fuehren). Daher musz ein Benutzer "snort" und eine Gruppe "snort" [zu der nur der User snort gehoert) angelegt werden. Dieser User sollte sich nicht einloggen koennen und auch keine Shell zur Verfuegung haben bzw. besitzen.

-g snort

So wird snort mit der Gruppen-ID "snort" gestartet.

-D

snort im Daemon-Modus starten.

-d

Daten aus der Applikationsschicht werden ebenfalls mitprotokolliert.

-b

Schreibt protokollierte Pakete im tcpdump-Format. Wenn man ein 100MBit-Netzwerk hat, ist diese Option schon aus Performancegruenden unumgaenglich.

-s

Alarme ins syslog schreiben

-C /etc/snort.conf

Das is der Pfad zu der Konfigurations- und Regeldatei

-l /var/log/snort

Der Pfad zum Verzeichnis, indem snort seine Logdatei anlegen soll.

TCP-Flags und ihre Bedeutung

FIN

"finish" zum Verbindungsabbau

SYS

synchronize

RST

reset

PSH

push

ACK

acknowledge

URG

urgent

(2)

reserviert

(1)

reserviert

Alle rule options und ihre Bedeutung

msg

generiert einen Alarm und schreibt ins Log

logto

in eine spezielle Datei loggen anstelle der standardmaeszig angegebenen Datei

ttl

das TTL-Feld im IP-Header

id

das Fragment-ID-Feld im IP-Header

dsize

die Groesze des Paketsinhalts

content

der Inhalt eines Paketes

offset

hiermit kann man fuer die content-Option einen OFFSET angeben, ab dem der Inhalt gematched wird

depth

hiermit kann man die maximale Suchlaenge fuer die content-Option angeben. Will man bspw. in Byte 20 bis 23 nach der Zeichenfolge "foo" suchen, benutzt man content ,,foo"; offset 20; depth 3;.

nocase

hiermit kann man die content-Option unabhaengig von Grosz- und Kleinschreibung machen.

flags

die TCP-Flags

seq

die TCP-Sequence-Number

ack

Das TCP-Acknowledge Feld

itype

Der ICMP-Type

icode

Der ICMP-Code

session

Hiermit kann die applikation layer information fuer eine Sitzung mitprotokolliert werden.

icmp_id

Das ICMP-Echo Id Feld

icmp_seq

DieICMP-Echo Secuence-Number

ipoption

Die IP-Option-Felder:

  • rr: Record route

  • eol: End of list

  • nop: No op

  • ts: Time stamp

  • sec: IP security option

  • lsrr: Loose source routing

  • ssrr: Strict source routing

  • satid: Stream identifier

rpc

RPC-Dienste auf spezifische Anwendungs- oder Prozeduraufrufe ueberpruefen

resp

Hiermit kann eine aktive Antwort generiert werden (z. B. um den Verbindungsaufbau durch das Senden eines RST-Paketes zu verhindern)

asd