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:
|
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