ПОПЕРЕДЖЕННЯ НЕ намагайтеся запустити це на виробничій машині. ПЕРЕГО НЕ ДАЙТЕ.
Попередження: Щоб спробувати будь-які "бомби", переконайтеся, що ulimit -u
вони використовуються. Прочитайте нижче [a] .
Давайте визначимо функцію отримання PID та дати (часу):
bize:~$ d(){ printf '%7s %07d %s\n' "$1" "$BASHPID" "$(date +'%H:%M:%S')"; }
Проста bomb
функція для нового користувача , яка не випускає (захистіть себе: читайте [a] ):
bize:~$ bomb() { d START; echo "yes"; sleep 1; d END; } >&2
Коли ця функція викликається виконанням, працює так:
bize:~$ bomb
START 0002786 23:07:34
yes
END 0002786 23:07:35
bize:~$
Команда date
виконується, потім друкується "так", спляча протягом 1 секунди, потім команда закриття date
і, нарешті, функція завершує друк нової командної лінії. Нічого фантазійного.
| труба
Коли ми називаємо функцію так:
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:~$
Дві команди запускаються через деякий час, дві закінчуються через 1 секунду, а потім підказка повертається.
Це причина, щоб труба |
почала два процеси паралельно.
& тло
Якщо ми змінимо виклик, додавши закінчення &
:
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
Підказка повертається негайно (всі дії надсилаються на задній план), і дві команди виконуються, як і раніше. Будь ласка, зверніть увагу на значення "номер завдання", [1]
надрукований перед PID процесу 3380
. Пізніше те саме число буде надруковано, щоб вказати, що труба закінчилася:
[1]+ Done bomb | bomb
Це ефект від &
.
У цьому причина &
: щоб швидше розпочати процеси.
Простіша назва
Ми можемо створити функцію, яку називають просто b
для виконання двох команд. Введено у три рядки:
bize:~$ b(){
> bomb | bomb
> }
І виконується як:
bize:~$ b
START 0003563 23:21:10
yes
START 0003564 23:21:10
yes
END 0003564 23:21:11
END 0003563 23:21:11
Зауважте, що ми не використовували ;
у визначенні b
(нові рядки використовувались для розділення елементів). Однак для визначення в одному рядку зазвичай використовується ;
таке:
bize:~$ b(){ bomb | bomb ; }
Більшість пробілів також не є обов'язковими, ми можемо записати еквівалент (але менш чіткий):
bize:~$ b(){ bomb|bomb;}
Ми також можемо використовувати a, &
щоб розділити }
(та відправити два процеси на задній план).
Бомба.
Якщо ми змусимо функцію відкусити її за хвіст (називаючи себе), отримаємо "вилкову бомбу":
bize:~$ b(){ b|b;} ### May look better as b(){ b | b ; } but does the same.
А щоб швидше викликати більше функцій, відправте трубу на другий план.
bize:~$ b(){ b|b&} ### Usually written as b(){ b|b& }
Якщо ми додамо перший виклик до функції після необхідного ;
і змінимо ім'я, :
ми отримаємо:
bize:~$ :(){ :|:&};:
Зазвичай пишеться як :(){ :|:& }; :
Або, написане на приємний спосіб, з якоюсь іншою назвою (сніговик):
☃(){ ☃|☃&};☃
Уліміт (який слід було встановити перед запуском цього) зробить швидке повернення досить швидко після багатьох помилок (натисніть клавішу Enter, коли список помилок припиниться, щоб отримати підказку).
Причина цього називається "вилковою бомбою" полягає в тому, що спосіб, за допомогою якого оболонка запускає під оболонку, полягає в тому, щоб розпалювати запущену оболонку, а потім викликати exec () в процес розщеплення з командою для запуску.
Труба "роздвоює" два нові процеси. Здійснення це до нескінченності спричинює бомбу.
Або кролик, як його називали спочатку, тому що він так швидко розмножується.
Час виконання:
:(){ (:) | (:) }; time :
Припинено
реальні 0м45.627с
:(){ : | :; }; time :
Припинено
реальні 0м15,283с
:(){ : | :& }; time :
реальний 0m00.002 s
все ще працює
Ваші приклади:
:(){ (:) | (:) }; :
Там, де друге закриття )
відокремлює, }
є більш складною версією :(){ :|:;};:
. Кожна команда в трубі так чи інакше викликається всередині підколі. Який ефект від ()
.
:(){ : | :& }; :
Більш швидка версія, написана без пробілів: :(){(:)|:&};:
(13 символів).
:(){ : | : }; :
### працює в zsh, але не в bash.
Має синтаксичну помилку (в bash), метахарактер потрібен перед закриттям }
,
як це:
:(){ : | :; }; :
[a]
Створіть нового чистого користувача (я зателефоную моємуbize
). Увійдіть до цього нового користувача в консоліsudo -i -u bize
або:
$ su - bize
Password:
bize:~$
Перевірте та змініть max user processes
ліміт:
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
Використання тільки 10 робіт , як це тільки один одинокий новий користувач: bize
. Це спрощує виклик killall -u bize
та позбавлення системи від більшості (не всіх) бомб. Будь ласка, не питайте, які з них ще працюють, я не розповім. Але все-таки: досить низький, але з безпечного боку, адаптуйтеся до вашої системи .
Це забезпечить, що "вилка бомба" не розвалить вашу систему .
Подальше читання:
:(){ : | :; }; :