Ось команда, яку я використав для перевірки моєї башти на наявність помилки Shellshock:
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
Може хто-небудь, будь ласка, пояснити команду детально?
Ось команда, яку я використав для перевірки моєї башти на наявність помилки Shellshock:
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
Може хто-небудь, будь ласка, пояснити команду детально?
Відповіді:
Ця відповідь є похідною від оригінальної статті журналу Fedora від Matthew Miller, ліцензованої за ліцензією Creative Commons Attribution-Share Alike 4.0 .
Дозволь пояснити:
env x='() { :;}; echo OOPS' bash -c :
Це надрукує "OOPS" на вразливій системі, але вийдіть мовчки, якщо баш був зафіксований.
env x='() { :;}; echo OOPS' bash -c "echo this is a test"
Це надрукує "OOPS" на вразливій системі, але друкує, “this is a test”
якщо баш був зафіксований.
І ви, напевно, чули, що це має щось спільне із змінними середовища. Але чому код у змінних оточуючого середовища виконується? Ну, це не повинно бути, але через особливість, яку я спокусив назвати трохи надто розумною для власного блага, є дещо для дефекту. Bash - це те, що ви бачите як термінальний запит, але він також є мовою сценаріїв і має можливість визначати функції. Ви робите це так:
$ Ubuntu() { echo "Ubuntu is awesome."; }
і тоді у вас є нова команда. Майте на увазі, що echo
тут ще насправді не працює; це просто збережено, як це станеться, коли ми запустимо нову команду. Це буде важливо через хвилину!
$ Ubuntu
Ubuntu is awesome.
Корисно! Але, скажімо, чомусь нам потрібно виконати новий екземпляр bash, як підпроцес, і хотіти запустити мою приголомшливу нову команду під цим. Оператор bash -c somecommand
робить саме так: запускає задану команду в новій оболонці:
$ bash -c Ubuntu
bash: Ubuntu: command not found
О-о. Сумно. Дитина не успадкувала визначення функції. Але це притаманне середовищу - це набір пар ключових значень, які були експортовані з оболонки. (Це ціла концепція "нутіра"; якщо ви з цим не знайомі, повірте мені зараз.) І, виявляється, баш може також експортувати функції. Так:
$ export -f Ubuntu
$ bash -c Ubuntu
Ubuntu is awesome.
Що все добре і добре - за винятком того, що механізм, за допомогою якого це здійснюється, - це своєрідна хитрість . В основному, оскільки не існує магії Linux / Unix для виконання функцій у змінних середовища, функція експорту фактично просто створює звичайну змінну середовища, що містить визначення функції. Потім, коли друга оболонка читає "вхідне" середовище і зустрічає змінну із вмістом, схожим на функцію, вона оцінює її.
Теоретично це абсолютно безпечно , оскільки, пам’ятайте, визначення функції насправді не виконує її . За винятком - і саме тому ми тут - виявилася помилка в коді, де оцінка не припинялася, коли було досягнуто кінця визначення функції. Це просто змушує йти.
Це ніколи не відбудеться, коли функція, що зберігається в змінній оточення, зроблена законно, з export -f
. Але, чому бути законним? Зловмисник може просто скласти будь-яку стару змінну середовища, і якщо це буде схоже на функцію, нові оболонки bash подумають, що це так!
Отже, у нашому першому прикладі:
env x='() { :;}; echo OOPS' bash -c "echo this is a test"
env
Команда виконує команду з заданим змінним набором. У цьому випадку ми встановлюємо x
щось, що схоже на функцію. Функція - це лише одна :
, яка насправді є простою командою, яка визначається як нічого не робити. Але потім, після semi-colon
чого сигналізує про закінчення визначення функції, є echo
команда. Це не повинно бути там, але нас ніщо не заважає робити це.
Тоді команда, що надається для запуску з цим новим середовищем, - це нова оболонка bash, знову ж таки командою " echo this is a test
" або "не робити нічого :
", після чого вона вийде абсолютно нешкідливою.
Але - ой! Коли ця нова оболонка запускається і читає середовище, вона потрапляє до x
змінної, і оскільки вона схожа на функцію, вона оцінює її. Визначення функції завантажено нешкідливо - і тоді спрацьовує і наше зловмисне навантаження. Таким чином, якщо ви запускаєте вищезазначене на вразливій системі, ви надрукуєте собі “OOPS”
друк. Або зловмисник може зробити набагато гірше, ніж просто друкувати речі.
env
це не потрібно. Ви можете отримати той же результат (пройшов / не пройшов в залежності від того, чи був оновлений Bash) за допомогою команди без нього: x='() { :;}; echo OOPS' bash -c "echo this is a test"
. Це тому, що перед командою зі призначенням змінної передається ця змінна та її значення в середовище команди ( bash -c "..."
в даному випадку).
env
, визначається оболонка, з якої виконується тест, а не оболонка, що тестується. (Вони можуть бути однаковими. Навіть тоді ми перевіряємо, як баш обробляє власне середовище.) Оболонки у стилі Борна приймають NAME=value command
синтаксис; Оболонки в стилі С (наприклад csh
, tcsh
) не роблять. Тож тест є трохи більш портативним env
(ціною іноді створюють плутанину щодо того, як він працює).
У непатч-версіїbash
він зберігає експортовані визначення функцій як змінні середовища.
Збережіть функцію x
як
$ x() { bar; }
$ export -f x
І перевірте його визначення як,
$ env | grep -A1 x
x=() { bar
}
Тож можна було б скористатися цим, визначивши власні змінні середовища та інтерпретуючи їх як визначення функцій. Наприклад env x='() { :;}'
, трактуються як
x() { :;
}
env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
З man env
,
env
- запускати програму в модифікованому середовищі.
:
не робити нічого, крім виходу зі статусом виходу 0
. побачити більше
Коли новий екземпляр unpatched bash запускається як bash -c "echo this is a test"
, створена змінна середовище трактується як функція та завантажується. Відповідно, кожен отримує вихід
вразливі це перевірка
Примітка: Відлуння поза визначенням функції несподівано виконується під час запуску bash. Визначення функції - це лише крок для того, щоб отримати оцінку та скористатися експлуатуванням, саме визначення функції та використана змінна середовища є довільними. Оболонка розглядає змінні середовища, бачить х, що схоже на те, що відповідає обмеженням, які вона знає про те, як виглядає визначення функції, і вона оцінює рядок, ненавмисно виконуючи також ехо (що може бути будь-якою командою, шкідливою чи ні) . Також дивіться це
env test='() { echo "anything"; }' bash -c "echo otherthing"
ви побачите на виході otherthing
. Це виправлено в патчі. почуваюся вільним, якщо мені все ще не зрозуміло.
unpatched bash
ви можете викликати функцію так, як вона визначена, але в патчі bash
самого визначення немає.
echo vulnerable
), не виконується. Зауважте, що в останніх виправленнях передана функція повинна мати певний префікс ( env 'BASH_FUNC_x()'='() { :;}; echo vulnerable' bash -c "echo this is a test"
). Деякі новіші виправлення можуть використовуватись %%
замість першого ()
.