Apa maksud dari perintah Bash samar ini?

23

Saya sedang membaca peringatan Forum Ubuntu tentang perintah jahat dan menemukan permata yang menarik ini:

:(){ :|:& };:

PERINGATAN: Kode di atas akan menyebabkan crash mesin Anda kecuali Anda memiliki batas proc ketat (yang mungkin tidak Anda lakukan) yang memicu restart keras.

Pertimbangkan kode ini mirip dengan menjalankan sudo rm -rf /.

Tapi apa artinya itu? Bahkan dengan pengalaman pemrograman saya, saya belum pernah melihat perintah yang samar itu bukan bahasa assembly.

TheLQ
sumber
16
Poin tambahan: ini sama sekali tidak mirip sudo rm -rf /. Perintah itu menghapus semua file Anda; ini hanya menyumbat sumber daya mesin Anda sampai menjadi tidak dapat digunakan dan Anda harus memulai ulang.
jtbandes
@ jtban: Lalu edit keluar. Kedua bagian kode tersebut adalah apa yang saya anggap "berbahaya" untuk dijalankan. Ya sudo rm -rf /adalah lebih berbahaya tapi aku pernah melihat orang mengeksekusi ini pada server remote "hanya ingin melihat apa yang terjadi" di mana Anda memiliki waktu yang sulit restart tanpa akses ke panel kontrol.
Josh K
7
its an emotibomb: P
RCIX
Perhatikan itu bisa saja arbitrary_name(){ arbitrary_name|arbitrary_name& };arbitrary_name. Nama ini :tidak hanya membuat perintah ini singkat dan samar, tetapi juga mengubah :builtin yang tidak melakukan apa - apa menjadi fungsi yang tidak banyak . Jika Anda menyelinap definisi :(){ :|:& }ke lingkungan orang lain dan membiarkannya tinggal di sana, itu akan menyerang ketika korban mengharapkan itu sedikit .
Kamil Maciorowski

Jawaban:

40

Seperti yang kau katakan, forkbomb. Apa yang dilakukannya adalah mendefinisikan suatu fungsi, lalu memanggilnya. Fungsi ini disebut :.

Beri nama forkbombsehingga kita dapat melihat dengan lebih baik apa yang terjadi:

forkbomb(){ forkbomb|forkbomb& };forkbomb

Seperti yang Anda lihat, dan mungkin menebak dari pengalaman pemrograman Anda, bagian pertama adalah definisi fungsi ( forkbomb(){ ... }), dan yang terakhir :adalah di mana fungsi dipanggil ( ;just just memisahkan pernyataan dalam Bash).

Sekarang, apa fungsi ini lakukan? Jika Anda terbiasa dengan Bash, Anda akan tahu bahwa |karakter mem-pipe output standar dari satu perintah / program ke input standar yang lain. Jadi pada dasarnya, :|:mulai dua contoh fungsi (ini adalah tempat "garpu").

Dan kemudian keajaiban: &menempatkan perintah-perintah di latar belakang, memungkinkan fungsi asli untuk kembali, sementara setiap contoh garpu sampai sapi pulang di latar belakang, sehingga menghabiskan semua sumber daya Anda dan mencatat sistem (kecuali jika ada batas dikenakan padanya).

jtbandes
sumber
1
Jawaban bagus! Saya tidak menyadari Anda bisa menggunakan: sebagai nama fungsi. Ganti nama membantu. Akan menerima dalam 3 menit.
TheLQ
1
+1 Keren ... Penjelasan hebat. Ini seperti tumpukan overflow untuk OS taskswitcher. Apakah itu benar-benar crash kernel atau hanya memakan sumber daya sampai terlalu tak tertahankan untuk digunakan?
Evan Plaice
Saya tidak berpikir itu benar-benar crash kernel, setidaknya tidak secara langsung. Itu hanya terus menciptakan lebih banyak proses secara eksponensial, yang masing-masing mengambil CPU & memori, dan dengan prosesor yang mencoba menangani semuanya itu benar-benar menjadi mustahil untuk digunakan. Mungkin saja kernel akhirnya crash di bawah beban (saya tidak yakin), tetapi itu tidak dapat digunakan sebelum itu.
jtbandes
3
Jangan lupa untuk menjelaskan final :, yang sebenarnya menjalankan fungsinya!
Phoshi
@ Phoshi: pikir saya lakukan, tapi saya akan mengedit untuk mengklarifikasi!
jtbandes
9

Diambil dari artikel Wikipedia, Forkbomb :

:()      # define ':' -- whenever we say ':', do this:
{        # beginning of what to do when we say ':'
    :    # load another copy of the ':' function into memory...
    |    # ...and pipe its output to...
    :    # ...another copy of ':' function, which has to be loaded into memory
         # (therefore, ':|:' simply gets two copies of ':' loaded whenever ':' is called)
    &    # disown the functions -- if the first ':' is killed,
         #     all of the functions that it has started should NOT be auto-killed
}        # end of what to do when we say ':'
;        # Having defined ':', we should now...
:        # ...call ':', initiating a chain-reaction: each ':' will start two more.
James T
sumber
7

Rusak:

: () // Define ':' as a function. When you type ':' do the following
{
    : // Call ':' 
    | // Redirect output
    : // Into ':'
    & // Push process to the background
}; // End of ':' def
: // Now do ':'

Ubah :ke bombdan Anda memiliki:

bomb(){ bomb|bomb& };bomb

Benar-benar sangat elegan.

Josh K.
sumber