WARNUNG VERSUCHEN SIE NICHT, DIESES GERÄT AUF EINER PRODUKTIONSMASCHINE ZU LAUFEN. NUR NICHT.
Warnung: Um "Bomben" auszuprobieren, stellen Sie sicher, dass sie ulimit -u
verwendet werden. Lesen Sie unten [a] .
Definieren wir eine Funktion, um die PID und das Datum (Uhrzeit) zu ermitteln:
bize:~$ d(){ printf '%7s %07d %s\n' "$1" "$BASHPID" "$(date +'%H:%M:%S')"; }
Eine einfache, problemlose bomb
Funktion für den neuen Benutzer (schützen Sie sich: lesen Sie [a] ):
bize:~$ bomb() { d START; echo "yes"; sleep 1; d END; } >&2
Wenn diese Funktion aufgerufen wird, um ausgeführt zu werden, funktioniert das folgendermaßen:
bize:~$ bomb
START 0002786 23:07:34
yes
END 0002786 23:07:35
bize:~$
Der Befehl date
wird ausgeführt, dann wird ein "Ja" ausgegeben, eine Pause von 1 Sekunde, dann der Schließbefehl date
und schließlich die Funktion, die das Drucken einer neuen Eingabeaufforderung beendet. Nichts Besonderes.
| Rohr
Wenn wir die Funktion so aufrufen:
bize:~$ bomb | bomb
START 0003365 23:11:34
yes
START 0003366 23:11:34
yes
END 0003365 23:11:35
END 0003366 23:11:35
bize:~$
Irgendwann werden zwei Befehle gestartet, die zwei enden 1 Sekunde später und dann kehrt die Eingabeaufforderung zurück.
Das ist der Grund für die Pipe |
, zwei Prozesse parallel zu starten.
& Hintergrund
Wenn wir den Anruf ändern und eine Endung hinzufügen &
:
bize:~$ bomb | bomb &
[1] 3380
bize:~$
START 0003379 23:14:14
yes
START 0003380 23:14:14
yes
END 0003379 23:14:15
END 0003380 23:14:15
Die Eingabeaufforderung kehrt sofort zurück (alle Aktionen werden in den Hintergrund gesendet) und die beiden Befehle werden wie zuvor ausgeführt. Bitte notieren Sie sich den Wert der "Auftragsnummer" [1]
, der vor der PID des Prozesses gedruckt wurde 3380
. Später wird dieselbe Nummer gedruckt, um anzuzeigen, dass die Pipe beendet wurde:
[1]+ Done bomb | bomb
Das ist die Wirkung von &
.
Das ist der Grund von &
: um Prozesse schneller in Gang zu setzen.
Einfacherer Name
Wir können eine Funktion erstellen, die einfach aufgerufen wird b
, um die beiden Befehle auszuführen. In drei Zeilen eingegeben:
bize:~$ b(){
> bomb | bomb
> }
Und ausgeführt als:
bize:~$ b
START 0003563 23:21:10
yes
START 0003564 23:21:10
yes
END 0003564 23:21:11
END 0003563 23:21:11
Beachten Sie, dass wir ;
in der Definition von b
no verwendet haben (die Zeilenumbrüche wurden zum Trennen von Elementen verwendet). Für eine Definition in einer Zeile ist es jedoch üblich, Folgendes zu verwenden ;
:
bize:~$ b(){ bomb | bomb ; }
Die meisten Leerzeichen sind auch nicht obligatorisch, wir können das Äquivalent schreiben (aber weniger klar):
bize:~$ b(){ bomb|bomb;}
Wir können auch a verwenden &
, um das zu trennen }
(und die beiden Prozesse in den Hintergrund zu stellen).
Die Bombe.
Wenn wir die Funktion dazu bringen, ihren Schwanz zu beißen (indem wir sich selbst aufrufen), erhalten wir die "Gabelbombe":
bize:~$ b(){ b|b;} ### May look better as b(){ b | b ; } but does the same.
Und um mehr Funktionen schneller aufrufen zu können, senden Sie die Pipe in den Hintergrund.
bize:~$ b(){ b|b&} ### Usually written as b(){ b|b& }
Wenn wir den ersten Aufruf an die Funktion nach einem erforderlichen anhängen ;
und den Namen in ändern, erhalten :
wir:
bize:~$ :(){ :|:&};:
Normalerweise geschrieben als :(){ :|:& }; :
Oder, auf lustige Weise geschrieben, mit einem anderen Namen (einem Schneemann):
☃(){ ☃|☃&};☃
Das ulimit (das Sie vor dem Ausführen festlegen sollten) bewirkt, dass die Eingabeaufforderung nach vielen Fehlern recht schnell zurückkehrt (drücken Sie die Eingabetaste, wenn die Fehlerliste angehalten wird, um die Eingabeaufforderung abzurufen).
Der Grund für die Bezeichnung "Fork Bomb" ist, dass die Shell eine Sub-Shell startet, indem sie die laufende Shell gabelt und dann exec () mit dem auszuführenden Befehl für den gegabelten Prozess aufruft.
Eine Pipe "gabelt" zwei neue Prozesse. Wenn man es bis ins Unendliche macht, entsteht eine Bombe.
Oder ein Kaninchen, wie es ursprünglich genannt wurde, weil es sich so schnell fortpflanzt.
Zeitliche Koordinierung:
:(){ (:) | (:) }; time :
Abgebrochene
echte 0m45.627s
:(){ : | :; }; time :
Abgebrochene
echte 0m15.283s
:(){ : | :& }; time :
real 0m00.002 s Läuft
noch
Ihre Beispiele:
:(){ (:) | (:) }; :
Wo die zweite Schließung die )
trennt, }
ist eine komplexere Version von :(){ :|:;};:
. Jeder Befehl in einer Pipe wird sowieso in einer Sub-Shell aufgerufen. Welches ist die Wirkung der ()
.
:(){ : | :& }; :
Ist die schnellere Version, geschrieben ohne Leerzeichen: :(){(:)|:&};:
(13 Zeichen).
:(){ : | : }; :
### funktioniert in zsh aber nicht in bash.
Hat ein Syntaxfehler (in Bash), wird vor dem Schließen ein Metazeichen benötigt }
,
wie folgt :
:(){ : | :; }; :
[a]
Erstelle einen neuen sauberen Benutzer (ich rufe meinen anbize
). Melden Sie sich bei diesem neuen Benutzer in einer Konsole ansudo -i -u bize
oder:
$ su - bize
Password:
bize:~$
Überprüfen und ändern Sie das max user processes
Limit:
bize:~$ ulimit -a ### List all limits (I show only `-u`)
max user processes (-u) 63931
bize:~$ ulimit -u 10 ### Low
bize:~$ ulimit -a
max user processes (-u) 1000
Mit nur 10 Werken als nur ein einsamer neuer Benutzer: bize
. Es macht es einfacher killall -u bize
, die meisten (nicht alle) Bomben anzurufen und das System loszuwerden. Bitte fragen Sie nicht, welche noch funktionieren, ich werde nicht sagen. Aber trotzdem: Ist doch auf der sicheren Seite recht günstig, passe dich deinem System an .
Dies stellt sicher, dass eine "Gabelbombe" Ihr System nicht zum Einsturz bringt .
Weitere Lektüre:
:(){ : | :; }; :