Спецпроекты

Безопасность Техника

В любимом хакерами языке программирования найдена зияющая «дыра»

Выявлена критическая уязвимость BatBadBut, затрагивающая стандартные библиотеки различных языков программирования, в том числе любимого хакерами Rust. Брешь позволяет злоумышленнику добиться выполнения произвольного кода при запуске Rust-программой сценария Windows в случае передачи аргументов без отдельного экранирования спецсимволов.

Критическая уязвимость в Rust

В стандартных библиотеках ряда популярных языков программирования, включая Rust, обнаружена уязвимость, которая угрожает компьютерам под управлением операционных систем семейства Windows, пишет Bleeping Computer.

В случае с Rust уязвимость, получившая название BatBadBut, отслеживается под идентификатором CVE-2024-24576 Сервис GitHub присвоил ей критический уровень опасности (10 из 10 баллов по шкале CVSS). Выявил проблему исследователь безопасности под псевдонимом RyotaK из японской ИБ-компании Flatt Security.

Брешь в стандартной библиотеке при определенных условиях позволяет злоумышленнику при помощи командной инъекции выполнить собственный код на машине с уязвимым приложением, без взаимодействия с пользователем, в том числе удаленно. Это может быть как клиентская программа, так и работающий на стороне сервера бэкенд веб-приложения.

Cвежая уязвимость BatBadBut затрагивает стандартные библиотеки некоторых языков программирования

Как отмечает RyotaK, большинство существующих приложений этой уязвимостью не затронуто, поскольку для ее эксплуатации требуется соблюдение ряда очень специфических условий. Для атакующего важно, чтобы в коде программы присутствовал вызов какой-либо команды операционной системы с аргументами, определяемыми пользователем – предпочтительно скрипта Windows с расширением bat или cmd.

В противном случае или же если разработчик потенциально проблемного приложения озаботился экранированием аргументов вызываемых команд ОС вручную, опасность оказаться жертвой этой уязвимости практически равна нулю.

Корни проблемы

Предпосылкой к возникновению уязвимости является неочевидное поведение системной функции Windows под названием CreateProcess, которая используется для порождения нового процесса на основе расположенной на диске программы. К выполнению пакетных (bat или cmd) файлов эта функция привлекает командный интерпретатор Windows (cmd.exe), поскольку иным образом ОС корпорации Microsoft подобные скрипты запускать не умеет.

Само по себе такое поведение функции проблемы не представляет, однако в стандартных библиотеках многих языков программирования часто присутствует функция-обертка над CreateProcess со встроенным механизмом экранирования специальных символов, который применяется всякий раз при ее выполнении.

Стандартная библиотека Rust представлена функциями Command::arg и Command::args, которые, согласно документации, рассчитаны на передачу процессу аргументов без обработки командным интерпретатором. Предполагается, что в таком случае проверка пользовательского ввода в качестве аргумента является безопасной.

В Windows реализация подобного механизма является более сложной задачей, чем в случае с другими программными платформами, поскольку эта ОС при порождении нового процесса с использованием CreateProcess передает ему все сопутствующие аргументы в одну строку, а это значит, что задача по ее дроблению на составляющие ложится на плечи этого процесса.

В большинстве программ для этих целей используется подход аналогичный прописанному в стандарте языка C – все аргументы при запуске приложения помещаются в массив argv, каждый элемент которого содержит аргумент командной строки, переданный процессу операционной системой. В cmd.exe же, который необходим для выполнения пакетных файлов, задействована особая логика разбиения строки аргументов, из-за чего разработчики стандартных библиотек вынуждены внедрять специальные обработчики экранирования, передаваемых bat- и cmd-файлами, – для защиты от подстановки аргумента. Именно эти алгоритмы в случае с Rust, как выяснилось, оказались несовершенными и вплоть до обновления 1.77.2 могли пропускать отдельные спецсимволы – при определенных манипуляциях с двойными кавычками – и таким образом допускать выполнение произвольного кода.

К, примеру, если внутри программы выполняется безвредный скрипт ‘/.test.bat’, который принимает один заданный пользователем аргумент, злоумышленник в его качестве может передать строку ‘”&calc.exe’, в результате чего полная команда после ее обработки функцией-оберткой поверх CreateProcess будет выглядеть как 'C:\Windows\System32\cmd.exe /c .\test.bat ""&calc.exe"', а итогом ее выполнения станет запуск калькулятора Windows.

Параметр ‘/c’ предписывает интерпретатору выполнить следующую за этим команду с последующим завершением. Знак амперсанда воспринимается им в качестве разделителя между двумя последовательно выполняемыми командами.

Какие еще языки программирования под угрозой

Помимо Rust, проблема наблюдается в стандартных библиотеках языков Erlang, Go, Java, Python, Ruby, Haskell, Node.js и PHP. Разработчики последних трех подготовили патчи, улучшающие механизм экранирования для защиты от подстановки аргумента.

Остальные проекты за исключением Java дополнили документацию сведениями о последствиях отказа от экранирования спецсимволов.

Разработчики Java устранять уязвимость не планируют, поскольку, вероятно, по умолчанию возлагают ответственность за экранирование на разработчиков.

Любимый язык хакеров

В феврале 2024 г. CNews писал о том, что власти США призвали разработчиков ПО как можно скорее отказаться от использования небезопасных языков С и С++. В качестве альтернативы предложены Python, а также Rust, который очень популярен среди хакеров.

Rust в качестве инструмента нередко выбирают авторы вредоносных программ, а в последнее время этот язык обретает все больше поклонников и среди законопослушных разработчиков ПО разной степени мастерства. Во всяком случае об этом свидетельствуют результаты опроса, проведенного сообществом Rust Foundation.

В рейтинге популярности языков программирования TIOBE по итогам января 2024 г. Rust занял 19 строчку, уступив Python, C, C++, Java, C#, JavaScript, PHP и даже Fortran.

Дмитрий Степанов

Короткая ссылка