Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
книги хакеры / Питер_Гудлиф_Ремесло_программиста_Практика_написания_хорошего_кода.pdf
Скачиваний:
16
Добавлен:
19.04.2024
Размер:
9.23 Mб
Скачать

 

 

 

 

hang

e

 

 

 

 

 

 

C

 

E

 

 

 

X

 

 

 

 

 

-

 

 

 

 

 

d

 

F

 

 

 

 

 

 

t

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

to

 

 

 

 

w Click

 

 

 

638m

 

 

 

 

w

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

.

 

 

 

 

 

.c

 

 

p

 

 

 

 

g

 

 

 

 

df

 

 

n

e

 

 

 

 

-xcha

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

Ответы и обсуждениеClick

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

Тщательно измеряйте рост производительности, и если он несуществе% нен, отмените изменения в коде. Лучше сохранить ясность кода, чем достичь незначительного прироста скорости и получить логику, кото% рую невозможно сопровождать.

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

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

4.В какой степени заданы требования к производительности вашей про граммы? Есть ли у вас конкретный план проверки того, что ваш код удовлетворяет этим критериям?

Если нет четкой спецификации, никто не может предъявить вам пре% тензии по поводу скорости работы программы.

Глава 12. Комплекс незащищенности

Вопросы для размышления

1. Что такое «безопасная» программа?

Безопасная программа должна противостоять попыткам неправильно% го употребления, взлома или применения для решения задач, которые не имелись в виду изготовителем. Это не просто надежная программа; надежный код отвечает спецификациям и не дает сбой при несколько повышенных требованиях. Однако надежная программа может разра% батываться без учета требований безопасности и допускать утечку важной информации при определенных исключительных условиях. Иногда лучше, чтобы при неправильном употреблении программа ава% рийно завершилась, чем давала нежелательную выдачу. Таким обра% зом, безопасная программа может аварийно завершаться!

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

Секретность

Система не предоставляет информацию тем, кто к ней не допущен. Они получат сообщение «доступ запрещен» или вообще не узнают, что такая информация существует.

Целостность

Система не позволяет неавторизованным лицам изменять данные.

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

Главаm

12. Комплекс незащищенности

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

639Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

Готовность к работе

Система работает непрерывно – даже в случае атаки. Трудно защи% титься от всех мыслимых угроз (что если кто%то отключит пита% ние?), но можно бороться с многими угрозами путем повышения степени избыточности в проекте или путем обеспечения быстрой перезагрузки после атаки.

Аутентификация

Система проверяет, что пользователи являются теми, за кого себя выдают, обычно с помощью механизма имя пользователя/пароль.

Аудит

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

2.Какие входные данные нужно проверять в безопасной программе? Ка кого типа проверка необходима?

Все входные данные нужно проверять. В их число входят параметры командной строки, переменные окружения, вводимые через графиче% ский интерфейс данные, данные веб%форм (даже если JavaScript про% веряет их на стороне клиента), URL в кодировке CGI, содержимое cookies, содержимое файлов и имена файлов.

Нужно проверять размер вводимых данных (если это не просто число% вые переменные), допустимость их формата и фактическое содержи% мое данных (вхождение чисел в допустимый диапазон, отсутствие встроенных строк запросов).

3.Как можно защищаться против атак со стороны группы доверенных пользователей?

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

Есть несколько способов борьбы с этим:

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

Потребуйте, чтобы все действительно важные операции подтвер% ждались двумя пользователями.

Заключите каждую операцию в транзакцию, которую нельзя отка% тить.

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

4.Где может произойти переполнение буфера, допускающее создание экс плойта? Какие функции особенно подвержены переполнению буфера?

 

 

 

 

hang

e

 

 

 

 

 

 

C

 

E

 

 

 

X

 

 

 

 

 

-

 

 

 

 

 

d

 

F

 

 

 

 

 

 

t

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

to

 

 

 

 

w Click

 

 

 

640m

 

 

 

 

w

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

.

 

 

 

 

 

.c

 

 

p

 

 

 

 

g

 

 

 

 

df

 

 

n

e

 

 

 

 

-xcha

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

Ответы и обсуждениеClick

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

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

Обычно эта ситуация возникает в процедурах ввода пользовательских данных, хотя это не единственное место – переполнение буфера может возникнуть в любом коде, обрабатывающем данные. Буфер может на% ходиться как на стеке (где размещаются локальные переменные функ% ции), так и в куче (пуле динамически распределяемой памяти).

5. Можно ли полностью исключить возможность переполнения буфера?

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

Вот некоторые основные приемы защиты вашего кода:

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

Если нет поддержки со стороны языка, нужно проверять на соот% ветствие диапазону все вводимые данные.

В C всегда применяйте более безопасные функции стандартной биб% лиотеки strncpy, strncat, snprintf, fgets и т. д. Не применяйте под% программы из stdio, такие как printf и scanf, – нельзя гарантиро% вать их безопасность.

Не применяйте библиотеки сторонних разработчиков, безопасность которых может вызвать сомнения.

Пишите свой код в управляемой среде выполнения (типа Java или C#). В этом случае атаки с использованием переполнения буфера становятся практически неосуществимыми – среда исполнения ав% томатически перехватывает большинство переполнений.

6. Как защитить память, используемую приложением?

Три момента, когда надо задуматься о безопасности памяти:

a.Перед использованием. Когда вы получаете какой%то объем памя% ти, в ней содержатся произвольные значения. Не пишите код, кото% рый полагается на значения, содержащиеся в неинициализирован% ной памяти. Взломщик может воспользоваться этим для атаки на ваш код. Для пущей надежности обнулите всю выделенную память,

перед тем как ее использовать.

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

Главаm

12. Комплекс незащищенности

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

641Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

w

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

b.Во время использования. Заблокируйте память с секретными дан% ными, чтобы ее нельзя было выгрузить на диск. Очевидно, что ОС должна быть защищенной; если одно приложение может прочесть память другого – пиши пропало.

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

7.Характерна ли для C и C++ принципиально более низкая защищен ность, чем для других языков?

C и C++ ответственны за большую часть незащищенных приложений и позволяют писать код, содержащий классические уязвимости. Вне всякого сомнения, с ними нужно быть настороже; даже опытные раз% работчики должны быть внимательны при написании кода на C/C++, чтобы не допускать переполнения буфера. Эти языки не очень способ% ствуют написанию защищенных программ.

Однако другие языки не избавляют вас от всех проблем защищенности – лишь от тех, что стали знаменитыми благодаря C и C++. В другом язы% ке вы, скорее всего, избежите проблем с переполнением буфера, но при этом не должно возникать ложного чувства безопасности; остается множество проблем, которых нельзя избежать в самом языке. Каким бы языком вы ни пользовались, нужно помнить о проблемах безопасно% сти – нельзя выбрать «безопасный» язык и забыть об их существовании.

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

8.Учтен ли опыт C для проектирования C++ как более защищенного языка?

В C++ появился абстрактный тип string, который сам управляет своей памятью. Это существенно помогает избежать переполнения буфера, хотя для тех, кто ищет неприятностей, сохранились обычные массивы char в стиле C. Другое полезное средство – vector, массив с управлением памятью. Однако обе эти структуры можно при желании обмануть – рассказать вам как?

C++ можно было бы считать более опасным, чем C, из%за того, что он часто держит указатели функций в куче (там хранятся таблицы вирту% альных функций). Если атакующему удастся изменить какой%нибудь из этих указателей, то он сможет передать управление своему зловред% ному коду.

Во многих отношениях C++ более защищен – или, скорее, его проще использовать защищенным образом. Однако при его разработке защи%