[Информационная безопасность, Системное администрирование, *nix] В bash безобидная с виду конструкция [[ $var -eq 42 ]] умеет выполнять и произвольный код (перевод)
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Знали ли вы о том, что следующий bash-скрипт способен выполнять произвольный код, который предоставит ему пользователь в ответ на запрос скрипта о вводе данных?
оригинал
#!/bin/bash
read -rp "Enter guess: " num
if [[ $num -eq 42 ]]
then
echo "Correct"
else
echo "Wrong"
fi
Вот пример:
$ ./myscript
Enter guess: 42
Correct
$ ./myscript
Enter guess: a[$(date >&2)]+42
Sun Feb 4 19:06:19 PST 2018
Correct
Это — не некая новая находка, и не уязвимость, которая появилась в bash совсем недавно. Но это — одна из тех проблем разработки bash-скриптов, о которой говорят очень и очень мало. Да и ksh ведёт себя так же, если принимать во внимание отсутствие read -p.
Оболочка выполняет вычисление выражений в арифметическом контексте в нескольких синтаксических конструкциях, в которых она ожидает увидеть целое число. Сюда входят $((here)), ((here)), ${var:here:here}, ${var[here]}, var[here]= ..; то же самое оболочка ожидает и в правой или левой части конструкции [[, используемой для сравнения чисел с применением операций -eq, -gt, -le и прочих подобных.
В этом контексте можно использовать или передавать в команду строковые литералы, вроде «1+1», которые будут обрабатываться как математические выражения. Например, команда var=«1+1»; echo $((var)) приведёт к выводу числа 2.
Но, как было показано, это — не просто система вычисления арифметических выражений, работающая в стиле «калькулятора» bc. Всё это более тесно интегрировано с оболочкой: команда a=«b»; b=«c+1»; c=41; echo $((a)) выведет 42. Тут же можно вспомнить и операции с индексами массивов. Как целые числа интерпретируются и замены команд.
Обычно эту проблему считают малозначительной или попросту игнорируют. На неё не указывают при проведении код-ревью или при анализе кода неких примеров. На неё не обращают внимания даже те, кто хорошо о ней осведомлён. Было бы довольно-таки утомительно использовать для выполнения всех операций сравнения ${var//[!0-9-]/}, да и, в любом случае, часто это не имеет отношения к нашему вопросу
И такое положение дел необязательно можно считать проявлением несправедливости, так как выполнение произвольного кода становится проблемой безопасности лишь в том случае, если оно предусматривает повышение уровня привилегий текущего пользователя. Например — когда выполняют вычисления, используя значения из файлов неизвестного происхождения, или данные, введённые пользователями, полученные от CGI-скрипта.
Исходный пример скорее представляет собой тот случай, когда можно говорить о том, что не каждый фрагмент программы, допускающий внедрение кода, может считаться брешью системы безопасности. Ведь в нашем случае того же эффекта можно добиться и гораздо проще — всего лишь выполнив команду date, а не запуская перед этим ./myscript.
А теперь сравните это всё с отношением к eval.
Там, где используется команда eval, часто тоже можно выполнять произвольный код. Но каждый случай использования этой команды, безопасного или небезопасного, можно ли его считать брешью системы безопасности или нет, вероятнее всего, вызовет множество комментариев. Это будут самые разные комментарии — от таких, авторы которых предупреждают о возможной опасности eval, до таких, авторы которых считают тех, кто пользуется eval, глупее себя.
Часто можно слышать, что «eval — это зло». Но почему-то никто никогда не говорит, что «-eq — это зло», или что «конструкция $((foo+1)) считается опасной».
Почему существуют подобные двойные стандарты?
Я взял бы на себя смелость утверждать, что команда eval считается «плохой» не (только) потому, что она небезопасна, но и потому, что её считают «примитивной» и «низкопробной». «Безопасность» — это всего лишь самая простая причина советовать использовать что-то такое, что лучше eval.
Команду eval называют «примитивной» из-за того, что её, в основном, используют новички, которые выполняют с её помощью сложные операции, не имея при этом достаточно глубокого понимания того, как работает командная оболочка. Если есть возможность в общих чертах понять то, какой именно код надо выполнить, и сгенерировать соответствующие команды, то не нужно знать о том, как, в разных ситуациях, правильно пользоваться кавычками, или о том, как происходит раскрытие выражений.
А между тем — арифметические контексты bash — это удобные и полезные инструменты, которыми часто пользуются опытные разработчики скриптов, сознательно делая выбор в их пользу.
Вот — пример скрипта. Если запустить его в виде ./myscript 1 — он выдаст Foo, а если в виде ./myscript 2 — он выдаст Bar. Вы, возможно, увидите тут шаблон именования переменных, характерный для новичков, когда после имени идёт цифра (а может, вы и сами когда-то создавали такие переменные):
#!/bin/bash
var1="Foo"
var2="Bar"
eval echo "\$var$1"
Если где-нибудь опубликовать этот пример — к нему появится куча комментариев, авторы которых будут говорить о том, что это — небезопасно, что ./myscript '1; rm -rf /' может привести к серьёзным проблемам… В итоге автора кода призовут «подумать о детях» и переписать код с использованием массивов:
#!/bin/bash
var[1]="Foo"
var[2]="Bar"
echo "${var[$1]}"
Как уже было сказано, такая конструкция не намного безопаснее eval: команда ./myscript '1+a[$(rm -rf /)]' приведёт к столь же серьёзным проблемам, что и ./myscript '1; rm -rf /'. Правда, из-за того, что тут правильно используются подходящие возможности оболочки, большинство опытных программистов сочтёт этот код вполне приемлемым.
Конечно, это не значит, что всем теперь надо широко и свободно пользоваться eval. Практически всё то, для чего применяют eval, можно сделать лучше, проще и правильнее, прибегнув к другим механизмам, и при этом ещё и получить код, который легче будет читать. Но даже если всё это выглядит не особенно убедительно для ограничения использования eval, соображения безопасности тоже никуда не деваются.
Просто стоит помнить о том, что существуют двойные стандарты.
Я, когда писал эту статью, не преследовал какой-то определённой цели. Я не могу сделать тут какого-то глубокомысленного вывода из вышесказанного. Поэтому обращаюсь к читателям. Что вы думаете обо всём этом? Может, нам стоит меньше нападать на eval и больше внимания уделять арифметическим контекстам? Может, стоит, в духе обмана детей ради их защиты, игнорировать проблему, а после того, как некто дорастёт до определённого уровня использования eval, серьёзно разговаривать с ним о внедрении кода? А может — нам всем надо просто перейти на командную оболочку fish?
оригинал
оригинал
===========
Источник:
habr.com
===========
===========
Автор оригинала: Vidar Holen
===========Похожие новости:
- [Информационная безопасность] ТОП-3 ИБ-событий недели по версии Jet CSIRT
- [Системное администрирование, Карьера в IT-индустрии, DevOps, Kubernetes] Как проходит DevOps-стажировка в Southbridge
- [Информационная безопасность, Криптография] Брайан Кребс: криптовымогатель DarkSide не шифрует ПК c русской раскладкой
- [Информационная безопасность] Обзор решения: Proget MDM
- [Информационная безопасность, Системное администрирование, Антивирусная защита, Разработка под Windows, Софт] Бэкдор в Win 10 Tweaker, или современные методы борьбы с пиратством
- Уязвимости в подсистеме eBPF, позволяющие выполнить код на уровне ядра Linux
- [Информационная безопасность, Системное администрирование, Сетевые технологии] 4. Континент 4 Getting Started. Веб-защита
- [Информационная безопасность, Программирование, IT-инфраструктура] Автоматизация как вектор роста бизнеса (перевод)
- [Системное администрирование] How to connect to FTPS or mount it to local folder
- Браузер Microsoft Edge для Linux достиг уровня бета-версии
Теги для поиска: #_informatsionnaja_bezopasnost (Информационная безопасность), #_sistemnoe_administrirovanie (Системное администрирование), #_*nix, #_linux, #_sistemnoe_administrirovanie (системное администрирование), #_ruvds_perevod (ruvds_перевод), #_blog_kompanii_ruvds.com (
Блог компании RUVDS.com
), #_informatsionnaja_bezopasnost (
Информационная безопасность
), #_sistemnoe_administrirovanie (
Системное администрирование
), #_*nix
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 12:19
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Знали ли вы о том, что следующий bash-скрипт способен выполнять произвольный код, который предоставит ему пользователь в ответ на запрос скрипта о вводе данных? оригинал #!/bin/bash
read -rp "Enter guess: " num if [[ $num -eq 42 ]] then echo "Correct" else echo "Wrong" fi Вот пример: $ ./myscript
Enter guess: 42 Correct $ ./myscript Enter guess: a[$(date >&2)]+42 Sun Feb 4 19:06:19 PST 2018 Correct Это — не некая новая находка, и не уязвимость, которая появилась в bash совсем недавно. Но это — одна из тех проблем разработки bash-скриптов, о которой говорят очень и очень мало. Да и ksh ведёт себя так же, если принимать во внимание отсутствие read -p. Оболочка выполняет вычисление выражений в арифметическом контексте в нескольких синтаксических конструкциях, в которых она ожидает увидеть целое число. Сюда входят $((here)), ((here)), ${var:here:here}, ${var[here]}, var[here]= ..; то же самое оболочка ожидает и в правой или левой части конструкции [[, используемой для сравнения чисел с применением операций -eq, -gt, -le и прочих подобных. В этом контексте можно использовать или передавать в команду строковые литералы, вроде «1+1», которые будут обрабатываться как математические выражения. Например, команда var=«1+1»; echo $((var)) приведёт к выводу числа 2. Но, как было показано, это — не просто система вычисления арифметических выражений, работающая в стиле «калькулятора» bc. Всё это более тесно интегрировано с оболочкой: команда a=«b»; b=«c+1»; c=41; echo $((a)) выведет 42. Тут же можно вспомнить и операции с индексами массивов. Как целые числа интерпретируются и замены команд. Обычно эту проблему считают малозначительной или попросту игнорируют. На неё не указывают при проведении код-ревью или при анализе кода неких примеров. На неё не обращают внимания даже те, кто хорошо о ней осведомлён. Было бы довольно-таки утомительно использовать для выполнения всех операций сравнения ${var//[!0-9-]/}, да и, в любом случае, часто это не имеет отношения к нашему вопросу И такое положение дел необязательно можно считать проявлением несправедливости, так как выполнение произвольного кода становится проблемой безопасности лишь в том случае, если оно предусматривает повышение уровня привилегий текущего пользователя. Например — когда выполняют вычисления, используя значения из файлов неизвестного происхождения, или данные, введённые пользователями, полученные от CGI-скрипта. Исходный пример скорее представляет собой тот случай, когда можно говорить о том, что не каждый фрагмент программы, допускающий внедрение кода, может считаться брешью системы безопасности. Ведь в нашем случае того же эффекта можно добиться и гораздо проще — всего лишь выполнив команду date, а не запуская перед этим ./myscript. А теперь сравните это всё с отношением к eval. Там, где используется команда eval, часто тоже можно выполнять произвольный код. Но каждый случай использования этой команды, безопасного или небезопасного, можно ли его считать брешью системы безопасности или нет, вероятнее всего, вызовет множество комментариев. Это будут самые разные комментарии — от таких, авторы которых предупреждают о возможной опасности eval, до таких, авторы которых считают тех, кто пользуется eval, глупее себя. Часто можно слышать, что «eval — это зло». Но почему-то никто никогда не говорит, что «-eq — это зло», или что «конструкция $((foo+1)) считается опасной». Почему существуют подобные двойные стандарты? Я взял бы на себя смелость утверждать, что команда eval считается «плохой» не (только) потому, что она небезопасна, но и потому, что её считают «примитивной» и «низкопробной». «Безопасность» — это всего лишь самая простая причина советовать использовать что-то такое, что лучше eval. Команду eval называют «примитивной» из-за того, что её, в основном, используют новички, которые выполняют с её помощью сложные операции, не имея при этом достаточно глубокого понимания того, как работает командная оболочка. Если есть возможность в общих чертах понять то, какой именно код надо выполнить, и сгенерировать соответствующие команды, то не нужно знать о том, как, в разных ситуациях, правильно пользоваться кавычками, или о том, как происходит раскрытие выражений. А между тем — арифметические контексты bash — это удобные и полезные инструменты, которыми часто пользуются опытные разработчики скриптов, сознательно делая выбор в их пользу. Вот — пример скрипта. Если запустить его в виде ./myscript 1 — он выдаст Foo, а если в виде ./myscript 2 — он выдаст Bar. Вы, возможно, увидите тут шаблон именования переменных, характерный для новичков, когда после имени идёт цифра (а может, вы и сами когда-то создавали такие переменные): #!/bin/bash
var1="Foo" var2="Bar" eval echo "\$var$1" Если где-нибудь опубликовать этот пример — к нему появится куча комментариев, авторы которых будут говорить о том, что это — небезопасно, что ./myscript '1; rm -rf /' может привести к серьёзным проблемам… В итоге автора кода призовут «подумать о детях» и переписать код с использованием массивов: #!/bin/bash
var[1]="Foo" var[2]="Bar" echo "${var[$1]}" Как уже было сказано, такая конструкция не намного безопаснее eval: команда ./myscript '1+a[$(rm -rf /)]' приведёт к столь же серьёзным проблемам, что и ./myscript '1; rm -rf /'. Правда, из-за того, что тут правильно используются подходящие возможности оболочки, большинство опытных программистов сочтёт этот код вполне приемлемым. Конечно, это не значит, что всем теперь надо широко и свободно пользоваться eval. Практически всё то, для чего применяют eval, можно сделать лучше, проще и правильнее, прибегнув к другим механизмам, и при этом ещё и получить код, который легче будет читать. Но даже если всё это выглядит не особенно убедительно для ограничения использования eval, соображения безопасности тоже никуда не деваются. Просто стоит помнить о том, что существуют двойные стандарты. Я, когда писал эту статью, не преследовал какой-то определённой цели. Я не могу сделать тут какого-то глубокомысленного вывода из вышесказанного. Поэтому обращаюсь к читателям. Что вы думаете обо всём этом? Может, нам стоит меньше нападать на eval и больше внимания уделять арифметическим контекстам? Может, стоит, в духе обмана детей ради их защиты, игнорировать проблему, а после того, как некто дорастёт до определённого уровня использования eval, серьёзно разговаривать с ним о внедрении кода? А может — нам всем надо просто перейти на командную оболочку fish? оригинал оригинал =========== Источник: habr.com =========== =========== Автор оригинала: Vidar Holen ===========Похожие новости:
Блог компании RUVDS.com ), #_informatsionnaja_bezopasnost ( Информационная безопасность ), #_sistemnoe_administrirovanie ( Системное администрирование ), #_*nix |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 12:19
Часовой пояс: UTC + 5