__ __ ___ /\ \ /\ \__ /\_ \ ___ \ \ \___ __ ___ ____ \ \ ,_\ __ \//\ \ /'___\ \ \ _ `\ /'__`\ / __`\ /',__\ \ \ \/ /'__`\ \ \ \ /\ \__/ \ \ \ \ \ /\ \L\.\_ /\ \L\ \ /\__, `\ \ \ \_ /\ \L\.\_ \_\ \_ \ \____\ \ \_\ \_\ \ \__/.\_\ \ \____/ \/\____/ \ \__\ \ \__/.\_\ /\____\ \/____/ \/_/\/_/ \/__/\/_/ \/___/ \/___/ \/__/ \/__/\/_/ \/____/ 01100011 01101000 01100001 01101111 01110011 01110100 01100001 01101100 ||||[Chaos meets Tal]-[http://www.chaostal.de]|||| -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [ Advanced Snorting ] ------------------------------------------------------------------------------- Datum: 14.08.2003 ------------------------------------------------------------------------------- Autor: balle ------------------------------------------------------------------------------- Snort ist ein Network Intrusion Detection System und wurde ursprünglich von Marty Roesch entwickelt. Wie das aber bei größeren Open Source Projekten so üblich ist, wird Snort mittlerweile von einer größeren Entwicklergemeinde gepflegt und weiter entwickelt. Firmen wie Silicon Defense (SnortSnarf) oder das CERT Institut (ACID) sind wohl die besten Beispiele. Die aktuellen Sourcen gibt es unter http://www.snort.org. Dieser Artikel über Snort soll nicht erklären wie man Snort an sich configuriert. Die Configdatei selbst gibt einem schon viele Information und zu diesem Thema findet man auch genügend gute Resourcen im Netz, ein paar davon findet man in den Referenzen am Ende dieses Artikels. Der Artikel soll einem viel mehr die Tools um Snort herum näher bringen (z.B. wie man Attacken, die Snort entdeckt hat automatisch abwehren kann), was Snort kann und was nicht, einen groben Überblick über den Aufbau von Snort bieten und erklären wie man Snort durch eigene Regelwerke erweitern kann und wo man das IDS plazieren sollte oder wie man Statistiken über die Angriffe erstellen kann. Snort schaltet das Netzwerk Interface in den Promisc Modus und bedient sich der berühmten libpcap Bibliothek, um die vorbei fliegenden Packete zu sniffen. Die abgefangenen Packete werden dann einmal über Plugins disassembled (Einstellungssache) und der Payload mit einer Vielzahl von verschiedensten Rulesets verglichen. Die Rulesets bestehen aus Packetbeschreibung, wie sie bei bestimmten Angriffen auftreten. Das heisst aber nicht, daß Snort nur bekannte Angriffe auf Protokolle und Exploits erkennen kann. Snort spürt genauso "illegale" Packete auf wie z.B. ein TCP Packet mit einer TTL von 0 oder Port 0, bemerkt DOS / DDOS Attacken oder unnormalen Netzwerkverkehr (Plugin Spade). Desweiteren kann Snort über viele Plugins erweitert werden. Diese Plugins können z.B. Portscans entdecken, den Code einer Telnet Session analysieren, Unicode codierten Payload decodieren oder CGI NULL Byte Attacken aufspüren. Die Möglichkeiten sind vielfältig! Diese Plugins sorgen auch dafür, daß der Payload für Packete von und / oder zu bestimmten Ports auf einem bestimmten Layer disassembled und analysiert werden können. Diese gefundenen bösen Packete kann Snort auf die unterschiedlichsten Wege loggen und an den Mann / Admin bringen: XML, Datenbank, tcpdump Format, Snort Binary Format oder traditionell über Syslog. Das sollten erstmal genug Informationen über die Arbeitsweise von Snort sein. Wie gesagt ich werde hier nicht auf die Configuration von Snort eingehen und setze ab diesem Zeitpunkt voraus, dass Du ein mehr oder weniger gut configuriertes Snort IDS vor der Nase hast! Und als letzte Anmerkung: Der Artikel beschäftigt sich mit Snort unter Linux. Ich weiß, dass es Snort auch für Win32 Systeme gibt, aber ich habe bisher keinen besonderen Sinn darin gesehen mich damit zu beschäftigen und kann deswegen auch nicht dafür garantieren, dass die behandelten Zusatztools alle unter Windows laufen! Für Windows Benutzer gibt es aber ein schönes GUI (ids_center) für die Configuration von Snort. Wo darf ich das Schwein denn parken? =) Natürlich ist es auch entscheident in welcher Stelle des Netzwerks Snort eingebunden wird, denn es versteht sich glaube ich von selbst, dass das beste NIDS nichts bringt, wenn man sich an ihm vorbei mogeln kann. Deshalb ist es eine gute Idee das NIDS System direkt auf dem Gateway laufen zu lassen, voraus gesetzt es gibt keine weitere Verbindung zum Internet bzw. zu einem anderen unsicheren Netz. Dadurch kann man auch einige Angriffe von intern erkennen, wenn z.B. der firmeneigene Mailserver gehackt wird, um die Mails von anderen Mitarbeiter zu lesen. [Internes Netz]-->[Gateway + Snort]-->[ DMZ ]<---[Firewall]<--[Internet] Nehmen wir mal an das Netzwerk sieht folgendermaßen aus und in der DMZ stehen Webserver, die vom Internet aus durch eine weitere Firewall geschützt werden. Dann sollte die Firewall natürlich auch ein Intrusion Detection System enthalten, weil sie ja der einzige Weg in die DMZ und das dahinter liegende interne Netz ist. Die meisten kommerziellen Firewall System bieten das mittlerweile auch an. Es ist auch nicht verkehrt in der DMZ selber ein weiteres NIDS zu installieren, um Angriffe und Anormalitäten zwischen den Webservern zu erkennen oder aber IIS und Apache Webserver getrennt zu überwachen. Man kann das IDS der Firewall auch so einstellen, daß es nicht die Ports 80 und 443 überwacht und diese Arbeit dem NIDS in der DMZ überläßt, weil vom Internet zu viel Traffic kommt. Genauso kann man Snort zwischen zwei Abteilungen im internen Netz schalten, um z.B. einen Angriff eines Programmierers auf die Datenbank der Personalabteilung zu erkennen und abzuwehren, damit der nicht seinen Gehaltseintrag verbessert oder so... =) Je nachdem wo Snort so rum steht, scannt man natürlich auch andere Packete und läßt andere Sachen unkontrolliert passieren, was sich sehr positiv auf die Performance auswirken kann. Obwohl Snort ist so oder so verdammt schnell unterwegs, man bemerkt es eigentlich gar nicht, nur wenn der Traffic massiv hoch ist, kann es sich eventuell störend auswirken. Weiterführende Literatur gibt es hier [http://www.snort.org/docs/scott_c_sanchez_cissp-ids-zone-theory-diagram.pdf]. Es ist ja schön und gut, daß Snort mir sagen kann wie und wann ein Angriff auf mein Netzwerk statt gefunden hat, es kann mir allerdings nicht sagen ob der Angriff erfolgreich war oder nicht und wäre es nicht auch viel schöner wenn man den erkannten Angriff gleich verhindern könnte?? Man kann, also sollte man es auch machen! Dazu bedienen wir uns dem Perl Script Guardian (liegt dem Snort Packet bei, ansonsten gibt es eine aktuellere Version auf www.snort.org). Guardian macht nichts anderes als die Logdatei von Snort nach Attacken zu durchsuchen und die IP des Angreifers über ipchains oder IPtables zu sperren. Dabei kann man Guardian auch ein Timeout für die Sperre mitteilen und eine Ignore Liste anlegen, damit nicht die eigenen Rechner gesperrt werden oder der Nameserver, der gerne für False Alarms sorgen soll (laut Guardian Dokumentation, stimmt nicht unebdingt mit meinen Erfahrungen überein). Die Configuration von Guardian ist total simpel und wird auch in der Dokumentation sehr gut beschrieben, deswegen werde ich hier auch darauf nicht weiter eingehen. Zu erwähnen ist allerdings noch, dass man sein IDS schon gut configuriert haben sollte, also mit so wenig false alarms wie nur irgend möglich, weil man ansosnten ungewollt auch unschuldige Maschinen blockt. Guardian loggt natürlich auch wann er wen und warum gesperrt hat. Snort loggt unter Umständen viele Attacken auf dem Rechner. Diese Flut an Informationen will man natürlich auch so gut wie möglich verarbeiten. Dazu gibt es die unterschiedlichsten Programme. SnortSnarf kann über ein CGI Programm die Logdaten in HTML präsentieren und auch schon ein paar statistische Daten liefern wie z.B. eine Top 20 der Source bzw. Destination IPs mit den meisten Angriffen. Man bekommt eine Zusammenfassung aller Angriffsarten und kann sich die betroffenen IPs und sonstigen Daten schön aufbereitet anschauen. Ich habe auch selbst mal ein kleines Perl Script geschrieben, daß einfach nur hin geht und die Snort Logdatei nach neuen interessanten Einträgen durchforstet und sie an einen oder mehrere Admins per Mail schickt. Interessant heisst in diesem Zusammenhang man bekommt alle Logdaten zu geschickt, von denen das Tool nicht weiss, dass sie einen _nicht_ interessieren. Das Script findet man hier [http://www.crazydj.de/devel/snortmailer.zip]. Man kann allerdings auch die Logdaten in eine Datenbank wie z.B. MySQL oder Postgesql schreiben lassen, um sie nachher für Statistiken zu gebrauchen... Dazu muss man in der snort.conf nur das Datenbank Plugin einschalten und mit Parametern versorgen: output database: log, mysql, user=snort password=snort dbname=snort host=localhost detail=full encoding=ascii Dieser Eintrag würde die Logs in eine MySQL schreiben. Die Packetinformationen sollen detailliert also auch mit dem enthaltenen Payload in ASCII geloggt werden. Dadurch kann man vielleicht selbst noch ein paar neue Angriffstechnicken erlernen, während man im Hintergrund die Packete droppt... =) Die Beschreibung zu dem Datenbankschema gibt es hier [http://www.snort.org/docs/snortdb.png]. Wenn man seine Logdaten nicht in eine Datenbank schreibt, kann man das Perl Script snort_stat.pl verwenden, um Statistiken von seinen Logs zu erstellen. Das Programm zeigt einem an welche Attacken am meisten auf den Rechner / das Netzwerk nieder prasseln oder von welchem Adressraum die meisten Attacken gestartet werden. Desweiteren kann man fest stellen wie viele Attacken insgesamt auf das Netzwerk gefahren wurden und welcher der Rechner am meisten angegriffen wurden. Wenn man über logrotate seine Logfiles täglich rotiert, dann kann man auch ganz leicht heraus finden an welchen Wochentagen man am meisten angegriffen wird. Wenn man das Spade Plugin verwendet, dann kann man auch sehen zwischen welchen Rechnern die meisten merkwürdigen (unnormalen) Pakete hin und her geschickt wurden. Schreibt man seine Logdaten dagegen in eine Datenbank und hat einen Apache mit PHP Unterstützung zur Verfügung, dann kann man auch das excellente Programm ACID (Analysis Console for Incident Databases) vom CERT Institut verwenden. Mit ACID kann man sich Statistiken darüber erstellen, in welchen Stunden, an welchen Tagen bzw. Monaten / Jahren die meisten Angriffe statt gefunden haben. Natürlich auch welches die meisten Angriffe waren und von welchen Adressbereichen. Das Ergebnis kann grafisch aufbereitet werden. Man kann sich auch anzeigen lassen über welche Protokolle die meisten Attacken gefahren wurden oder was die letzten 5 Angriffe oder die Angriffe in den letzen 24 Stunden waren. Fast schon selbst verständlich kann man sich auch Select Statements zusammen klicken, um Angriffe mit bestimmten Kriterien zu suchen. Die Ergebnisse kann man sich auch per Mail zu schicken und es gibt die Möglichkeit Angriffe zu Alert Groups zusammen zu fassen. Mit letzerem hab ich aber noch nicht rum gespielt... Auf der Homepage von ACID (http://acidlab.sourceforge.net) wird auch auf ein weiteres Tool hingewiesen: logsnorter. Dieses Perl Script läuft im Hintergrund und schreibt alle über die Firewall (IPtables, ipchains, ipfwadm...) gedroppten Packete in die Snort Datenbank, damit man sich mit ACID ein noch besseres Bild über die wirklich auf den Rechner / das Netzwerk niederprasselnden Angriffe machen kann. Zum Schluss noch schnell ne kleine Warnung: Wenn Du auf Snort 1.8.6 updatest, dann musst Du unbedingt auch ACID updaten, weil sich das Datenbankschema anscheinend leicht geändert hat. Um genau zu sein "nur" die Tabelle iphdr, die alle IP Header Informationen beinhaltet. Zumindest will meine ACID Version 0.9.6b11 immer auf Spalten wie ip_src0 zu greifen und die gibt es nicht... Fazit: ACID ist genial!!! Du solltest es auf jeden Fall ausprobieren, weil wenn Du es einmal gesehen hast, dann kommst Du schon von alleine drauf, dass Du es nicht mehr missen möchtest... ;) Vor und während des CCC Easterhegg Congresses hab ich mal Snort einfach so laufen lassen, während ich meine TCP Hijacking Angriffe ausprobiert habe und ich musste zu meinem Entsetzen fest stellen, dass Snort nichts mit bekommt, wenn man sich nicht völlig blöd anstellt. Voll blöd wäre in diesem Fall ein generiertes TCP Packet mit TTL 0 oder einem bestimmten Windowsize Wert, den Snort dann als einen bestimmten Angriff eines Tools erkennt, weil dieses Tools halt die Eigenschaft hat, Packete mit genau dieser Windowsize zu generieren. Ein RST Daemon bleibt allerdings völlig unentdeckt. Ich habe auch ein wenig mit dem SPADE Plugin rum gespielt und das konnte diese Situation leider nicht verbessern, obwohl es garantiert unnnormal ist, wenn man von einem Server zuerst ein (gespooftes) RST Packet zurück bekommt und danach ein ACK oder SYN/ACK Paket. Last but not least ist der ARP Spoof Preprocessor (von Snort 1.8.3) völliger Schrott, weil er hat noch nicht einmal gepeilt, dass ich mit hunt jede Sekunde einen ARP Poisoning Attack abfeuer! Geschweige denn etwas von weniger auffallenderen Attacken mitbekommen. Sollte ich mit dieser Behauptung falsch liegen, korrigier mich bitte und sag mir wie Du den ARP Preprocessor configuriert hast! Außerdem müssen die gesammelten Log Daten immernoch von einem Admin ausgewertet werden und auf dem Easterhegg Congress hat auch jemand ein Tool vorgestellt, das aus den Paketbeschreibungen der Rulesets Pakete erstellt und diese dann Snort vor die Schnauze wirft. Bzw. ich habe fuer das P.A.T.H Projekt [http://p-a-t-h.sourceforge.net] selbst solch ein Tool geschrieben. Die enstehenden Logs kann man nicht mehr besonders sinnvoll auswerten und somit kann ein Angreifer in dieser Datenflut untergehen. Vorausgesetzt seine Pakete kommen an und werden nicht über Guardian entsorgt. Als letzes möchte ich hier noch kurz auf den CGI Scanner Whisker von RFP eingehen. Abgesehen davon, dass ich Whisker für den besten CGI Scanner halte, versucht das Tool durch verschiedene Technicken IDS Systeme zu umgehen. Die Ideen wie Hex codierte URLs oder Double-Shlashes in der URL sollten die Regelwerke eines IDS austricksen. Die Ideen fand ich recht interessant und somit hab ich Whisker mal auf Snort los gelassen. Das Ergebnis kann sich sehen lassen: Snort kann man dadurch nicht verarschen! =) Wenn man auf einen neuen Exploit gestossen ist und möchte, dass Snort diesen auch erkennen kann, dann sollte man sich ein eigenes Ruleset schreiben bzw. ein bestehendes erweitern. Es versteht sich hoffentlich von selbst, dass die neuen Rules der Snort Gemeinde zur Verfügung gestellt werden... Um ein einfaches Beispiel zu nehmen, schreiben wir uns jetzt mal eine Paketbeschreibung, die alle RST Packete mit Window size 1024 als gefährlich einstuft. Tcpdump 16:06:03.326371 syntaxerror.crazydj.de.6666 > gateway.crazydj.de.http: R 0:2(2) win 1024 [tos 0x10] Snort Rule alert tcp $EXTERNAL_NET any <> $HOME_NET any (msg:"Detected packet with window-size 1024; flags:R; classtype:misc-activity; rev:5;) Unter diese Regel fällt ein TCP Packet, dass entweder vom externen Netz ins interne Netz oder umgekehrt geschickt wird (Port any), das RST Flag (und nur das RST Flag) gesetzt hat und eine Windowsize von 1024 aufweist. Als Logmeldung wird daraufhin der msg String in die Logdatei geschrieben. Als nächstes soll das Paket nur geloggt werden, wenn es von dem Rechner syntaxerror and gateway geschickt wird, anders herum interessiert uns nicht und um die Sache noch etwas spannender zu gestalten, muss das Paket noch den Payload "CCC TCP Hijacking is not a crime" enthalten. Der Rechner Syntaxerror hat die IP 192.168.0.1 und Gateway die 192.168.0.2. Tcpdump 16:09:26.017503 syntaxerror.crazydj.de.6666 > gateway.crazydj.de.http: R 0:30(30) win 1024 [tos 0x10] * 0x0000 4510 0046 419a 0000 1906 d876 c0a8 0321 E..FA......v...! * 0x0010 c0a8 0320 1a0a 0050 0000 0000 0000 0000 .......P........ * 0x0020 5004 0400 75bb 0000 4343 4320 4869 6a61 P...u...CCC.Hija * 0x0030 636b 696e 6720 6973 206e 6f74 2061 2063 cking.is.not.a.c * 0x0040 7269 6d65 0d0a rime.. * Snort Rule alert tcp 192.168.0.1 any -> 192.168.0.2 any (msg:"Detected packet with window-size 1024; flags:R; content:"CCC Hijacking is not a crime"; classtype:misc-activity; rev:5;) Um die Packetbeschreibung so genau wie möglich zu gestalten und false alarms zu vermeiden, wollen wir das Packet jetzt nur loggen, wenn es als Destination Port 80 eingetragen hat alert tcp $EXTERNAL_NET any -> $HOME_NET 80 (msg:"Detected packet with window-size 1024; flags:R; content:"CCC Hijacking is not a crime"; classtype: misc-activity; rev:5;) Die Ausdrücke können natürlich auch über den ! Operator netgativ formpalawanert werden, also wenn das Paket nicht nach Port 80 geschickt wird. Oder aber wenn das Packet an einen Port kleiner als 1024 geschickt wird, dann sähe die Regel so aus: alert tcp $EXTERNAL_NET any -> $HOME_NET:1024 (msg:"Detected packet with window -size 1024; flags:R; content:"CCC Hijacking is not a crime"; classtype: misc-activity; rev:5;) Es gibt noch eine ganze Reihe weitere interessante Befehle wie z.B. ttl, nocase, seq, ack, dsize usw... Die offizielle Snort Dokumentation enthält eine gute Referenz dazu: http://www.snort.org/docs/writing_rules/ Ansonsten hält man seine Snort Rules am besten mit dem Programm oinkmaster auf dem neuesten Stand. Das Perl Script gibt es unter http://www.algonet.se/~nitzer/oinkmaster/ Allerdings ist oinkmaster noch auf die alte Homepage Struktur von snort.org eingeschossen, deswegen muss man ihm immer mit dem Parameter -u die neue URL http://www.snort.org/dl/signatures/snortrules.tar.gz unterschieben. Offizielle Snort Homepage http://www.snort.org Snort Mailing Listen http://www.snort.org/lists.html Snort im Usenet mailing.unix.snort The Lisa Paper http://www.snort.org/docs/lisapaper.txt Snort VS Whisker CGI Scanner http://online.securityfocus.com/infocus/1577 Virtual Honeynets http://online.securityfocus.com/infocus/1506 Snort Installation and Basic Usage http://online.securityfocus.com/infocus/1421 Identifying ICMP Hackery Tools Used In The Wild Today http://online.securityfocus.com/infocus/1183 Useful stuff Snort Cheat Sheet [https://comparite.ch/snort-cs]