Как работает вилочная бомба?

22
  • ПРЕДУПРЕЖДЕНИЕ НЕ ПЫТАЙТЕСЬ ЗАПУСТИТЬ ЭТО НА ПРОИЗВОДСТВЕННОМ МАШИНЕ

Читая страницу Википедии по теме, я обычно следую за тем, что происходит со следующим кодом:

:(){ :|:& };:

выдержка из описания

Следующая вилочная бомба была представлена ​​как искусство в 2002 году;56 его точное происхождение неизвестно, но оно существовало в Usenet до 2002 года. Бомба выполняется путем вставки следующих 13 символов в оболочку UNIX, например, bash или zsh . Он работает путем определения функции с именем ':', которая вызывает себя дважды, один раз на переднем плане и один раз на заднем плане.

Однако последнее не совсем понятно для меня. Я вижу определение функции:

:(){ ... }

Но что еще происходит? Кроме того, другие оболочки, такие как ksh, cshи tcshтакже постигнет та же участь, что они способны построить нечто подобное?

SLM
источник
2
Это всплывает довольно часто при обмене стека, хороший ответ здесь: stackoverflow.com/questions/991142/…
Драв Слоан
@DravSloan - Я пытался создать часть этого контента здесь, мой вопрос немного загружен таким образом 8-).
SLM
Возможно, вы захотите добавить обязательное «Ради любви к Богу, не запускайте это на производственной машине, или если вы хотите продолжать использовать машину, на которой вы ее запускаете !!» сообщение :)
Драв Слоан
1
@ MartinSchröder - вы понимаете, что именно этот вопрос заставил вас задать этот вопрос? 8-). Я спросил это в пятницу вечером, чтобы что-то пошло, а затем другой вопрос пришел через час или два после этого.
SLM
1
@ MartinSchröder - вероятно, лучше оставить их отдельно, они немного отличаются. Это требует полного подробного представления о том, как работают вилочные бомбы, а другой спрашивал о механизме, лежащем в основе вилочной бомбы. Я знаю, это может показаться странным, потому что они связаны, но они разные (IMO - очевидно). Я даже ответил на другой вопрос и попытался показать механизм под капотом, который управляет вилкой, и я не пометил его как дубликат.
SLM

Ответы:

23

Эта вилочная бомба всегда напоминает мне то, что сказал учитель по программированию ИИ на одном из первых уроков, которые я посетил: «Чтобы понять рекурсию, сначала вы должны понять рекурсию».

По сути, эта бомба - рекурсивная функция. По сути, вы создаете функцию, которая вызывает себя, которая вызывает себя, которая вызывает себя .... до тех пор, пока системные ресурсы не будут израсходованы. В этом конкретном случае рекурсия усиливается за счет использования функции для ее передачи и создания фона.

Я видел ответ на StackOverflow , и я думаю, что приведенный там пример иллюстрирует это лучше всего, просто потому, что легче сразу увидеть, что он делает (украдено по ссылке выше ...)

☃(){ ☃|☃& };☃

Определите функцию ошибки ☃() { ... }, тело которой вызывает себя (функция ошибки), передайте вывод самому себе (функция ошибки) ☃|☃и заштрихуйте результат &. Затем, после того , как функция определена, на самом деле вызов функции ошибок, ; ☃.

Я отмечаю, что, по крайней мере на моей Arch VM, необходимость в фоновом режиме процесса не является обязательным требованием иметь тот же конечный результат, чтобы использовать все доступное пространство процесса и сделать хост хостом b0rked. На самом деле сейчас я сказал, что, кажется, иногда он завершает процесс запуска и после его скрининга -bash: fork: Resource temporarily unavailableостанавливается с Terminatedjournalctlпоказывает сброс ядра bash).

Чтобы ответить на ваш вопрос о csh / tcsh, ни одна из этих оболочек не поддерживает функции, вы можете использовать только псевдоним. Поэтому для этих оболочек вы должны написать сценарий оболочки, который вызывает себя рекурсивно.

zsh, похоже, постигла та же участь (с тем же кодом), не выдает дамп ядра и выдает Arch Out of memory: Kill process 216 (zsh) score 0 or sacrifice child., но все равно продолжает форк. Через некоторое время он затем заявляет Killed process 162 (systemd-logind) ...(и все еще продолжает иметь разветвление zsh).

Arch, похоже, не имеет pacmanверсии ksh, поэтому мне пришлось попробовать ее на Debian. ksh возражает :как имя функции, но использует что-то, скажем, b()вместо этого, похоже, желаемый результат.

Драв Слоан
источник
Что это за персонажи? Я знаю, что они ошибки, но как ты их сделал?
СЛМ
10
Хотя при небольшом размере шрифта это выглядит как ошибка, вы обнаружите, что это на самом деле снеговик. Это будет символ Юникода U + 2603, который можно отобразить в html, введя & # x 2603 без пробелов.
Сэмблер
2
Очевидно, под Linux довольно много приложений, связанных с Gnome, и Firefox поддерживают, Ctrl+Shift+u+<hex>где hex - это шестнадцатеричный код символа юникода, который вы хотите отобразить. Список видимых юникодов можно найти по адресу: fileformat.info/info/unicode/utf8test.htm (большинство нечетных в разделах «Прочее»). Windows должна проверить superuser.com/questions/47420/… , и я лично использую инструмент, упомянутый в ссылке, unicodeinput.exeили вырезал и вставлял через мой браузер. Вы всегда можете использовать html-последовательности в соответствии с рекомендациями sambler.
Драв Слоан
1
В вики также есть список символов юникода: en.wikipedia.org/wiki/List_of_Unicode_characters
Драв Слоан
Мне понравилась ошибка снеговика, та, которую вы используете здесь, не отображается в моей системе, 🐛 выглядит как поле с шестнадцатеричными числами в нем.
Тердон