OS Command Injection [Command Execution]

1. Введение:

Инъекция команд ОС (также известная как shell-инъекция) - это уязвимость в веб-безопасности, позволяющая злоумышленнику выполнить произвольные команды операционной системы (ОС) на сервере, на котором запущено приложение, и, как правило, полностью скомпрометировать приложение и все его данные.

Атаки с внедрением команд возможны в основном из-за недостаточной проверки ввода.

2. Типичный уязвимый код:

import os
import sys

file = sys.argv[1]

text = os.system("cat " +  file)

3. Смягчение последствий:

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

SQL Injections [SQLi]XML External Entity Injection [XXE]

3.1. Избегайте прямого вызова команд ОС:

Основной защитой в случае инъекции команд ОС является использование встроенных функций, поскольку ими нельзя манипулировать для выполнения какой-либо вредоносной задачи. Вот пример:

Вместо того чтобы использовать os.system("mkdir " + dir_name), мы должны использовать ее альтернативу - os.mkdir(dir_name)

3.2. Экранирование аргументов команд ОС:

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

Пример экранирования команд ОС показан в PHP-функции escapeshellarg. Здесь функция добавляет одинарные кавычки вокруг строки и кавычки/эскейп всех существующих одинарных кавычек, что позволяет передавать строку непосредственно в функцию shell и рассматривать ее как единственный безопасный аргумент.

<?php

    system('ls '.escapeshellarg($dir));

?>

3.3. Параметризация с проверкой вводимых данных:

Если вызов команд os на пользовательский ввод неизбежен (хотя это почти всегда так), разработчик может использовать следующие два защитных уровня. Как уже говорилось в разделе SQLi, можно защитить свою конечную точку с помощью:

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

  2. Проверка ввода: Значения команд и соответствующих аргументов должны быть проверены. Существуют различные степени проверки для фактической команды и ее аргументов:

  • Что касается используемых команд, то они должны быть проверены на соответствие списку разрешенных команд.

  • Что касается аргументов, используемых для этих команд, то они должны быть проверены с помощью следующих опций: 1. Положительная или разрешенная проверка ввода списка: Где явно определены разрешенные аргументы. 2. Список разрешений регулярных выражений: Здесь задается список безопасных, разрешенных символов и максимальная длина строки. Убедитесь, что метасимволы, такие как:

& |  ; $ > < ` \ !

и пробелы не являются частью регулярного выражения. Например, следующее регулярное выражение допускает только строчные буквы и цифры и не содержит метасимволов. Длина также ограничена 3-10 символами: ^[a-z0-9]{3,10}$

В идеале разработчик должен использовать существующие API/библиотеки для своего языка. Например (Python): Вместо того чтобы использовать os.system() для выдачи mail используйте доступную почтовую библиотеку Python.

Если такого API не существует, разработчик должен очистить все вводимые данные от вредоносных символов. Как правило, гораздо проще определить легальные символы, чем нелегальные.

3.4. Дополнительные средства защиты:

Помимо основных средств защиты, параметризации и проверки ввода, рекомендуется также использовать все эти дополнительные средства защиты:

  • Приложения должны работать с минимальными привилегиями, необходимыми для выполнения необходимых задач.

  • По возможности создавайте изолированные учетные записи с ограниченными привилегиями, которые используются только для выполнения одной задачи.

4. Выводы:

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

Last updated