Как предотвратить уязвимость выполнения произвольного кода в наших программах? - PullRequest
3 голосов
/ 02 апреля 2010

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

Поскольку вы читаете это так часто, это означает, что любая программа может иметь схожие уязвимости ... Что вызывает это? Как разработать наши программы для предотвращения подобных проблем?

Ответы [ 4 ]

4 голосов
/ 02 апреля 2010

Один пример того, как ошибка может создать возможность для эксплойта:

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

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

В традиционном программировании (C, C ++) символьные массивы (буферы) часто хранятся в программном стеке. Стек очень быстрый и простой в распределении памяти для небольших временных данных.

Другая вещь, которая хранится в стеке, это адрес возврата вызова функции - какой кодовый адрес возвращать при выходе из этой функции.

Теперь у вас есть все части, необходимые для создания катастрофы: если вы можете передать только правильные данные в эту подпрограмму, чтобы она перезаписывала стек, и перезаписывала его настолько, чтобы перезаписать адрес возврата функции, который также находится в стеке недалеко из буфера данных, у вас есть возможность изменить, куда вернется выполнение программы при выходе из функции. Вместо того, чтобы возвращаться к вызывающей стороне, можно было бы сделать так, чтобы она «возвращалась» (действительно, переход) в Halt () или Format () или PhoneHome (). Любая функция в любой библиотеке или DLL, на которую ссылается текущий процесс, доступна в данный момент.

Это всего лишь один из примеров произвольного выполнения эксплойта. Есть десятки таких моделей.

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

1 голос
/ 02 апреля 2010

Существует книга Руководство шеллкодера: обнаружение и использование дыр в безопасности , ISBN 978-0470080238, в которой подробно рассматриваются различные типы эксплойтов (переполнение стека, переполнение кучи, внедрение SQL и т. Д.). ).

1 голос
/ 02 апреля 2010

Первое и самое важное правило - «не доверяй никому».

  • Не доверяй описанию своих данных пользователя (количество записей, длины массивов и т. Д.).
  • Не повторяйте ничего, что клиент дает вам, не предварительно тщательно изучив его и не сделав его безвредным (исключая непечатаемые символы, проверяя соответствие границам структуры и типам и т. Д.).
  • Всегда предполагайте, что, когда вас снабжаютс информацией, она будет повреждена.Строки не будут прекращены.Массивы будут иметь разные размеры.В конструкциях будут отсутствовать кусочки.Пакеты будут слишком большими или неполными.

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

Примите это мышление полностью, и вы будете лучше подготовлены к противостоянию атакам.Но вы все равно будете совершать ошибки, как и все другие, и вам нужно реагировать на них и иметь процесс обновления для ваших клиентов.

0 голосов
/ 02 апреля 2010

Есть хорошие источники "google" для этой проблемы, но вкратце, вам нужно сделать все ваши вызовы (вызовы функций, вызовы методов и т. Д.) Безопасными. Безопасный означает, что они усекают входящие данные до нужного размера, не «оценивают» их и т. Д.

Количество возможных атак очень велико. Вы можете прочитать Bugtraq , чтобы быть в курсе событий.

Надеюсь, это поможет!

...