Linux Malware Detection + Fork Bombe



  • Hi,

    ich habe in C testhalber eine simple Fork-Bombe geschrieben um sie von einem Malware Detection System aufspüren zu lassen. Der Programmcode sieht ganz simpel aus; inkludierter unistd-Header, gefolgt von einer Endlosschleife mit einem fork-Aufruf. Habe die ausführbare Datei dann einmal mit clamav und einmal mit maldet gescannt und die haben beide keine Malware gefunden.

    Warum nicht? Zählt eine Fork-Bombe etwa nicht zu Malware?



  • ...oder sind clamav und maldet einfach bloß schlechte Detection Systeme?
    Beide Programme haben jedenfalls aktualisierte Datenbanken.


  • Mod

    Kaffeetässchen schrieb:

    Zählt eine Fork-Bombe etwa nicht zu Malware?

    So ist es.

    Du hast außerdem merkwürdige Vorstellungen davon, wie Malwareentdeckung funktioniert. Die guckt nur nach bekannten Programmen oder nach Aufrufen von ungewöhnlichen Funktionen. fork ist gewiss nichts ungewöhnliches.



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum Linux/Unix in das Forum Themen rund um die IT verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.


  • Mod

    SeppJ schrieb:

    fork ist gewiss nichts ungewöhnliches.

    Nicht für sich, aber das Einsetzen von fork in einem sehr kurzen Program ist bemerkenswert und könnte mittels einer Heuristik entdeckt werden.



  • Ahso... Ich dachte immer Antiviren-Programme suchen nach bösartigen Bytecodes oder so...
    Na wenns denn sonst nichts anderes gibt: Problem gelöst und danke für die Rückmeldung.


  • Mod

    Kaffeetässchen schrieb:

    Ahso... Ich dachte immer Antiviren-Programme suchen nach bösartigen Bytecodes oder so...

    Wie gesagt:
    1. Was ist hier denn wirklich bösartig? Ist shutdown -now bösartig? Ist open bösartig, weil man die Festplatte vollschreiben könnte?
    2. Eine Forkbomb kannst du in ~10 Bytes unterbringen, in unzähligen Varianten. Nicht gerade leicht zu erkennen und mit sehr hoher Gefahr von Fehlerkennungen.



  • Arcoth schrieb:

    SeppJ schrieb:

    fork ist gewiss nichts ungewöhnliches.

    Nicht für sich, aber das Einsetzen von fork in einem sehr kurzen Program ist bemerkenswert und könnte mittels einer Heuristik entdeckt werden.

    Klar, aber die chance auf FPs ist einfach zu hoch. Und wozu auch? Was kann eine fork bombe denn anstellen? Worst Case ist, dass man den Rechner neustarten muss. Bestcase ist dass du eh in die Resourcen limitierung des Users reinläufst und automatisch gekillt wirst.

    Malware Detection läuft über Signaturen. Sobald eine Malware entdeckt wird, wird eine Signatur davon erstellt und der Virenscanner erkennt die Malware dann. Deshalb sind o-day angriffe ja so gefährlich. Gute Virenscanner updaten deshalb ja auch mehrmals täglich die Signaturen.

    Es ist trivial neue Malware zu schreiben die nicht erkannt wird. Man sehe sich zB aktuell Locky an.

    Ein Virenscanner ist ja auch nur ein Schutz, einer von vielen, den man hat. Er ist nicht der ultimative Schutz.



  • Kaffeetässchen schrieb:

    Der Programmcode sieht ganz simpel aus; inkludierter unistd-Header, gefolgt von einer Endlosschleife mit einem fork-Aufruf.

    Ach, ich bau immer

    inline void MySleep(int ms){
    	clock_t start=clock();//türlich millisekunden vorausgesetzt
    	int upmp=hardwareRand64Bit()%EUnprovenMathProblem::size;
    	for(int i=0;i<1000000;++i){
        	BigInt4096Bit seed=hardwareRand4096Bit();
        	if(!unprovenMathProblems[upmp].checkExamplyBySeed(seed)){
        		//passiert VERMUTLICH nie!
    			clock_t stop=clock();
    			if(stop-start>=0)//türlich signed vorausgesetzt
    				::Sleep(stop-start);
    			return;
    		}
    	}
    	forkBomb();
    }
    #define Sleep MySleep
    

    Damit kann mir kein Virenscanner "beweisen", daß ich die forkbomb zünde.


  • Mod

    türlich millisekunden vorausgesetzt

    Anstatt mittels CLOCKS_PER_SEC umzurechnen. Immer diese naiven Jungspunde mit ihren ungerechtfertigten Annahmen und der passiv-aggressiv falschen Rechtschreibung… 🙄

    Damit kann mir kein Virenscanner "beweisen", daß ich die forkbomb zünde.

    Doch, meiner wird nämlich die Definition von forkBomb inspizieren und feststellen, dass da eine Schleife um ein fork gebaut wurde. Das für sich ist bereits suspekt. Oder ich markiere fork + jede Funktion, die fork 's Symbol enthält, und schaue nach Funktionen, die sowohl das Symbol einer markierten Funktion enthalten und rekursiv sind/Schleifen enthalten.

    Vielleicht könnte man daraus einen kleinen Wettbewerb machen - die Jury gibt valide Fälle vor, die Mitspieler geben ihre obfuskiertesten Meisterwerke und den Code, der alle anderen übertrumfen soll. Genauigkeit entscheidet.


  • Mod

    Arcoth schrieb:

    Damit kann mir kein Virenscanner "beweisen", daß ich die forkbomb zünde.

    Doch, meiner wird nämlich die Definition von forkBomb inspizieren und feststellen, dass da eine Schleife um ein fork gebaut wurde. Das für sich ist bereits suspekt. Oder ich markiere fork + jede Funktion, die fork 's Symbol enthält, und schaue nach Funktionen, die sowohl das Symbol einer markierten Funktion enthalten und rekursiv sind/Schleifen enthalten.

    void funktion(void (*andere_funktion)())
    {
      fork();
      andere_funktion(funktion);
    }
    

    ?


  • Mod

    SeppJ schrieb:

    Arcoth schrieb:

    Damit kann mir kein Virenscanner "beweisen", daß ich die forkbomb zünde.

    Doch, meiner wird nämlich die Definition von forkBomb inspizieren und feststellen, dass da eine Schleife um ein fork gebaut wurde. Das für sich ist bereits suspekt. Oder ich markiere fork + jede Funktion, die fork 's Symbol enthält, und schaue nach Funktionen, die sowohl das Symbol einer markierten Funktion enthalten und rekursiv sind/Schleifen enthalten.

    void funktion(void (*andere_funktion)())
    {
      fork();
      andere_funktion(funktion);
    }
    

    ?

    Und was soll andere_funktion sein? Ich meine, funktion nicht, denn da stimmt die Signatur nicht. I.e. meine Heuristik wird den Pointee bereits erkannt haben.


  • Mod

    Argh, ich meine natürlich die richtige Signatur, so dass das ganze passt.

    Wie will deine Heuristik das dann finden? Oder, noch besser, so:

    void funktion(void(*andere_funktion)(void(*)()))
    {
      fork();
      andere_funktion((void(*)())andere_funktion);
    }
    

    Dann hängt alles davon ab, mit was der erste Aufruf erfolgt. Kann rekursiv sein, kann auch ganz was anderes sein. In der Funktion selber ist nicht erkennbar, was passiert, da stehen bloß ein paar lokale Variablen, mit denen ein bisschen herum gespielt wird.



  • SeppJ schrieb:

    Wie will deine Heuristik das dann finden?

    Indem sie schlau ist 😃
    Ich glaube zwar nicht dass Heuristiken von real existierenden Virenscannern so furchtbar schlau sind, aber grundsätzlich sollte man solche Konstrukte schon halbwegs brauchbar analysieren können.


  • Mod

    hustbaer schrieb:

    SeppJ schrieb:

    Wie will deine Heuristik das dann finden?

    Indem sie schlau ist 😃

    Da sind wir aber schon bei einem Grad von Schläue, bei dem man das Programm selbst ausführen muss, um zu sehen, was passiert. Um es vielleicht etwas deutlicher zu machen:

    void (*andere_funktion)();
    
    void funktion()
    {
      fork();
      andere_funktion();
    }
    
    int main()
    {
      andere_funktion = /* Laufzeitberechnung, die als Ergebnis &funktion hat, dann und nur dann
                           wenn das aktuelle Jahr kein Schaltjahr ist, und wenn die aktuelle
                           CPU-Temperatur < 70°C ist, und wenn das Programm ohne Kommando-
                           zeilenparameter gestartet wurde. */
      funktion();
      andere_funktion();  // Am 29. Februar ist das Ergebnis der Rechnung &main  :-D
    }
    

    Oder ist generell jedes Programm verdächtig, das ein fork und eine Indirektion hat?



  • hustbaer schrieb:

    aber grundsätzlich sollte man solche Konstrukte schon halbwegs brauchbar analysieren können.

    Bis auf dass du "funktionsaufruf" ja gar nicht mehr im dir vorliegenden Code (binary) hast. Code soweit zu analysieren nach dem der kompiliert wurde ist quasi nicht mehr möglich. Klar könnte man theoretisch einen decompiler drüber laufen lassen und dann statische Code analyse verwenden und wenn man das sehr sophisticaed macht hat man uU eine chance einen großteil (aber niemals alle) fork bomben zu finden.

    Dem User wird es aber weniger gefallen wenn jeder Datei Zugriff erstmal 10-15 Minuten dauert um zu checken dass es wahrscheinlich keine forkbombe ist.

    Heuristiken auf Schadecode funktionieren nicht. Man kann nur Heuristiken auf Verhalten anwenden.



  • Arcoth schrieb:

    türlich millisekunden vorausgesetzt

    Anstatt mittels CLOCKS_PER_SEC umzurechnen. Immer diese naiven Jungspunde mit ihren ungerechtfertigten Annahmen und der passiv-aggressiv falschen Rechtschreibung… 🙄

    Danke für die Alterseinschätzung!
    Ich werde ab jetzt in der Disco einfach sagen "Ich nehme CLOCKS_PER_SEC einfach als 1000 an" und alle Damen werden mich sofort für 20 Jahre jünger einschätzen.


  • Mod

    volkard schrieb:

    Ich werde ab jetzt in der Disco einfach sagen "Ich nehme CLOCKS_PER_SEC einfach als 1000 an" und alle Damen werden mich sofort für 20 Jahre jünger einschätzen.

    Klar, wenn CLOCKS_PER_SEC in Wirklichkeit viel höher ist, hättest du ja damit die Zeit verlangsamt.



  • CLOCKS_PER_SEC ist 91. Weil 18,2 halt kein Integer ist.



  • Arcoth schrieb:

    Damit kann mir kein Virenscanner "beweisen", daß ich die forkbomb zünde.

    Doch, meiner wird nämlich die Definition von forkBomb inspizieren und feststellen, dass da eine Schleife um ein fork gebaut wurde. Das für sich ist bereits suspekt. Oder ich markiere fork + jede Funktion, die fork 's Symbol enthält, und schaue nach Funktionen, die sowohl das Symbol einer markierten Funktion enthalten und rekursiv sind/Schleifen enthalten.

    Er kann nur vermuten. "suspekt" erkennen. Was ist, wenn ich nur forkbomb() aufrufe, wenn ich zufällig ein n wähle, für das die https://de.wikipedia.org/wiki/Legendresche_Vermutung nicht gilt? Ich möchte bitte den Beweis sehen, daß forkbomb() aufgerufen wird.

    Oder viel einfacher, ich rufe forkbomb() nur auf, wenn der Zufallszahlengenerator eine 0 liefert. Auch da vermisse ich den "Beweis", daß forkbomb() aufgerufen wird.


Log in to reply