Rozumiem, jak działa normalna bomba z widelcem, ale tak naprawdę nie rozumiem, dlaczego wymagana jest bomba z widelcem typu bash na końcu i dlaczego te skrypty zachowują się inaczej:
:(){ (:) | (:) }; :
i
:(){ : | :& }; :
Ten pierwszy powoduje skok zużycia procesora przed wrzuceniem mnie z powrotem do ekranu logowania. Ten ostatni zamiast tego powoduje zawieszenie się mojego systemu, zmuszając mnie do twardego restartu. Dlaczego? Oba ciągle tworzą nowe procesy, więc dlaczego system zachowuje się inaczej?
Oba skrypty zachowują się inaczej
:(){ : | : }; :
co wcale nie powoduje żadnych problemów, chociaż spodziewałbym się, że będą podobne. Strona podręcznika bash mówi, że polecenia w potoku są już wykonywane w podpowłoce, więc jestem przekonany, że: | : powinno już wystarczyć. Wierzę i powinienem po prostu uruchomić potok w nowej podpowłoce, ale dlaczego to tak bardzo się zmienia?
Edycja: Używając htop i ograniczając liczbę procesów, mogłem zobaczyć, że pierwszy wariant tworzy rzeczywiste drzewo procesów, drugi wariant tworzy wszystkie procesy na tym samym poziomie, a ostatni wariant nie wydaje się tworzyć żadnych procesów w ogóle. To jeszcze bardziej mnie dezorientuje, ale może to jakoś pomaga?
źródło
:(){ : | :; }; :
Odpowiedzi:
OSTRZEŻENIE NIE PRÓBUJ URUCHOMIĆ TEGO NA MASZYNIE PRODUKCYJNEJ. TYLKO NIE. Ostrzeżenie: aby wypróbować „bomby”, upewnij się, że
ulimit -u
jest w użyciu. Przeczytaj poniżej [a] .Zdefiniujmy funkcję, aby uzyskać PID i datę (czas):
Prosta, bezproblemowa
bomb
funkcja dla nowego użytkownika (chroń się: przeczytaj [a] ):Po wywołaniu tej funkcji do wykonania działa ona tak:
Polecenie
date
jest wykonywane, następnie drukowane jest „tak”, uśpienie przez 1 sekundę, następnie polecenie zamknięciadate
, a na koniec funkcja kończy drukowanie nowego wiersza polecenia. Nic fajnego.| rura
Kiedy wywołujemy funkcję w ten sposób:
Dwa polecenia zaczynają się w pewnym momencie, dwa kończą się 1 sekundę później, a następnie monit powraca.
To jest powód, dla którego rura
|
rozpoczyna równolegle dwa procesy.& tło
Jeśli zmienimy połączenie dodając zakończenie
&
:Monit natychmiast wraca (cała akcja jest wysyłana do tła) i dwa polecenia są wykonywane jak poprzednio. Zwróć uwagę na wartość „numeru zadania”
[1]
wydrukowanego przed PID procesu3380
. Później ten sam numer zostanie wydrukowany, aby wskazać, że rura się zakończyła:Taki jest efekt
&
.Właśnie dlatego
&
: aby procesy były uruchamiane szybciej.Prostsza nazwa
Możemy stworzyć funkcję wywoływaną po prostu w
b
celu wykonania dwóch poleceń. Wpisany w trzech wierszach:I wykonywane jako:
Zauważ, że
;
w definicji nie użyliśmyb
(nowych linii użyto do oddzielenia elementów). Jednak w przypadku definicji w jednym wierszu zwykle stosuje się;
:Większość spacji również nie jest obowiązkowa, możemy napisać ekwiwalent (ale mniej wyraźny):
Możemy również użyć a,
&
aby oddzielić}
(i wysłać dwa procesy do tła).Bomba.
Jeśli sprawimy, że funkcja ugryzie się w ogon (nazywając siebie), otrzymamy „bombę widelcową”:
Aby przyspieszyć wywoływanie większej liczby funkcji, wyślij potok do tła.
Jeśli dołączymy pierwsze wywołanie do funkcji po wymaganym
;
i zmienimy nazwę:
, otrzymamy:Zwykle napisane jako
:(){ :|:& }; :
Lub, napisany w zabawny sposób, pod jakimś innym imieniem (snow-man):
Ulimit (który powinieneś ustawić przed uruchomieniem tego) spowoduje, że monit powróci dość szybko po wielu błędach (naciśnij Enter, gdy lista błędów zatrzyma się, aby otrzymać monit).
Powodem tego, że nazywany jest „bombą widełkową”, jest to, że sposób, w jaki powłoka uruchamia podpowłokę, polega na rozwidleniu działającej powłoki, a następnie wywołaniu exec () do rozwidlonego procesu za pomocą polecenia uruchomienia.
Rura „rozwidli” dwa nowe procesy. Robienie tego do nieskończoności powoduje bombę.
Lub królika, jak pierwotnie nazywano, ponieważ rozmnaża się tak szybko.
Wyczucie czasu:
:(){ (:) | (:) }; time :
Zakończone
prawdziwe 0m45.627s
:(){ : | :; }; time :
Zakończone
prawdziwe 0m15.283s
:(){ : | :& }; time :
real 0m00.002 s
Nadal działa
Twoje przykłady:
:(){ (:) | (:) }; :
Tam, gdzie
)
oddziela się drugie zamknięcie,}
jest to bardziej złożona wersja:(){ :|:;};:
. W każdym razie każde polecenie w potoku jest wywoływane wewnątrz podpowłoki. Który jest efektem()
.:(){ : | :& }; :
Jest to szybsza wersja, napisana bez spacji:
:(){(:)|:&};:
(13 znaków).:(){ : | : }; :
### działa w Zsh, ale nie w bash.Ma błąd składniowy (w bash), metaznak jest potrzebny przed zamknięciem
}
,ponieważ:
[a] Utwórz nowego czystego użytkownika (zadzwonię do mojego
bize
). Zaloguj się do tego nowego użytkownika w konsoli albosudo -i -u bize
:Sprawdź, a następnie zmień
max user processes
limit:Przy użyciu tylko 10 działa jako tylko jeden samotny nowy użytkownik:
bize
. Ułatwia dzwonieniekillall -u bize
i pozbycie się systemu większości (nie wszystkich) bomb. Proszę nie pytać, które nadal działają, nie powiem. Ale nadal: jest dość niski, ale po bezpiecznej stronie, dostosuj się do swojego systemu .Zapewni to, że „bomba widełkowa” nie zawali twojego systemu .
Dalsza lektura:
źródło