Forum: Digitale Signalverarbeitung / DSP / Machine Learning Machinelearning/Patternrecognition-Algorithmus für Monitoring-Anwendung gesucht


von Moritz (Gast)


Lesenswert?

Hallo Forum,
derzeit bin ich ein wenig am programmieren unter Linux. Entstanden ist 
ein Monitoring-Tool, das jeden Prozessaufruf/fork/exit mit Zeitstempel 
dokumentiert. Entstehen soll ein IDS, das abnormales Verhalten erkennt. 
Geholfen hat dabei vor allem der Code von forkstat 
(http://kernel.ubuntu.com/git/cking/forkstat.git/ ). Den habe ich zum 
Teil nach Perl portiert. Das Script verbindet sich auf mit dem Kernel 
über das Netlink-Interface und erhält dort über das 
NETLINK_CONNECTOR-Protokoll sämtliche Execs/Forks/Exits/Coredumps etc. 
Jedes einzelne Event wird in einer Datenbank hinterlegt. Die 
Datenbankeinträge werden durch Informationen zu den Prozessen aus 
/proc/$pid/ angereichert. Also z.B. Name des Prozesses, Argumente, 
Workdir, User-id unter der der Prozess läuft usw.

Der nächste Schritt wäre jetzt dem reinen Monitoring ein wenig 
Intelligenz zu verleihen. Ich stell mir das so vor, dass ich ein 
sauberes System eine Woche laufen lass, oder von mir aus auch einen 
Monat und dabei eben alles mitprotokolliere. Danach füttere ich die 
erhobenen Daten in einen - nennen wir ihn jetzt einfach mal - 
Algorithmus. Der soll dann z.B. alarmieren, wenn plötzlich Prozesse 
gestartet werden, die entweder noch nie zuvor gestartet wurden (das ist 
einfach zu implementieren, ich erstelle von jedem gestarteten Prozess 
eine sha256-checksum (die ich nebenbei mit Virenchecksummen vergleich)) 
oder, wenn z.B. ein Interpreterprozess alla Python gestartet wird, dann 
sollen eben die Argumente dazu gecheckt werden (wird da gerade ein 
Standardscript aufgerufen? Oder wurde der Parameter noch nie gesehen 
zuvor?).

In meinem kindlichen Leichtsinn habe ich das erstmal ganz simpel 
angegangen und habe meine Datenbankinhalte in einen 
NaiveBayes-Algorithmus gesteckt (hier etwas Pseudocde zum 
Veranschaulichen):
1
use Algorithm::NaiveBayes;
2
# SELECT `command`, `args`, `workdir`, `event`, `userid` FROM `command_stats`
3
while( @db_result = $sth->fetchrow_arrayref() ) {
4
  $naive_bayes-> add_instance(
5
      attributes => {
6
        args    => "X".$db_result[ args ], # awkward, but needs to be done to prevent strings being interpreted as numbers
7
        workdir => $db_result[ workdir ],
8
        uid     => $db_result[ userid ],
9
        what    => $db_result[ event ],
10
      },
11
      label => $db_result[ command ] # z.B. /usr/bin/nslookup
12
}
13
14
$naive_bayes->train(); # Train the bayes-algorithm

Im nächsten Schritt hab ich dann einfach die Livedaten von einem 
laufenden System an die predict()-Funktion geschickt und hätte gehofft, 
dass mir dort mehr oder minder sinnvolle Wahrscheinlichkeiten für den 
jeweiligen Prozess präsentiert werden. Zum Testen nutze ich ein 
openSUSE, welches standardmäßig einen Alias für `ls` besitzt, sodass `ls 
-N --color=tty -T 0` ausgeführt wird. Sprich, wenn ich in meiner Konsole 
`ls` ausführe, hätte ich erwartet, dass der Bayes-Algorithmus mit hoher 
Wahrscheinlichkeit den Befehl `ls` ausgibt. Denn kein anderes Programm 
verwendet diese Argumente. Die Wahrscheinlichkeiten die ich erhalte sind 
aber eher bei 3%, teilweise sogar richtig klein mit irgendeinem 10^-54 
Wert.

Daher jetzt meine Frage, ob ihr mir da irgendwie weiterhelfen könntet, 
wie man so etwas implementiert. Gibt es geeignetere Algorithmen dafür? 
Einigermaßen schnell sollte er sein (nicht umbedingt beim Anlernen, aber 
dann beim Füttern mit Beispielwerten). Zum Bayes-Algorithmus gibt's zwei 
ganz interessante Papers:

https://www.scribd.com/document/236482283/Detecting-Intrusion-in-Data-Mining-using-Naive-Bayes-Algorithm
http://cs.fit.edu/~pkc/id/related/schultz-ieeesp01.pdf

Hoffe, das war jetzt nicht zu viel Text und schon mal Danke für alle 
Hinweise.
 Moritz


P.S. der Code ist derzeit noch sehr alpha, daher hab ich ihn bisher noch 
nirgends hoch geladen. Wenn wirklich Interesse besteht, könnt ihr euch 
per PM an mich wenden.

: Verschoben durch Admin
von Vlad T. (vlad_tepesch)


Lesenswert?

hmm - ich versteh dein Ziel in dem Code nicht ganz.

Ich interpretiere das so:
Du versuchst einen Bayes Klasifikator zu trainieren, anhand der 
Parameter, der User id und des Working direktory, auf basis einzelner 
Events das Programm herauszufinden. oder was ist 'command'?

Was imho fehlt ist eine saubere einteilung der Testdaten in Klassen, die 
du zu zu erkennen veruchst, nämlich: böse und gut. (bzw die 
böshaftigkeit, als Wahrscheinlickeit)

Der Trick beim Machine Learning ist es, möglichst gute 
Unterscheidungsmermale zu finden, die die Klassen gut trennen und einen 
geeigneten Klassifikator, der in dem vorhandenen Merkmalsraum gut 
trennen kann.

Das Problem, was ich bei dir sehe ist vor allem, du betrachtest die 
Events getrennt. Der Klassifikator sieht aber keinen Zusammenhang 
zwischen zwei zu klassifizierenden Merkmalsvektoren.
Er betrachtet an sich jeden Datensatz unabhängig und versucht 
gemeinsamkeiten zu finden. Ob ein Programm in der Regel einen Fork pro 
minute oder 1000 macht, wird er aus deinen Daten nicht lernen können.
(vielleicht hab ich aber auch deinen Code, oder Ansatz auch nicht 
verstanden)

Aussagekräftiger wird es, wenn du statistiken über das Programm erhebst 
und diese als Merkmale benutzt.

Wenn ich unter Windows einen Blick in die möglichen Spalten des Process 
Explorers von SysInternals werfe, drängen sich diese Statisticen gerade 
zu auf. ODer auch ein paar andere Kennzahlen.
An der Aussagekraft von Forkstatistiken hege ich aber große Zweifel.

Ein Tool, was zB in Kurzer Zeit (!) massenweise Dateien beschreibt 
könnte ein Verschlüsselungstrojaner sein, oder auch nur ein 
Kopierprogramm oder RCS.

: Bearbeitet durch User
von Moritz (Gast)


Lesenswert?

Hallo Vlad,
danke für deine Antowrt.

Das Problem mit der Klassifizierung ist, ich habe leider nur 
Positiv-Daten, also ich kann nur sagen, welche Prozessaufrufe einem 
normalen Verhalten entsprechen. Deswegen war meine Idee eben den 
Prozessnamen als Klasse zu verwenden und zu schauen, wie nah die 
Parameter für den Aufruf des Prozesses an den "guten" Patterns ist. Wenn 
die mit einer hohen Wahrscheinlichkeit auf den Prozess passen, dann ist 
alles i.O.
Wenn die Aufrufparameter dem Prozess nicht zugeordnet werden können, 
dann stimmt da etwas nicht.

Als Daten in der Datenbank hab ich eine Tabelle mit den Namen der 
Befehle, wann sie erstmals aufgerufen wurden und einer sha256sum, um zu 
sehen, ob die Datei binär noch gleich ist beim nächsten Aufruf.
Eine zweite Tabelle speichert dann bei jedem Event 
(Exec/Fork/Exit/Coredump/...) eine Zeile mit den Aufrufparametern. Also 
z.B. Workdir, aufrufender Benutzer, Argumente, Zeitstempel des Aufrufs, 
etc.


Den Ansatz das ganze statistisch weiter aufzuwerten kann ich mir mal 
ansehen. Denkbar wären ja z.B. die Länge die ein Prozess typischer weise 
läuft, oder evtl. auch direkt die fork-raten. Bei Befehlen die 
eigentlich nur durch Cron aufgerufen werden, sollte auch ein Muster zu 
erkennen sein, dass der Befehl immer zur Stunde X, Minute Y ausgeführt 
wird.
Das sind halt leider alles Kriterien, die ich als Mensch ganz gut 
verstehe, aber derzeit habe ich noch Verständnisprobleme, wie ich den 
Algorithmus dazu bringe, das ebenfalls richtig einzuordnen.

Ich gebe dir ebenfalls recht mit der schwierigen Unterscheidung eines 
einfachen, forkenden Kopierprozesses und einem Verschlüsselungsvirus. 
Wobei der Virus immerhin als neuer Prozess auftauchen würde, der vorher 
gar nicht in der Sammlung der "guten" Programme auftaucht.
Auch müsste es ja z.B. leicht zu erkennen sein, wenn z.B. Python 
plötzlich vom Webserver ausgeführt wird, was in den gesammelten Daten 
nie der Fall war.
Das könnte man alles händisch programmieren, aber interessant, wäre eben 
eine selbstlernende Universallösung. Ob da der Bayes-Algorithmus 
überhaupt der richtige ist, weiß ich leider auch nicht.

von Honk (Gast)


Lesenswert?

Orientiert sich die Wahrscheinlichkeit nicht am Kontext aller Prozesse 
einer ganzen Woche oder eines Monats? Da sind 3 % schon ordentlich.

Versuch gute Kluster der Daten zu bilden und klassifiziere alles 
innerhalb als gut. Der Prozess der außerhalb des Klusters läuft ist 
verdächtig.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.