Bu bash çatal bombaları neden farklı çalışıyor ve içinde ve içindeki önemi nedir?


16

Normal bir çatal bombanın nasıl çalıştığını anlıyorum, ancak ortak bash çatal bombalarının neden & sonunda gerekli olduğunu ve bu komut dosyalarının neden farklı davrandığını gerçekten anlamıyorum:

:(){ (:) | (:) }; :

ve

:(){ : | :& }; :

Birincisi, beni giriş ekranına geri atmadan önce cpu kullanımında artışa neden oluyor. İkincisi bunun yerine sadece sistemimin donmasına neden oluyor ve beni yeniden başlatmaya zorluyor. Neden? Her ikisi de sürekli olarak yeni süreçler yaratıyor, peki sistem neden farklı davranıyor?

Her iki komut dosyası da

:(){ : | : }; :

benzer olmalarına rağmen hiçbir sorun yaratmaz. Bash manuel sayfa, bir boru hattındaki komutların zaten bir alt kabukta yürütüldüğünü belirtir, bu yüzden buna inanmaya yönlendirdim: | : zaten yeterli olmalı. İnanıyorum ve sadece yeni bir alt kabukta boru hattını çalıştırmalı, ama bu neden bu kadar değişiyor?

Düzenleme: htop kullanarak ve süreçlerin miktarını sınırlandırarak, ilk varyantın gerçek bir ağaç ağacı oluşturduğunu, ikinci varyant tüm süreçleri aynı seviyede oluşturduğunu ve son varyant herhangi bir süreç yaratmadığını görmeyi başardım hiç. Bu beni daha da karıştırıyor, ama belki bir şekilde yardımcı oluyor?


2
son varyantınızda noktalı virgül eksik olduğunu düşünüyorum::(){ : | :; }; :
adonis

Yanıtlar:


22

UYARI BUNU ÜRETİM MAKİNESİNDE ÇALIŞTIRMAYIN. SADECE YAPMAYIN. Uyarı: Herhangi bir "bomba" denemek için ulimit -ukullanımda olduğundan emin olun . Aşağıdakileri okuyun [a] .

PID ve tarih (saat) almak için bir fonksiyon tanımlayalım:

bize:~$ d(){ printf '%7s %07d %s\n' "$1" "$BASHPID" "$(date +'%H:%M:%S')"; }

bombYeni kullanıcı için basit, sorunsuz bir işlev (kendinizi koruyun: okuma [a] ):

bize:~$ bomb() { d START; echo "yes"; sleep 1; d END; } >&2

Bu işlev yürütülecek şekilde çağrıldığında şu şekilde çalışır:

bize:~$ bomb
  START 0002786 23:07:34
yes
    END 0002786 23:07:35
bize:~$

Komut dateyürütülür, sonra bir "evet" yazdırılır, 1 saniye uyku, ardından kapanma komutu dateve son olarak işlev yeni bir komut istemi yazdırmadan çıkar. Hiçbir şey fantezi.

| boru

İşlevi böyle çağırdığımızda:

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:~$

Bir seferde iki komut başlar, iki saniye 1 saniye sonra sona erer ve ardından bilgi istemi geri döner.

Borunun |iki işlemi paralel olarak başlatmasının nedeni budur .

& arka fon

Aramayı bir bitiş ekleyerek değiştirirsek &:

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

Komut istemi hemen geri döner (tüm eylem arka plana gönderilir) ve iki komut daha önce olduğu gibi yürütülür. Lütfen [1]işlemin PID'sinden önce yazdırılan "iş numarası" değerini not edin 3380. Daha sonra, borunun bittiğini belirtmek için aynı numara yazdırılacaktır:

[1]+  Done                    bomb | bomb

Etkisi budur &.

Bunun nedeni &: süreçleri daha hızlı başlatmak.

Daha basit ad

bİki komutu yürütmek için basitçe adlandırılan bir işlev oluşturabiliriz . Üç satır halinde yazılmıştır:

bize:~$ b(){
> bomb | bomb
> }

Ve şu şekilde yürütülür:

bize:~$ b
  START 0003563 23:21:10
yes
  START 0003564 23:21:10
yes
    END 0003564 23:21:11
    END 0003563 23:21:11

Unutmayın ki hayır ;tanımında b(satırsonu elemanları ayırmak için kullanıldı). Bununla birlikte, bir satırdaki bir tanım için, aşağıdaki gibi kullanılması normaldir ;:

bize:~$ b(){ bomb | bomb ; }

Boşlukların çoğu da zorunlu değildir, eşdeğerini yazabiliriz (ancak daha az net):

bize:~$ b(){ bomb|bomb;}

Ayrıca &, ayırmak için a'yı kullanabiliriz }(ve iki işlemi arka plana gönderebiliriz).

Bomba.

İşlevin kuyruğunu ısırmasını sağlarsak (kendini çağırarak), "çatal bombası" elde ederiz:

bize:~$ b(){ b|b;}       ### May look better as b(){ b | b ; } but does the same.

Daha fazla işlevi daha hızlı çağırmasını sağlamak için boruyu arka plana gönderin.

bize:~$ b(){ b|b&}       ### Usually written as b(){ b|b& }

Gerekli bir aramanın ardından işleve ilk çağrıyı eklersek ve ;adını şu şekilde değiştirirsek ::

bize:~$ :(){ :|:&};:

Genellikle şu şekilde yazılır: :(){ :|:& }; :

Veya eğlenceli bir şekilde, başka bir isimle (kar adam) yazılmış:

☃(){ ☃|☃&};☃

Ulimit (bunu çalıştırmadan önce ayarlamanız gerekir) birçok hatadan sonra istemin çok hızlı bir şekilde geri dönmesini sağlar (istemi almak için hata listesi durduğunda enter tuşuna basın).

Bunun "çatal bombası" olarak adlandırılmasının nedeni, kabuğun bir alt kabuğa başlama şeklinin, çalışan kabuğun çatallanması ve ardından çalıştırılacak komutla çatallı sürece exec () çağrılmasıdır.

Bir boru iki yeni süreci "çatacak". Sonsuza kadar yapmak bir bombaya neden olur.
Veya orjinal olarak adlandırılan bir tavşan çünkü çok hızlı çoğalır.


Zamanlama:

  1. :(){ (:) | (:) }; time :
    Sonlandırılmış
    gerçek 0m45.627s

  2. :(){ : | :; }; time :
    Sonlandırıldı
    gerçek 0m15.283s

  3. :(){ : | :& }; time :
    real 0m00.002 s
    Hala Çalışıyor


Örnekleriniz:

  1. :(){ (:) | (:) }; :

    Burada ikinci kapanışın )ayrıldığı }daha karmaşık bir versiyonudur :(){ :|:;};:. Bir borudaki her komut yine de bir alt kabuğun içinde çağrılır. Bunun etkisi ().

  2. :(){ : | :& }; :

    Boşluksuz olarak yazılan daha hızlı sürüm: :(){(:)|:&};:(13 karakter).

  3. :(){ : | : }; : ### zsh ile çalışır ancak bash ile çalışmaz.

    Bir sözdizimi hatası var (bash'da), kapanmadan önce bir metakarakter gereklidir },
    çünkü:

    :(){ : | :; }; :

[a] Yeni bir temiz kullanıcı oluşturun (benimkini arayacağımbize). Bu yeni kullanıcıya bir konsoldan giriş yapınsudo -i -u bizeveya:

$ su - bize
Password: 
bize:~$

max user processesSınırı kontrol edin ve değiştirin :

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

Yalnızca 10 yeni bir kullanıcı gibi çalışır bize. killall -u bizeSistemin çoğunu (hepsi değil) bombalardan kurtarmayı ve kurtarmayı kolaylaştırır . Lütfen hangilerinin hala çalıştığını sormayın, söylemeyeceğim. Ama yine de: Oldukça düşük ama güvenli tarafta, sisteminize uyum sağlayın .
Bu , bir "çatal bomba" nın sisteminizi çökmemesini sağlayacaktır .

Daha fazla okuma:

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.