19 смертных грехов, угрожающих безопасности программ - [10]
Пользуйтесь STL–контейнерами вместо статических массивов
Все вышеупомянутые проблемы относятся и к STL–контейнерам, например vector, но ситуация осложняется еще и тем, что не все реализации класса vector::iterator контролируют выход за границы контейнера. Указанная в заголовке мера может помочь, и автор полагает, что STL способствует быстрому написанию правильного кода, но имейте в виду, что это все же не панацея.
Пользуйтесь инструментами анализа
На рынке появляются прекрасные инструменты для анализа кода на языках C/C++ на предмет нарушения безопасности, в том числе Coverity, PREfast и Kloc–work. В разделе «Другие ресурсы» приведены ссылки. В состав Visual Studio .NET 2005 войдет программа PREfast и еще один инструмент анализа кода под названием Source code Annotation Language (SAL – язык аннотирования исходного текста), позволяющий обнаружить такие дефекты, как переполнение буфера. Проще всего проиллюстрировать SAL на примере. В показанном ниже фрагменте (примитивном) вы знаете, как соотносятся аргументы data и count: длина data составляет count байтов. Но компилятору об этом ничего не известно, он видит только типы char * and a size_t.
void *DoStuff(char *data, size_t count) {
static char buf[32];
return memcpy(buf, data, count);
}
На первый взгляд, код не содержит ничего плохого (если не считать, что мы возвращаем указатель на статический буфер, ну посмейтесь над нами). Однако если count больше 32, то возникает переполнение буфера. Если бы этот код был аннотирован с помощью SAL, то компилятор мог бы отловить эту ошибку:
void *DoStuff(__in_ecount(count) char *data, size_t count) {
static char buf[32];
return memcpy(buf, data, count);
}
Объясняется это тем, что теперь компилятор и/или PREfast знают о тесной связи аргументов data и count.
Дополнительные защитные меры
Дополнительные защитные меры – это как ремни безопасности в автомобиле. Часто они смягчают последствия столкновения, но в аварию попадать все равно не стоит. Важно понимать, что для всех основных способов минимизировать эффект от переполнения буфера условия, которые приводят к переполнению буфера, продолжают существовать, поэтому достаточно изощренная атака может обойти ваши контрмеры. Все же рассмотрим некоторые подходы.
Защита стека
Защиту стека первым применил Криспин Коуэн в своей программе Stack–guard, затем она была независимо реализована Microsoft с помощью флага компилятора /GS. В самом простом варианте суть ее состоит в том, что в стек между локальными переменными и адресом возврата записывается некое значение. В более современных реализациях для повышения эффективности может также изменяться порядок переменных. Достоинство этого подхода в том, что он легко реализуется и почти не снижает производительности, а кроме того, облегчает отладку в случае порчи стека. Другой пример – это программа ProPolice, созданная компанией IBM как расширение компилятора Gnu Compiler Collection (GCC). Любой современный продукт должен включать в себя защиту стека.
Запрет исполнения в стеке и куче
Эта контрмера существенно усложняет задачу хакера, но может сказаться на совместимости. Некоторые приложения считают допустимым компилировать и исполнять код на лету. Например, это относится к языкам Java и С#. Важно также отметить, что если противник сумеет заставить ваше приложение пасть жертвой атаки с возвратом в libc, когда для достижения неблаговидных целей выполняется вызов стандартной функции, то он сможет снять защиту со страницы памяти.
К сожалению, современная аппаратура по большей части не поддерживает эту возможность, а имеющаяся подержка зависит от процессора, операционной системы и даже ее конкретной версии. Поэтому рассчитывать на наличие такой защиты в реальных условиях не стоит, но все равно следует протестировать свою программу и убедиться, что она будет работать, когда стек и куча защищены от исполнения. Для этого нужно запустить ее на том процессоре и операционной системе, которые поддерживают аппаратную защиту. Например, если целевой платформой является Windows ХР, то прогоните тесты на машине с процессором AMD Athlon 64 FX под управлением Windows ХР SP2. В Windows эта технология называется Data Execution Protection (DEP – защита от исполнения данных), а раньше носила имя No eXecute (NX).
ОС Windows Server 2003 SP1 также поддерживает эту возможность, равно как подсистема РаХ для Linux и OpenBSD.
Другие ресурсы
□ Writing Secure Code, Second Edition by Michael Howard and David C. LeBlanc (Microsoft Press, 2002), Chapter 5, «Public Enemy #1: Buffer Overruns»
□ «Defeating the Stack Based Buffer Overflow Prevention Mechanism of Microsoft Windows Server 2003» by David Litchfield: www.ngssoftware.com/papers/ defeating–w2k3–stack–protection.pdf
□ «Non–stack Based Exploitation of Buffer Overrun Vulnerabilities on Windows NT/2000/ХР» by David Litchfield: www.ngssoftware.com/papers/non–stack–bo–windows.pdf
□ «Blind Exploitation of Stack Overflow Vulnerabilities» by Peter Winter–Smith: www.ngssoftware.com/papers/NISR.BlindExploitation.pdf
□ «Creating Arbitrary Shellcode In Unicode Expanded Strings: The \'Venetian\' Exploit» by Chris Anley: www.ngssoftware.com/papers/unicodebo.pdf
Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.