WWW.BOOK.LIB-I.RU
БЕСПЛАТНАЯ  ИНТЕРНЕТ  БИБЛИОТЕКА - Электронные ресурсы
 


Pages:     | 1 |   ...   | 2 | 3 || 5 |

«том 4 альманах програ ста Тематический сборник материалов MSDN Library и IN/ISDN' Magazine Microsoft Безопасность в.NET Шифрование Защита кода и данных Н.РШШР Е альманах программиста ...»

-- [ Страница 4 ] --

Вот строка, которая создает потенциальную угрозу:

DRIVER={SQL Server};SERVEH=hrserver;UID=sa;PWD=$esame

На самом деле в этом примере две ошибки. Первая — подключение выполняется под учетной записью администратора sa, что нарушает принцип наименьшей привилегии. Код никогда не должен подключаться к базе данных под учетной записью системного администратора, так как эта учетная запись может принести неисчислимые беды, если ею воспользуется злонамеренный пользователь. Вторая ошибка — пароль прописан в коде. Это неправильно по двум причинам: во-первых, его можно обнаружить, во-вторых, что произойдет, если пароль сменят? (Придется вносить изменения на всех клиентах.)

–  –  –

«select», «insert», «exec» и все известные мне имена таблиц и баз данных.

В этом мне помогает следующая команда:

ildasm /adv /metadata /out:file test.exe Затем я смотрю в раздел «User Strings» в результатах работы команды. Запросы к базе данных, связанные с конкатенацией строк, представляют собой потенциальную угрозу безопасности, их следует заменить на параметризованные запросы.

Конкатенация строк для создания хранимых процедур тоже не защищает от внедрения SQL-кода. Если коротко, то конкатенация строк в сочетании с SQL-выражениями опасна, но конкатенация строк в сочетании с SQLвыражениями и учетной записью sa равноценна катастрофе.

Код Web-страницы на любом языке

Самые распространенные ошибки в Web-приложениях связаны с кросссайтовыми сценариями (cross-site scripting, XSS). Хотя есть и другие ошибки, на которые я обращаю внимание, в том числе внедрение SQL-кода и нестойкое шифрование, XSS-ошибки встречаются весьма часто. Суть XSS-уязвимости — вывести данные, введенные недоверяемым пользователем, в браузере жертвы, поэтому первым делом я ищу выражения, посылающие данные пользователю. Например, в ASP я ищу Response.Write и тэги. Затем смотрю на отправляемые данные и выясняю, откуда они берутся. XSS-ошибка возникает, если данные поступили от HTTP, например из формы или строки запроса, и не были проверены на корректность.

Вот довольно простой, но распространенный пример XSS:

Hello, Х Response.WriteOtequest.QueryStringC'Name")} X Как видите, параметр «Name» отправляется пользователю без какой-либо проверки на корректность.

Секреты и шифрование на любом языке У некоторых разработчиков есть привычка хранить секретные данные в коде, например пароли или шифровальные ключи, а также изобретать собственные «волшебные» алгоритмы шифрования. Никогда так не делайте!

.

Прежде всего я ищу переменные и функции, имена которых содержат слова «key», «password», «pwd», «secret», «cipher» и «crypt». Совпадения треПолезные советы по выявлению уязеимостей в вашем коде 217 буют анализа. «Key» зачастую безобиден, но все прочие могут содержать секретные данные или «волшебные» системы шифрования. Когда я ищу алгоритмы шифрования, я анализирую операторы XOR — они часто применяются в криптографии. Худший способ шифрования — побитовая логическая операция XOR над встроенным ключом и потоком данных!

ActiveX-элементы в Visual Basic и C++ Анализируя новый ActiveX-элемент, я всегда спрашиваю: «Почему он не реализован в управляемом коде»? Я задаю этот вопрос, потому что в управляемом коде разрешены частично доверяемые сценарии, а в ActiveX — нет.

Далее я изучаю все методы и свойства элемента управления (лучший источник — IDL-файл) и ставлю себя на место злоумышленника. Что бы такого плохого я мог сделать с этими методами или свойствами? Обычно имена многих методов состоят из глагола и существительного, например ReadRegistry, WriteFile, GetUserName и NukeKey, поэтому я ищу странно звучащие глаголы и существительные, относящиеся к секретным ресурсам.





Например, метод SendFile потенциально опасен, если злоумышленник может обращаться к файлам на жестком диске пользователя и отправлять их куда-либо, например на Web-сайт, которым владеет злоумышленник. Любой код, который обращается к ресурсам на компьютере пользователя, нуждается в дополнительной проверке.

Я провожу дополнительную работу, если элемент управления помечен как «безопасный в сценариях» (safe for scripting, SFS), так как в этом случае он может быть выполнен в Web-браузере без предупреждения.

Элемент управления безопасен для использования в сценариях, если он реализует ATL-интерфейс lObjectSafetylmpl или задает при установке категории реализации «безопасен в сценариях» или «безопасен для активации»:

[HKEY_CLASSES_ROOT\CLSID\GUID\Implemented Categories\{7QD95801-9882-11CF-9FA9-OOAA006C42C4}] [HKEY_CLASSES_HOOACLSID\GUlD\Implemented Categories\{7DD95802-9882-11CF-9FA9-OOAA006C42C4}] Я уже упоминал, что доступ к файлам пользователя через SendFile плох.

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

Защита кода и данных Заключение Вы получили приблизительное представление о первом проходе в процессе оценки кода. Многие из ошибок просты, и можно возразить, что разработчики просто не должны их допускать. Но, увы, допускают. Однако знание того, что ваш код будет проанализирован на защищенность, обычно приводит к тому, что код изначально получается более защищенным.

Возможно, вы заметили, что распространенная причина многих уязвимостей — прием данных из ненадежного источника. Анализируя код, всегда проверяйте, откуда приходят данные и можно ли им доверять.

Майкл Говард (Michael Howard) — старший менеджер программы, один из основателей группы Secure Windows Initiative в Microsoft, а также соавтор книги "Writing Secure Code» (Microsoft Press, 2002). Наибольшее внимание уделяет проектированию, созданию, тестированию и развертыванию приложений, противостоящих атакам и полезных миллионам технически неподкованных пользователей.

Габриэл Торок и Билл Лич Затемнение кода Пресечение попыток обратного проектирования вашего кода Visual Basic.NET или С# Одно из преимуществ архитектуры.NET в том, что сборки, созданные с ее использованием, содержат массу полезной информации, которая может быть получена через ILDASM — дизассемблер IL-кода. Но, как побочный эффект, любой, у кого есть доступ к вашим двоичным файлам, может получить хорошее подобие оригинального исходного кода. Авторы рассказывают о затемнении программ (program obfuscation) как о способе противодействия обратному проектированию (reverse engineering). Кроме того, в статье рассматриваются разные типы существующих технологий затемнения кода и демонстрируется новый инструмент для затемнения кода, включенный в пакет Visual Studio.NET 2003.

Наверное, вы уже знакомы со всеми преимуществами архитектуры Microsoft.NET Framework, ориентированной на метаданные, — от упрощения развертывания ПО и контроля версий (versioning) до богатой функциональности IDE (integrated development environment), опирающейся на двоичные файлы со встроенными описаниями (self-describing binaries).

Возможно, вы не задумывались об этом, но легкость доступа ко всем этим метаданным породила проблему, до сих пор не беспокоившую большинство разработчиков. Программы, написанные для общеязыковой исполняющей среды (CLR), легче поддаются обратному проектированию Публиковалось в MSDN Magazine/Русская Редакция. 2003. № И (ноябрь). — Прим. изд.

220 Защита кода и данных (reverse engineering). Это не является следствием каких-то упущений в архитектуре.NET Framework — просто таковы реалии современных языков с промежуточной компиляцией (Java-приложения демонстрируют те же качества). И Java, и.NET Framework широко используют метаданные, встраиваемые в исполняемый код: байт-код (bytecode) в Java и MSIL в.NET. Находясь на гораздо более высоком уровне, чем двоичный машинный код, современные исполняемые файлы насыщены информацией, которую можно легко декодировать.

С помощью таких инструментов, как ILDASM (MSIL-дизассемблер. поставляемый с.NET Framework SDK), или декомпиляторов (decompilers) вроде Anakrino (http://www.sanrik.com/net/exemplar) и Reflector for.NET (http://www.aisto.com/roeder/dotnet) кто угодно может легко просмотреть ваши сборки и разобрать их обратно в исходный код. Эти могут воспользоваться хакеры, чтобы отыскивать бреши в защите, красть уникальные идеи или взламывать программы. По-моему, этого достаточно, чтобы призадуматься.

Но не волнуйтесь. Есть такое решение — затемнение кода (code obfuscation), — которое поможет вам пресечь обратное проектирование. Затемнение — это технология, предусматривающая переименование символов в сборках и другие трюки для запутывания декомпиляторов. При правильном применении затемнение способно усилить защиту от декомпиляции на много порядков, не нарушая работы приложения. Затемнение часто используется в Java-средах, и уже многие годы помогает компаниям сохранять интеллектуальную собственность в своих Java-продуктах.

Несколько сторонних поставщиков отреагировали на эту ситуацию, создав «затемнители» (obfuscators) для.NET-кода. Microsoft включает Dotfuscator Community Edition в Visual Studio.NET 2003 совместно с нашей компанией PreEmptive Solutions, которая поставляет разнообразные пакеты средств затемнения.

На примере Dotfuscator Community Edition мы расскажем все о затемнении (и кое-что о декомпиляции), широко доступных типах затемнения и о некоторых «подводных камнях», которых следует остерегаться, работая с затемнителями.

Чтобы продемонстрировать декомпиляцию и затемнение, мы будем использовать реализацию классической игры Vexed с открытым исходным кодом. Vexed.NET написана Руи Бин-Амоцем (Roey Ben-amotz) и доступна по ссылке http://vexeddotnet.benamotz.com. Это головоломка, где надо сдвигать одинаковые блоки друг к другу, чтобы они исчезали.

Вот простой метод из исходного кода Vexed.NET:

Пресечение попыток обратного проектирования 221 public void undo() { if (numOfMoves0) { numOfMoves--;

if (_UserNoves.Length=2) _UserHoves = _UserMoves.Substring(0, _UserMoves.Length02);

this.loadBoardCthis.moveHistory[nijinOfHinoves - (numOfHoves/50) * 50]);

this.drawBoard(this.gr);

} I Дизассемблирование.NET Framework SDK поставляется с дизассемблером ILDASM, который позволяет декомпилировать сборки.NET Framework в операторы IL-acсемблера. Для запуска ILDASM убедитесь, что.NET Framework SDK установлен, и в командной строке наберите ILDASM, указав далее имя программы, которую вы хотите дизассемблировать. В данном случае мы наберем «ILDASM vexed.net.exe». Запустится пользовательский интерфейс ILDASM, через который можно просматривать структуру любого приложения.NET Framework. На рис. 1 показан дизассемблированный метод Undo.

–  –  –

Декомпиляция Если вы сейчас думаете, что ваш исходный код сможет увидеть и понять лишь узкий круг знающих IL-ассемблер, вспомните, что декомпиляция на этом не заканчивается. С помощью декомпилятора можно воссоздать подлинный исходный код. Утилиты такого рода способны декомпилировать.NET-сборку непосредственно в исходный код на высокоуровневом языке вроде С#, Visual Basic.NET или C++.

Посмотрим на метод Undo, реконструированный декомпилятором Anakrino:

public void undo() { if {this.numOfMcves 0} { this.numOfMoves = this.numOfMoves - 1;

if (this. JJserMoves.Length = 2) this._UserMC'ves = this. JJserMoves.Substring(0, this.JJserMoves.Length - 2);

this.loadBoa.rd( this.nraveHistory[this.numOfMoves - this.nunOfHoves / 50 * 50]);

this.drawBoard(this.gr);

I Как видите, воссозданный код практически идентичен оригинальному.

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

Углубляемся в затемнение Затемнение выполняется с применением ряда смежных технологий. Его цель — скрыть характер программы, не меняя ее поведение в период выполнения. Это не шифрование, но в контексте.NET-кода это даже к лучшему. Дело в том, что вы могли бы зашифровать.NET-сборки и сделать их полностью нечитабельными. Но такой способ создает классическую дилемму: поскольку исполняющая среда способна выполнять лишь незашифрованный код, вместе с зашифрованной программой должен храниться ключ для расшифровки. А раз так, то нетрудно создать утилиту для извлечения ключа, расшифровки кода и записи IL на диск в его исходном виде. После этого программа будет абсолютно беззащитна перед декомпиляцией.

Шифрование в какой-то мере аналогично тому, как если бы вы заперли в сейфе обед из шести блюд. Ключ есть лишь у того, кому этот обед предназначен (в данном случае — у CLR), и мы не хотим, чтобы кто-то другой узнал, что будет есть владелец ключа. Увы, в обеденное время вся Пресечение попыток обратного проектирования 225 if (this.г.Length = 2) this.г = this.r.Substring(0, this.r.Length - 2);

this.a(this.q[this.p - this.p / 50 * 50]);

this.a(this.e);

i Как видите, и без других способов затемнения понять этот метод уже намного труднее.

Удаление несущественных метаданных Не все метаданные в скомпилированном.NET-приложении используются исполняющей средой. Некоторые из них предназначены для других средств, таких как дизайнеры (designers), IDE и отладчики. Например, если вы определяете свойство с именем «Size» в С#-типе, компилятор создает метаданные для имени свойства «Size» и сопоставляет это имя с методами, реализующими операции get и set (которые он назовет соответственно «get_Size»

и «set_Size»). Когда вы пишете код, устанавливающий свойство Size, компилятор генерирует вызов самого метода set_Size и никогда не ссылается на свойство по его имени. По сути имя свойства присутствует здесь для IDE и разработчиков, использующих ваш код; оно никогда не применяется CLR.

Если ваше приложение предназначено для использования только исполняющей средой, а не другими средствами, затемнитель может безопасно удалить соответствующие метаданные. Кроме имен свойств в ту же категорию попадают имена событий и параметров методов. Dotfuscator Community Edition удаляет все эти типы метаданных, когда полагает, что это безопасно.

Дополнительные технологии С помощью описанных выше технологий Dotfuscator Community Edition обеспечивает хорошее затемнение, но вы должны знать и о дополнительных технологиях, которые предоставляют еще большую защиту и способны вообще предотвратить обратное проектирование. Dotfuscator Professional Edition реализует множество дополнительных технологий, включая затемнение потока управления (control flow obfuscation), шифрование строк (string encryption), инкрементное затемнение (incremental obfuscation) и уменьшение размера (size reduction).

–  –  –

изменения логики. Что важнее, она удаляет ключи, которые ищет декомпилятор для правильного восстановления высокоуровневых операторов исходного кода, таких как if-t hen-else и циклы. Фактически эта технология нацелена на нарушение работы декомпиляторов.

Чтобы увидеть ее эффект в действии, снова взгляните на декомпилированный метод Undo — после переименования и затемнения потока управления (рис. 3). Как видите, вместо ранее существовавших вложенных операторов if, декомпилятор создал оператор if, два вложенных цикла while и несколько goto. Имеется ссылка на метку 11, но сама метка декомпилятором не создана (похоже, что это «баг» в самом декомпиляторе).

–  –  –

Шифрование строк Технология, применяющая простой алгоритм шифрования к строковым литералам (string literals), встроенным в ваше приложение. Как уже говорилось, любое шифрование (или дешифрование), проводимое в период выполнения, уязвимо. То есть умный хакер со временем взломает его, но для строк в коде приложения оно имеет смысл. Не будем прятать голову в песок: если хакеры захотят разобрать ваш код, они не станут слепо искать переименованные типы. Скорее всего они будут искать «Invalid License Key», что приведет их прямо в то место кода, где выполняется проверка лицензии. Поиск строки невероятно прост, а шифрование строк в какой-то мере препятствует этому, поскольку в скомпилированном коде присутствуют только зашифрованные строки.

Инкрементное затемнение Помогает решить при затемнении проблему с «заплатками» (patches), выпускаемыми для устранения ошибок. При Пресечение попыток обратного проектирования 227 устранении ошибок в коде часто создаются или удаляются классы, методы или поля. Изменение кода (например добавление или удаление метода) может привести к тому, что при последующем затемнении названия будут переименовываться несколько иначе. То, что раньше называлось «а», теперь может называться «Ы». И это, увы, непредсказуемо.

Инкрементное затемнение позволяет справиться с этой проблемой. Dotfuscator создает файл сопоставлений (map file), сообщающий, как выполнялось переименование. Однако тот же файл сопоставлений может быть применен как исходная информация при последующих запусках Dotfuscator, чтобы задать ему использовать предыдущие переименования везде, где это возможно. Если вы выпустили свои продукт, а затем исправили несколько классов, Dotfuscator можно запустить таким способом и позаимствовать предыдущую схему переименования. Тогда вы сможете передавать пользователям только исправленные классы.

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

Более того, мы все работаем с библиотеками и типами, написанными другими людьми для многократного применения.

Код для многократного применения предполагает наличие дополнительного кода, рассчитанного на самые разнообразные случаи (contingent code); однако в каждом конкретном приложении, как правило, встречается лишь один-два случая. Продвинутый затемнитель обнаруживает это и удаляет весь незадействованный код (опять же, из скомпилированной сборки, а не из исходного кода). В результате на выходе оказываются только те типы и методы, которые нужны вашему приложению, — больше ничего. Более компактное приложение расходует меньше вычислительных ресурсов и быстрее загружается. Это особенно важно для приложений, выполняемых под управлением.NET Compact Framework, и для распределенных приложений.

Использование Dotfuscator Community Edition

–  –  –

Он предоставляет GUI, помогающий легко создавать и эксплуатировать файл конфигурации, а также запускать затемнитель и проверять результат.

Кроме того, интерфейс командной строки для Dotfuscator Community Edition позволяет легко инте]рировать затемнение в процесс автоматизированной сборки. Запустить GUI можно непосредственно из меню Tools в Visual Studio.NET 2003.

Чтобы подготовить Vexed для затемнения, укажите в GUI три параметра:

входную сборку, местоположение файла сопоставлений и выходной каталог. Входные сборки (в Dotfuscator они называются «trigger assemblies») указываются на вкладке Trigger. Здесь их можно добавлять в любом количестве, но для Vexed нужна лишь одна.

Адрес файла сопоставлений указывается на вкладке Rename | Options (рис. 4). Файл сопоставлений содержит однозначное сопоставление между исходными и незатемненными* именами. Очень важно сохранить этот файл после затемнения приложения; без него искать и устранять проблемы в затемненном приложении будет непросто. Из-за важности этого файла Dotfuscator по умолчанию не перезаписывает существующий файл сопоставлений, пока вы не установите флажок Overwrite Map file.

Рис. 4. Вкладка Rename I Options

–  –  –

Рис. 5. Браузер результатов Наконец, вкладка Build позволяет указать каталог, где будет размещено затемненное приложение. Сделав это, вы готовы затемнить приложение.

Вы можете сохранить файл конфигурации для дальнейшего использования, а затем нажать кнопку Build на вкладке Build или кнопку Play на панели инструментов. Во время сборки Dotfuscator отображает информацию о ходе процесса на панели вывода GUI. Чтобы изменить объем выводимой здесь информации, выберите Quiet или Verbose на вкладке Options.

По завершении сборки можно наглядно оценить результаты на вкладке Output (рис. 5). Как видите, Dotfuscator отображает графическое представление приложения, подобно браузеру объектов (object browser). В режиме просмотра новые имена располагаются сразу под исходными. Заметьте, что класс с именем «board» переименован в «h», а два метода с разными сигнатурами (init и Tolmage) переименованы в «а».

Исследование файла сопоставлений Создаваемый с помощью Dotfuscator файл сопоставлений имеет XMLформат и, помимо уже упомянутых сопоставлений имен, содержит кое-какую статистику, дающую представление о том, насколько эффективным был процесс затемнения. В табл. 1 суммирована статистика для типов и методов после затемнения приложения Vexed.

230 Защита кода и данных Табл. 1. Статистика переименования

–  –  –

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

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

Во-первых, придется поработать чуть больше, если ваше приложение включает сборки со строгими именами (strongly named assembly). Такие сборки содержат цифровую подпись, которая позволяет исполняющей среде определить, изменялась ли сборка после подписания. Подпись представляет собой SHAl-хэш, подписанный закрытым ключом (private key) из RSA-пары ключей «закрытый-открытый». Подпись и открытый ключ (public key) встраиваются в метаданные сборки. Поскольку затемнитель изменяет сборку, важно, чтобы подписание было выполнено после затемнения. В период разработки и перед затемнением следует реализовать отложенное подписание (delay-signing) сборки и завершать процесс подписания позже. Подробнее о сборках с отложенным подписанием см. в документации.NET Framework. Также не забудьте отключить верификацию строгих имен (strong name validation) при тестировании сборок с отложенным подписанием.

Применение Reflection API и динамической загрузки классов (dynamic class loading) усложнит процесс затемнения. Поскольку эти технологии являются динамическими, они не сочетаются с технологиями статичеПресечение попыток обратного проектирования 231 ского анализа, которые используются в большинстве затемнителей.

Рассмотрим следующий фрагмент кода на С#, который получает тип по имени и динамически создает его экземпляр, возвращая тип, приведенный к интерфейсу:

public Mylnterface GetNewTypeO { Type type = Type.6etType( GetUserlnputStringO, true };

object newlnstance = Activator.Createlnstance( type );

return newlnstance as Mylnterface;

} Имя типа код получает от другого метода. GetUserlnputString может предлагать пользователю ввести строку или извлекать ее из базы данных.

В любом случае имя типа в коде отсутствует, и его нельзя получить статическим анализом, поэтому затемнитель не сумеет выяснить, для каких типов в исходных сборках могут создаваться экземпляры подобным образом. Выход из данной ситуации — запрет переименования всех потенциально загружаемых типов, реализующих Mylnterface (заметьте, переименование методов и полей по-прежнему допускается). Именно здесь важную роль играет настройка вручную и некоторые знания о затемняемом приложении. Dotfuscator Community Edition предоставляет средства, предотвращающие переименование заданных типов, методов или полей. Можно выбирать отдельные имена или писать правила исключения (exclusion rules), используя регулярные выражения и другие критерии вроде области видимости. Например, из переименования можно исключить все открытые методы.

Еще одна проблема с использованием затемнителей — сопровождение уже развернутого затемненного приложения.

Скажем, ваше приложение инициирует исключение (что случается даже с лучшими из нас), и пользователь отправляет вам дамп стека, который выглядит примерно так:

System.Exception: A serious error has occurred at cv.a() at cv..ctor(Hashtable A_0) at ar.a(di A_0) at ae.a(Strlng[] A_0) Разумеется, этот дамп стека гораздо менее информативен, чем дамп стека незатемненного приложения. Хорошая новость в том, что с помощью файла сопоставлений, созданного в ходе затемнения, можно декодировать информацию из стека в исходный вид. А плохая новость — информации из стека иногда недостаточно для того, чтобы по файлу сопоставлений однозначно восстановить исходные символы. Например, обратите внимание, что в дампе опущены возвращаемые типы метода. В приложениях, затемненных 232 Защита кода и данных с помощью усовершенствованного алгоритма переименования с использованием технологии введения перегрузки, методам, различающимся только возвращаемыми типами, могут быть присвоены одинаковые имена. Так что информация из стека может оказаться весьма туманной. В большинстве случаев вы сможете сузить круг возможных вариантов, чтобы с высокой степенью достоверности установить исходные имена. С этой целью Dotfuscator Professional предоставляет инструмент для автоматического перевода информации из стека к исходному «провинившемуся» методу.

Заключение Не давайте хакерам применять удобную утилиту ILDASM к вашему приложению с сомнительными целями. Защитить ваш код поможет хороший затемнитель. Затемнение препятствует обратному проектированию. Dotfuscator Community Edition, поставляемый с коробочной версией Visual Studio.NET 2003, обеспечивает хорошее затемнение кода всего несколькими щелчками кнопки мыши.

Габриэл Торок {Gabriel Torok) — президент PreEmptive Solutions. Соавтор книг «JavaScript Primer Plus» и «Java Primer Plus» издательства Macmillan.

Выступает с докладами на международных семинарах и конференциях по разработке программного обеспечения.

Билл Лич {Bill Leach) — технический директор PreEmptive Solutions. Архитектор и главный технолог линейки продуктов Dotfuscator. Раньше часто выступал в роли научного рецензента книг и статей по разработке программного обеспечения.

АлекДзвис

–  –  –

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

В этой статье объясняются основы защиты данных и сравниваются различные технологии, которые могут быть использованы для защиты параметров приложения. Автор рассказывает, чего следует избегать, например скрытия ключей в исходном коде и использования Local Security Authority. Кроме того, он представляет некоторые эффективные решения вроде Data Protection API.

Проблема защиты строк подключения баз данных, паролей и других секретных параметров приложения часто обсуждается в группах новостей и онлайновых форумах разработчиков. Хотя большинство специалистов по защите сходятся в том, что сохранить секреты с помощью программного обеспечения нельзя, известно несколько технологий, способных обеспечить достаточную защиту для приложений большинства типов. Все существующие способы защиты данных базируются на трех фундаментальных технологиях: скрытие (hiding), управление доступом (access control) Публиковалось в MSDN Magazine/Русская Редакция. 2003. № 11 (ноябрь). — Прим. изд.

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

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

Скрытие данных Скрытие данных (data hiding) иногда называют зашитой через затуманивание (security through obscurity). Полагаясь на этот способ, вы считаете, что только вам известно, где хранится секретная информация, и надеетесь, что никто другой не сможет это выяснить. Подвох в том, что приложение тоже должно знать, как получить доступ к данным, поэтому возможность сохранения секретов во многом зависит от способности приложения защищать это знание.

В число самых распространенных мест для скрытия секретных параметров приложения входят исходный код приложения, файлы конфигурации и реестр Windows. Данные можно хранить и в таких экзотических местах, как метабаза IIS (IIS metabase), UDL-файлы (Universal Data Link), файлы собственного формата — где угодно.

–  –  –

За редкими исключениями, простое скрытие данных обеспечивает в лучшем случае примитивную защиту. Как правило, объем работы, необходимой, чтобы хакер выяснил ваши секреты, минимален. Так, взломщик может обнаружить местоположение данных, отслеживая изменения в системе, выполняемые работающим приложением (рис. 1). Это можно сделать с помощью таких утилит, как regmon, filemon и diskmon от Syslnternals (http://www.sysinternals.com).

Простота декомпиляции.NET-сборок представляет еще более серьезную угрозу. При помощи декомпиляторов вроде Anakrino (http://www.saurik.com/ net/exemplar) или Salamander (http://www.remotesoft.com) код приложения может быть подвергнут обратному проектированию (reverse engineering), что приведет к раскрытию секретных данных или логики приложения (рис. 2).

*• Anakrino

–  –  –

Рис. 2. Декомпиляция Ограничение доступа к данным Если доступ к данным ограничен, скрывать их местоположение не нужно.

При таком подходе вы полагаетесь на технологические функции, встроенные в операционную систему и способные предотвратить несанкционированный доступ к данным. Обычно ограничения доступа базируются на идентификации вызвавшего (caller's identity) или знании общего секрета (рис. 3). Этот способ защиты данных используют Access Control Lists (ACL), Microsoft Data Protection API (DPAPI) и изолированные хранилища.

–  –  –

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

Типичные проблемы, связанные с управлением доступом на основе идентификации, приведены в табл. 1.

–  –  –

вызвавший должен что-то знать... вызвавший должен кем-то быть Пароля • Криптографического ключа Щ$ Пользователя I Машины 1 Сборки Рис. 3, Управление доступом Табл. 1. Проблемы управления доступом на основе идентификации Тип идентификации Проблемы

–  –  –

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

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

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

то Data link Properties

–  –  –

Рис. 5. Удостоверения в UDL-файле Выбирая или создавая механизм защиты данных, взвесьте его уязвимость перед потенциальными угрозами. Такая оценка может оказаться проще, если мыслить в категориях основных технологий зашиты данных, описанных выше. Например, если вы храните информацию для подключения к базе данных, содержащую SQL-удостоверения пользователя в UDL-файле (рис. 5), безопасность ваших данных сильно зависит от разрешений для файла (ACL-списков), которые являются одной из форм ограничения доступа. (В какой-то мере она зависит и от скрытия данных, но в данном 238 Защита кода и данных конкретном случае скрытие данных — очень слабая защита, поскольку требуется немного усилий, чтобы найти UDL-файл.) Хотя ACL-списки играют важную роль в защите данных, важно понимать, что, если хакер сумеет получить доступ к UDL-файлу для чтения, ваши SQL-удостоверения будут раскрыты.

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

Оценка вариантов По мнению многих экспертов по безопасности, лучший способ защиты секретов — вовсе не использовать их. Например, если вам нужно защитить строки подключения к базе данных, содержащие SQL-удостоверения, подумайте об отказе от SQL-аутентификации. Если ваше приложение способно для подключения к серверу баз данных применять Windows-аутентификацию вместо SQL-аутентификации, вам вообще не нужно будет беспокоиться о защите SQL-удостоверений.

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

• Насколько ценной является защищаемая информация? Какого ущерба можно ожидать, если защита данных будет скомпрометирована?

• От каких пользователей вы защищаете данные? От сотрудников, которые любят заглянуть в информацию, для них не предназначенную, но которые не станут преднамеренно атаковать систему? Или от целеустремленных хакеров, которые готовы потратить время, силы и деньги, чтобы скомпрометировать систему? Насколько далеко, по-вашему, может зайти потенциальный хакер, чтобы получить ваши данные?

• Так ли необходимо вашему приложению работать с секретными данными в расшифрованном виде?

• Вы защищаете только строки подключения к базам данных или данные и другого типа?

• Сколько идентификаций использует приложение, получающее доступ к вашим данным? Оно выполняется под одной идентификацией или несколькими?

Закрытие доступа к строкам подключения баз данных 239

• Какие версии операционных систем должно поддерживать приложение?

• Что вам важнее; производительность приложения или безопасность?

Готовы ли вы пожертвовать производительностью ради большей безопасности?

• Каков механизм определения данных? Это выполняется вручную, например с помощью текстового редактора, или программно? Если данные создаются программно, параметры приложения определяются из того приложения, которое их использует, или из другого приложения?

• Сколько приложений в вашей организации или компании используют защиту данных? Если их больше одного, все ли они предъявляют одинаковые требования? Хотите ли вы применить единое решение, удовлетворяющее требованиям всех приложений, или предпочитаете разные механизмы защиты данных для каждого приложения?

• Насколько сложно обслуживающему персоналу будет работать с защитой приложения после его развертывания? Согласна ли группа технической поддержки с вашим решением?

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

Все способы хранения секретных данных в открытом виде считаются ненадежными, поскольку раскрывают данные любому, кто получит доступ к их источнику, — задача, которая может оказаться проще, чем кажется. Следует избегать хранения незашифрованных данных в реестре Windows, конфигурационных файлах, каталогах СОМ+, изолированных хранилищах, файлах собственных форматов, метабазе IIS и UDL-файлах.

Более того, вообще никогда не храните секретные данные в открытом виде.

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

ACL-списков, а также скрытие и ограничение доступа к шифровальнымключам.

Реализуя защиту данных, можно принять во взимание и другие аспекты защиты, например предотвращение несанкционированной модификации данных (data tampering), но поскольку это не относится к секретности, я не стану рассказывать о таких аспектах в своей статье. Вместо этого я затрону более практичные темы: где хранить зашифрованные данные, какой тип алгоритмов шифрования использовать и как защитить криптографические ключи.

Хранение зашифрованных данных Если у вас нет веской причины поступать иначе, храните зашифрованные данные в конфигурационных файлах приложения или в реестре Windows. Основные преимущества этих вариантов — возможность защиты данных с помощью ACL-списков и легкость программного доступа.

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

Некоторые разработчики настаивают, что приложения Microsoft.NET Framework не должны использовать реестр, но это не закон. Главный недостаток реестра в том, что он не вполне подходит для развертывания приложения через XCOPY, однако, поскольку многие современные приложения развертываются с помощью программ установки и требуют выполнения определенных этапов конфигурирования в тех системах, куда они устанавливаются, совместимость с ХСОРУ может оказаться необязательной. Другой минус реестра в его специфичности для Windows-платформ — этот подход не сработает в других операционных системах. Впрочем, это ограничение станет серьезной проблемой, только когда и другие платформы станут поддерживать общеязыковую реализацию (common language implementation, С LI).

Если вас интересует развертывание через XCOPY или взаимодействие с платформами, отличными от Windows, используйте конфигурационные файлы; нет — выберите вариант, наиболее подходящий вашим потребностям. Если нужно хранить параметры, совместно используемые несколькими приложениями, или определять эти параметры программно, реестр может оказаться более удобным в работе. Параметры, специфичные для приложения, которые не изменяются программно, могут храниться в Закрытие доступа к строкам подключения баз данных 241 конфигурационных файлах. В любом случае не забудьте применить соответствующие ACL к хранилищу данных. Например, неплохо было бы назначить право доступа для чтения к файлу или разделу реестра, содержащему секретные данные, учетной записи пользователя, под которой выполняется приложение. Также следует явным образом присвоить право доступа для записи пользователю или группе пользователей (например Administrators), которым разрешено модифицировать данные.

Остальным следует запретить любой доступ.

Необратимое и обратимое шифрование Существуют два метода шифрования данных: необратимое (one-way) (обычно называемое хэшированием) и обратимое (two-way). Технически хэширование — это не шифрование, но поскольку обе технологии при защите данных могут применяться сходным образом, т. е. преобразовывать данные из открытого текста в шифрованный, я буду считать их логически связанными.

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

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

Аутентификация на основе паролей — типичный случай, в котором хэширование более приемлемо» чем обратимое шифрование. Если ваше приложение хранит пароли только в целях аутентификации, не зашифровывайте их симметричным или открытым ключом — храните вместо этого их хэшированные значения. При регистрации пользователя на входе вместо расшифровки и сравнения паролей в открытом виде приложение может сравнивать хэши паролей. Чтобы уменьшить риск атаки по словарю (dictionary attack), всегда используйте в хэшах «расширяющие»

значения (salt values). «Расширение» — это случайные данные, добавляемые к открытому тексту до того, как он будет хэширован, и сохраняемые вместе с хэшем для последующего использования при сравнении другого открытого текста с хэшем. Пример использования хэша с «расширением» для аутентификации на основе паролей см. в рубрике «Безопасный код» за август 2003 г, (http://msdn.micTosoft.com/msdnmag/issues/03/08/ SecurityBriefs/default.aspx).

242 Защита кода и данных Алгоритмы хэширования Самые популярные алгоритмы хэширования — MD5 и SHA-1. Длина хэшей SHA-1 равна 160 битам, а длина хэшей MD5 — 128, Алгоритм SHA-1 чуть медленнее, но обеспечивает более высокую защиту, чем MD5.

В дополнение к MD5 и SHA-1 NET Framework предлагает поддержку 256-, 384- и 512-битных версий алгоритма SHA, что еще надежнее, но, вероятно, и медленнее.

Простейший способ хэшировать данные — вызвать метод HashPasswordForStoringlnConfigFile класса FormsAuthentication, как в следующем примере:

using System.Web.Security;

...

string base64Hasn\'alue = FormsAuthentlcatlon.HashPasswordForStoringlnConfigFileC'mypassword", "shaT);

К сожалению, этот метод поддерживает только алгоритмы хэширования MD5 и SHA-1, так что, если вы хотите использовать хэши SHA-256, SHA-384 или SHA-512, вам придется писать чуть больше кода. Пример но ссылке http;//www.obviex.com/samples/hash,aspx поясняет, как создавать и сравнивать хэши с применением различных алгоритмов хэширования.

Шифровальные ключи Если вашему приложению необходимо знать текстовые значения секретных данных, вы не сможете применить хэширование. В таком случае используйте обратимое шифрование с симметричным ключом или с парой из открытого и закрытого ключей. Если вы не уверены, какой тип ключей выбрать, используйте симметричные ключи. Основной недостаток шифрования с открытым ключом — низкая производительность, которая может быть в 1000 раз меньше, чем при шифровании с симметричным ключом. Шифрование с открытым ключом также накладывает некоторые ограничения на размер текстовых данных, которые могут быть зашифрованы.

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

При выборе алгоритма шифрования имеет смысл выбрать самый надежный алгоритм с максимально длинным ключом. Самым надежным среди всех алгоритмов с симметричным ключом, поддерживаемых.NET Framework, считается одобренный правительством США алгоритм Rijndael (также известный как алгоритм Advanced Encryption Standard, или AES). Этот алгоритм поддерживает 128-, 192- и 256-битные ключи. Более подробную информацию о Rijndael см. в статье Джеймса Мак-Каффри в этом номере.

Алгоритм Rijndael обладает еще одним преимуществом по сравнению с другими алгоритмами с симметричным ключом, поддерживаемыми.NET Framework. Тогда как другие алгоритмы предлагаются в форме «тонких»

классов-оболочек.NET Framework над имеющимися модулями CryptoAPI, Rijndael (реализованный как класс RijndaelManaged) написан полностью в управляемом коде. Замечу, что некоторые разработчики считают это недостатком и предпочитают использовать неуправляемую реализацию алгоритма Rijndael для большей производительности.

К сожалению, эта реализация алгоритма Rijndael поддерживается только в Windows XP и выше, а также в системах, где установлена.NET Framework. Если ваше приложение должно быть совместимо с неуправляемыми программами, работающими под Windows 2000 или ниже, используйте Triple DES — улучшенную версию менее защищенного алгоритма DES. Алгоритм Triple DES поддерживает ключи длиной в 112 и 168 бит, но рекомендуется использовать 168-битные ключи. Из-за разной трактовки битов четности (parity bits) ключа 168-битные ключи Triple DES иногда называют 192-битными. Если вы хотите предоставить управляемым и неуправляемым приложениям возможность зашифровывать или расшифровывать данные одинаковым ключом Triple DES, учтите, что кодовая фраза (или пароль), из которого формируется ключ, должна содержать только печатаемые ASCII-символы; иначе сгенерированные ключи не совпадут (вследствие ограничений.NET-реализации алгоритма Triple DES)..

Оригинальные алгоритмы DES, RC2 и RC4 в целом считаются менее стойкими, чем Rijndael и Triple DES, поэтому их следует избегать. Ни при каких обстоятельствах не используйте доморощенный алгоритм шифрования. Не воображайте, что никто не сумеет его взломать.

–  –  –

Рис. 6. Схемы шифрования данных Защита криптографических ключей При использовании симметричных ключей для шифрования и расшифровки данных приложения важно иметь возможность создать такой же ключ через некоторое время. И здесь возникает проблема защиты ключей или логики генерации ключей (не путать с алгоритмами шифрования).

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

Постоянные симметричные ключи можно генерировать двумя способами:

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

Эти характеристики, как правило, включают кодовую фразу, по которой создается ключ, и, возможно, другие значения, например инициализирующий вектор (initialization vector). Что бы вы ни выбрали — кодирование байтов ключа или реализацию логики генерации ключа, вы в конечном счете скрываете ключ в исходном коде приложения. Такой вариант дает вам больший контроль и гибкость, но и подвергает ваши данные большему риску в случае обратного проектирования вашего приложения. В качестве альтернативы можно хранить ключ в постоянном хранилище вроде файла или реестра и защищать это хранилище с помощью ACL. Но такой подход чреват ошибками при сопровождении, поэтому я не рекомендую его.

Более безопасный, но менее гибкий способ генерировать ключи — позволить операционной системе делать это за вас. Для этого используются таЗакрытие доступа к строкам подключения баз данных 245 кие средства операционной системы, как Local Security Authority (LSA) или DPAPI.

Берегитесь LSA Во времена расцвета Windows NT 4.0 функции LSA Policy LsaStore PrivateData и LsaRetrieve Private Data предоставляли достаточно надежный способ защиты секретов приложения. Хотя функции LSA Policy доступны в Windows 2000 и выше (и по-прежнему используются для защиты таких данных, как пароли для служб Windows), Microsoft не рекомендует применять их, поэтому я упомянул эти функции лишь для полноты картины, чтобы объяснить, почему их следует избегать.

Проблема с функциями LSA Policy в том, что они не только управляют ключами и шифруют их, но и работают с хранилищами данных, используя защищенную область реестра Windows. Может показаться, что это хорошо, но это не так, потому что объем доступного места для функций LSA Policy ограничен 4096 слотами, половина из которых уже занята системой. Если приложения будут использовать LSA Policy для хранения секретных данных, им просто не хватит места. Далее, поскольку лишь в высшей степени привилегированные пользователи могут вызывать функции LSA Policy, они не сработают для приложений, выполняемых под непривилегированными учетными записями, такими как ASP.NET. Хуже того, существуют инструменты вроде LSADUMP2 (http://razor.bindview.com/tools/desc/ Isadump2_readme.html), способные раскрыть секреты LSA. Вывод: не применяйте функции LSA Policy для защиты данных.

Использование DPAPI Как альтернативу функциям LSA Policy компания Microsoft рекомендует применять подмножество Crypto API, которое называется DPAPI. DPAPI включает две функции, пригодные для защиты данных: CryptProtectData и CryptUnprotectData. Эти функции реализованы в crypt32.dll и могут вызываться из приложений.NET Framework через P/Invoke. DPAPI является частью операционной системы и доступен в Windows 2000 и выше.

DPAPI — в отличие от функций LSA — не работает с хранилищами данных, но способен создавать индивидуальные для машины или пользователя ключи для шифрования и расшифровки данных. Чтобы различать два типа ключей, в документации DPAPI их называют хранилищем машины (machine store) и хранилищем пользователя (user store).

Ключи, специфичные для машины, в общем небезопасны, поскольку могут быть использованы любым, кто получает доступ к системе. Можно сгенерировать более защищенную версию такого ключа, передав функции 246 Защита кода и данных DPAPI пароль (также называемый вторичной энтропией). Этот вариант лучше, поскольку он требует от вызвавшего кода знания этого пароля, но создает трудности с хранением пароля, что возвращает нас к исходной проблеме. Другая проблема с ключами, специфичными для машины, в отсутствии гарантий того, что они останутся такими же при изменениях в среде. Такие изменения, как перенос приложения на другой компьютер или перекомпиляция системы, способны разрушить приложение, использующее DPAPI с ключами, специфичными для машины.

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

Во-первых, поскольку эти ключи могут генерироваться только программами, выполняемыми с загружаемыми профилями пользователей, они не сработают в приложениях ASP.NET и в приложениях, выполняемых под определенными встроенными учетными записями, Хотя существует' способ обойти эти ограничения через обслуживаемые компоненты (serviced components), расплатой за него станет рост сложности и снижение производительности приложения. Этот способ также требует, чтобы обслуживаемый компонент выполнялся под привилегированной учетной записью, что нарушает принцип наименьшей привилегии. Если вы решите использовать DPAPI с ключами для пользователей, учтите, что только пользователь, зашифровавший данные, сможет расшифровать результат. Очевидно, это неприемлемо для приложений, выполняемых под разными учетными записями, или для программ, чьи параметры могут определяться разными пользователями. Другая проблема ключей, специфичных для пользователей, в том, что они позволяют всем приложениям, выполняемым в одном профиле пользователя, получать доступ к данным /[руг друга, что может стать брешью в защите. Как и в случае с DPAPI, использующим хранилища машины, эту проблему можно решить, требуя от вызвавшего кода предоставить вторичную энтропию, но, как и в предыдущем примере, возникнет проблема с хранением этой энтропии. К сожалению, DPAPI не позволяет одновременно использовать ключи, специфичные для машины и специфичные для пользователя (в одном вызове CryptProtectData).

DPAPI рекомендуется для приложений, которые выполняются под одной учетной записью с загружаемым профилем пользователя, и чьи параметры определяются одним пользователем. (Более подробную информацию см. во врезке «Загружаемый профиль пользователя».) Типичный пример — служба Windows, выполняемая под учетной записью локального или доменного пользователя. Если ваше приложение удовлетворяет этим требованиям, ему следует задействовать DPAPI с ключами, специфичными для пользователей. В других приложениях можно использовать DPAPI Закрытие доступа к строкам подключения баз данных 247 с ключами, специфичными для машины и защищенными вторичной энтропией (см. http://msdn.microsoft.com/library/en-us/dnnetsec/html/SecNetHTOS.asp и http://www.obviex.com/samples/dpapi.aspx). Вы можете определить эту энтропию в исходном коде приложения и затемнить двоичный файл приложения, чтобы обнаружить энтропию было непросто. Но если вы изберете такой способ, учтите, что даже затемненный код может быть подвергнут обратному проектированию. Чтобы узнать, что может и чего не может предложить вам затемнение, прочтите статью Брента Ректора (Brent Rector) «The Premier Obfuscator for Microsoft.NET Applications!» по ссылке http://www.wintellect.com/resources/newsletters/2002/ aug2002.aspx и статью Габриэла Торока (Gabriel Torok) и Билла Лича (Bill Leach) в этом номере.

Загружаемый профиль пользователя Хотя в документации Microsoft одним из требований к приложению, в котором применяется DPAPI с хранилищем пользователя, указан загружаемый профиль пользователя, там не объясняется, что это такое. Если вы озадачены этим термином, считайте, что это профиль интерактивного пользователя, который создается, когда пользователь впервые регистрируется в системе. Все приложения, интерактивно запущенные пользователем, выполняются с загруженным профилем интерактивного пользователя. Неинтерактивные приложения, такие как службы Windows, настроенные на выполнение под LocalSystem, не могут загружать профиль пользователя и, таким образом, не в состоянии задействовать DPAPI с хранилищем пользователя. То же можно сказать и о системных процессах, таких как процессы ASP.NET, которые выполняются под встроенными учетными записями. Чтобы позволить службам Windows обращаться к DPAPI с хранилищем пользователя, их следует настроить на выполнение под учетными записями локальных или доменных пользователей с уже созданным профилем.

На практике это означает, что до того, как приложение сможет выполнять вызовы DPAPI от имени :

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

Если ваше приложение не может напрямую использовать DPAPI с ключами, специфичными для пользователей, а вы не хотите примириться с угрозой обратного проектирования, подумайте о реализации DPAPI с обслуживаемым компонентом, но учтите, что это негативно отразится на производительности вашего приложения [см. «Use DPAPI (User Store) from I

248 Защита кода и данных

ASP.NET with Enterprise Services» по ссылке http://msdn.microsoft.com/ library/en-us/dnnetsec/html/SecNet-HT09,asp]. Выбрав такой вариант, будьте готовы реализовать схему авторизации для защиты от вызовов обслуживаемого компонента злонамеренными приложениями и пользователями, что может оказаться весьма непросто. Чтобы понять, как справиться с этой проблемой, изучите утилиту CipherSafe.NET и ее документацию — она иллюстрирует применение DPAPI для критичных задач и предлагает интересный подход к решению проблемы авторизации (см.

http://www.obviex.com/ciphersafe).

Скрытие ключей в исходном коде приложения Хотя профессионалы по защите продолжают убеждать прекратить «прятать» криптографические ключи (и другие секретные данные) в исходном коде приложений, разработчики продолжают игнорировать этот совет. Объяснить это можно двояко. Одной, очевидно непростительной причиной, по которой разработчики выбирают такой подход, является чрезвычайная простота его реализации. Другое объяснение в том, что альтернативные варианты в некоторых ситуациях не годятся. Например, рассмотрим ситуацию, где несколько приложений (скажем, служб Windows), выполняемых на разных компьютерах, должны использовать одинаковый ключ для шифрования и расшифровки информации, хранящейся в базе данных. В такой ситуации применение DPAPI для шифрования непрактично, поэтому разработчики могут принять решение встроить ключ в исходный код приложения. Быть может, это просто, но небезопасно. Лучшим подходом стало бы требование к администратору определить ключ для шифрования при установке приложения, зашифровать его значение через DPAPI с ключом, специфичным для пользователя с учетной записью, под которой выполняется приложение, и сохранить зашифрованное значение в реестре Windows или конфигурационном файле приложения. Но следует учитывать, что хотя этот метод представляет более безопасную техническую реализацию, он создает процедурные сложности.

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

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

Затемнение не делает обратное проектирование невозможным, но способно усложнить и замедлить этот процесс. Сравните рис. 7, на котором показана декомпилированная сборка, затемненная с помощью Demeanor (http://www.wiseowl.com), и рис. 3. Поскольку все закрытые (nonpublic) символы в затемненной сборке переименованы с использованием непечатаемых символов, а строки зашифрованы, воссоздание логики приложения из сборки может оказаться практически невозможным. Коммерческие декомпиляторы, такие как Salamander (http://www.remotesoft.com), способны облегчить задачу обратного проектирования, преобразуя непечатаемые символы в их печатаемые эквиваленты, а классы приложения — в исходные файлы, но они стоят денег, а хакеру по-прежнему придется разбирать нечитаемые символы (именно здесь «макаронный код» может действительно помочь!).

*• Andkitno

–  –  –

Рис. 7. Декомпиляция затемненных сборок Если вы определяете ключ в приложении, то, кроме затемнения сборки, старайтесь не хранить реальные байты ключа в исходном коде.

Вместо этого реализуйте логику генерации ключа на основе постоянных характеристик, таких как алгоритм шифрования, размер ключа, кодовая фраза, инициализирующий вектор, и «расширение» (см. пример по ссылке http:// www.obviex.com/samples/encryption.asp). Это внесет дополнительный уровень неопределенности, и ключ не удастся получить простым дампом символов из двоичного файла сборки. Так как логика генерации ключа и его характеристики постоянны, неизменность результирующего ключа гарантирована. Также хорошей идеей будет отказ от использования статических строк в качестве характеристик для генерирования ключа и их создание 250 Защита кода и данных «на лету». Еще можно предложить рассматривать сборку так же, как хранилище данных, т. е. применять соответствующие ACL. И прибегайте к этому варианту лишь в качестве крайней меры, когда никакая другая технология защиты данных неприменима и единственной альтернативой остается хранение секретных данных в незашифрованном виде.

Изолированное хранилище Иногда изолированное хранилище упоминается как метод защиты данных.

Оно позволяет ограничить доступ к данным сборки приложения. Хотя такой вариант может быть полезен, изолированное хранилище не рекомендуется для защиты секретных данных, поскольку в нем не используется шифрование; оно лучше подходит для хранения индивидуальных пользовательских параметров приложения. Для хранения секретных пользовательских данных в приложении используйте DPAPI совместно с изолированным хранилищем.

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

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

Алек Дэвис (Alek Davis) — старший разработчик в группе инженеров по защите в корпорации Intel (Фолсом, штат Калифорния). Обладает опытом разработки Windows-приложений с акцентом на защиту корпоративных приложений. Имеет степени бакалавра компьютерных наук и магистра в области программирования, полученные в Калифорнийском университете (Сакраменто).

Джейсон Фишер Знание типичных механизмов вирусных атак поможет лучше защитить приложения* Компьютеры разработчиков зачастую более уязвимы для вирусов, чем компьютеры среднестатистических корпоративных пользователей, поскольку разработчики чаще обращаются к удаленным машинам и общим сетевым ресурсам и поддерживают разные уровни административных привилегий на множестве машин. Антивирусное ПО неплохо справляется с функциями первой линии обороны, но, чтобы самостоятельно защищать свои исполняемые файлы и противостоять вирусам, вам потребуются определенные базовые знания. В этой статье обсуждаются профилактические методы защиты от вредоносного исполняемого кода в ресурсах, библиотеках компонентов, сценариях и макросах, а также поясняется, как избежать множества других уязвимостей в системе.

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

Публиковалось в MSDN Magazine/Русская Редакция. 2003. № 5 (май). — Прим. изд.

Защита кода и данных Я не предлагаю отказаться от антивирусных программ для повседневной защиты — тем более что они прекрасно справляются с известными угрозами. Однако, если вам еще не доводилось бороться с вирусом без антивирусных программ, рано или поздно это обязательно случится.

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

Готовимся к бою Как в принципе работают вирусы? Ну, во-первых, его создателю нужно написать исполняемый код для активизации вируса. Чего хочет автор от своего вируса? Должен ли он форматировать ваш винчестер? Удалять JPG-файлы? Отправлять по почте свои копии вашим друзьям и коллегам? Для всего этого потребуется некий исполняемый код. А чтобы запустить этот код, нужно активизировать вирус. Обычно исполняемый код вируса запускается напрямую: некий беспечный пользователь получает по электронной почте письмо с вложенным файлом типа «Дважды щелкни здесь и будет тебе счастье.ехе» или с чем-то столь же притягательным. Он запускает программу, и вирус срывается с цепи.

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

Из чего состоит исполняемый код вируса?

Конечно же, вы знаете, что исполняемыми являются ЕХЕ-файлы, а также некоторые другие типы файлов с расширениями вроде.cmd и.com. Поскольку документы текстовых процессоров могут содержать макрокоманды для выполнения определенных задач, они тоже способны запускать небезопасный код. Существует много других типов файлов, содержащих или запускающих исполняемый код. а любой исполняемый код может оказаться небезопасным. В целом исполняемый код делится на три основных вида: самостоятельные программы, код в ресурсах или библиотеках и код сценариев или макросов, исполняемых каким-либо интерпретатором.

Знание типичных механизмов вирусных атак 253 В широком смысле самостоятельная программа — это файл любого из многих возможных типов, запускаемый операционной системой. Как узнать эти типы? Ответ — в реестре Windows. Для борьбы с вирусами на их собственной территории вы должны уверенно чувствовать себя в работе с реестром. Посмотрим, как вызываются исполняемые программы.

Запустите редактор реестра (regedit.exe) и раскройте узел HKEY_CLASSES_ROOT (HKCR). В нем операционная система хранит информацию о сопоставлениях файлов и относящихся к ним командах. Раскрыв HKCR, вы увидите узлы для всех типов файлов, зарегистрированных на вашей машине. Просмотрите дерево и найдите раздел.ехе. Выберите его и обратите внимание, что в нем хранится параметр по умолчанию со значением «exefile» (оно показывается в правой панели окна). Это указатель на другой раздел в HKCR — exefile.

Раздел exefile содержит подраздел shell. В нем определяются возможные действия для данного типа файлов. В терминологии ОС эти действия называются операциями (verbs). Так, для документа Microsoft Word может быть определена операция печати, что позволяет, щелкнув файл правой кнопкой мыши, выбрать из контекстного меню команду Print. Раскройте подраздел shell узла exefile и вы увидите возможные операции для ЕХЕ-файлов. В зависимости от конфигурации вашей системы вы скорее всего найдете два или три подраздела. Возьмем для примера подраздел open. Раскройте его и выберите подраздел command. Для каждой операции создается собственный подраздел, каждый из которых в свою очередь включает подраздел command. Параметр по умолчанию в этом разделе точно описывает, что произойдет при выполнении данной операции.

Двойной щелчок значка файла в Explorer дает тот же эффект: выполняется команда для операции по умолчанию (для ЕХЕ-файлов — операция open), Как видите, для ЕХЕ-файлов раздел command в open содержит параметр %1 %*. Если вы помните командные файлы MS-DOS, то, вероятно, почувствуете что-то знакомое. Идея в том, что вместо параметра %1 подставляются путь и имя запускаемого ЕХЕ-файла, а все ключи и параметры командной строки, идущие за именем файла, передаются через параметр %*.

Так что любые другие типы файлов, для которых операция open содержит параметр %1, могут представлять угрозу. Таких типов уйма, и все они потенциально опасны. Создателю вируса известно, что многие не станут дважды щелкать файлы с расширением.ехе и скорее всего не будут запускать ВАТ-файлы, но не запустят ли они CMD-файл? А как насчет расширений.com,.pif или.vbs? Операция open для всех этих типов файлов содержит параметр %1. Создатель вируса может просто заменить расширение файла с исполняемым кодом вируса с «.ехе» на, скажем, «.com», и тем самым Защита кода и данных увеличит вероятность того, что многие неподготовленные пользователи запустят этот файл. Особенно опасны скромные файлы экранных заставок с расширением.scr.

Волк в овечьей шкуре Сравните в редакторе реестра параметр по умолчанию разделов command операции open для ЕХЕ- и SCR-файлов. Как видите, они почти совпадают: "%1" %* для ЕХЕ-файлов и "%1" /s для SCR-файлов. Получается, что экранные заставки — самостоятельные приложения. Единственное отличие в параметрах по умолчанию — ключ /S для SCR-файлов. Операция open для файла экранной заставки изначально предназначена для предварительного просмотра заставки; ее исполняемый файл именно так и воспринимает ключ /S. Ничто не может помешать создателю вируса присвоить файлу своей программы расширение.scr и проигнорировать ключ /S, передаваемый при ее вызове пользователем.

Эксплуатировать популярность заставок особенно просто, потому что в контекстном меню команда для операции open называется «Test». Пользователь думает, что он просто предварительно просматривает заставку, а на самом деле активизирует вирус. Самые «умные» вирусы могут даже показывать настоящую заставку, чтобы занять вас на то время, пока вирус будет разрушать файлы на жестком диске. Название команды хранится в параметре по умолчанию раздела open. Может, стоит заменить ее название на «O&pen and Test», что точнее, — ведь для того, чтобы проверить заставку, операционной системе придется открыть файл. Это поможет пользователям понять, что при выборе данной команды меню они запускают исполняемый код экранной заставки, что может оказаться небезопасным, если код заражен вирусом.

Библиотеки бывают опасны Исполняемый код также может находиться в различных ресурсах или библиотеках компонентов. На первый взгляд, это странное место для вирусов, но на самом деле оно прекрасно подходит для них. К таким ресурсам относятся файлы динамически подключаемых библиотек (,dll), апплетов панели управления (.cpl), библиотек типов (.tlb,.olb и т, д.), ActiveX-элементов и СОМ-комлонентов (.осх,.vbx,.dll и др.). Этот код не запускается напрямую с параметром %1, как ЕХЕ-, CMD-, СОМ- и прочие исполняемые файлы, но это не значит, что его нельзя выполнить.

Почти любую функцию из DLL-библиотеки можно вызвать при помощи вспомогательной программы RUNDLL32.EXE.

Возьмем такой пример:

Знание типичных механизмов вирусных атак rundll32.exe shell32.dll,OpenAs_RunDLL c:\winnt\win.ini Функция OpenAs_RunDLL из SHELL32.DLL принимает один параметр — имя файла. При вызове она отображает диалог Open With (рис. 1). Выбрав в нем имя файла и щелкнув кнопку ОК, можно открыть этот файл в соответствующем приложении, которому имя файла передается в виде параметра командной строки. И примеров таких вызовов в системном реестре — масса. Возможно, вы захотите взглянуть на некоторые из них, чтобы лучше понять их работу и предоставляемые ими системные функции. Для этого просто выполните в реестре поиск по RUNDLL32.

win.lnj - War dP ad Fia fflit View Jnsert Fori

–  –  –

Здесь вирус может атаковать вас двумя способами. Первый заключается в подмене DLL зараженной версией, где соответствующая функция заменена функцией с таким же именем, но иного назначения. Тогда при вызове этой функции операционной системой вместо желаемого результата активизируется вирус. Второй способ состоит в написании новой DLL и вызове ее функций через RUNDLL32.EXE. Это не так просто, как запустить код из ЕХЕ-файла, но DLL, OCX, TLB или другие библиотечные файлы с большей вероятностью будут приняты неподготовленным пользователем или пропущены антивирусной программой, что вознаграждает дополнительные усилия вирусописателя.

Сценарии и макросы: больше гибкости — больше риска Чтобы интерпретировать и запустить код сценария, нужен соответствующий движок (engine), но этот код все же можно использовать для инфицирования. Сценарии бывают нескольких видов. Очевидно, что самые популярные сценарии — макросы Visual Basic for Applications (VBA), содержащиеся в документах Microsoft Office. Microsoft многое сделала для обеспечения безопасности этих макросов, но макровирус по-прежнему может нанести значительный ущерб, тем более что к документам с макросами слишком многие относятся безответственно. Другой набирающий популярность вид сценариев — файлы Windows Script Host (WSH). Эти файлы, как правило, имеют расширения.wsf,.js или.vbs и по умолчанию сопоставлены своим приложениям, поэтому при двойном щелчке такой файл запускается без всяких вопросов. Последствия могут быть катастрофическими. Чтобы предотвратить их, желательно изменить операцию по умолчанию с «open» на «edit». Это делается через реестр или диалоговое окно Folder Options (рис. 2).

Опасные сценарии могут содержаться и в Web-приложениях. Как вы, вероятно, знаете, в целях безопасности клиентские сценарии и ActiveX-элементы сильно ограничены в правах доступа к системе, но есть малоизвестный тип файлов — HTMLAppIication (с расширением НТА), — который работает как клиентское Web-приложение, но не скован такими же ограничениями доступа. Он предназначен для того, чтобы разработчики могли использовать свои навыки в Web-разработке при создании полнофункциональных приложений на основе браузера. Но опять же, неподготовленный пользователь может создать полный хаос, скачав и запустив такой файл без предварительной проверки его содержимого. Перед запуском все эти сценарии и макросы можно легко проверить, поэтому следует уделять внимание любым файлам такого типа в вашей системе.

Знание типичных механизмов вирусных этак

–  –  –

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

R ЕС-файлы Как вы, наверное, знаете, файлы с расширением.reg — это системные регистрационные файлы (system registration files) с информацией, которая

–  –  –

вносится в реестр. Проблема в том, что для них по умолчанию применяется операция «open» (с названием «Mer&ge»). Значит, если дважды щелкнуть любой REG-файл, то в зависимости от конфигурации системы его содержимое может быть немедленно скопировано в системный реестр без запроса подтверждения. Ужасная идея, даже если не принимать во внимание возможность злоупотребления. Прямо сейчас оторвитесь от чтения и измените операцию по умолчанию для REG-файлов с «open» на «edit». Это можно сделать через диалог Folder Options (рис. 2) или изменить параметр по умолчанию для подраздела shell в разделе regfile, щелкнув его правой кнопкой и выбрав команду Modify (рис. 3). В любом случае для файлов этого типа операцией по умолчанию станет редактирование.

–  –  –

Рис. 3. Устранение уязвимости Почему REG-файлы столь опасны? Рассмотрим пример. В прошлом году мне пришлось разбираться с вирусом на компьютере моего друга. Каждый раз при запуске приложения я получал сообщение об ошибке, где говорилось, что не удается найти некий исполняемый файл (не тот, который я пытался запустить). После допроса с пристрастием мой друг признался, что, пытаясь самостоятельно «почистить систему», увидел этот файл и просто удалил его. Но теперь он вообще не может ничего запустить. Теоретически он правильно сделал, что удалил исполняемый файл вируса, но, очевидно, что-то было не так в параметрах реестра для файлов с расширением.ехе.

Знание типичных механизмов вирусных атак 259 Разумеется, из-за удаления самого вируса он не мог запустить ни один исполняемый файл, включая редактор реестра. Можно было попробовать переименовать RegEdit.EXE в RegEdit.COM. Я надеялся, что, хотя вирус явно изменил параметры реестра для ЕХЕ-файлов, он, возможно, не тронул параметры для СОМ-файлов.

К счастью, это решение позволило запустить редактор реестра. Как я и думал, вместо "%1" %*, операция open для ЕХЕ-файлов содержала команду «VirusExecutable.EXE %1. Таким образом, при каждом запуске ЕХЕ-файла сначала запускалась программа с вирусом. Запрашиваемая программа передавалась вирусу через параметр командной строки, и вирус мог запустить ее, оставляя пользователя в неведении относительно происходящего. В этом и кроется опасность REGфайлов: с их помощью можно запросто проделать такие изменения. Но если вы разбираетесь в реестре, то сможете отменить эти изменения. Хорошим, но выходящим за рамки данной статьи решением будет контроль доступа к важнейшим узлам реестра. Подробнее об этом см. по ссылке http://msdn.microsoft.com/library/en-us/dnexnt01/html/ewn0201.asp.

Узел ЕХЕ — лишь одно из многих мест в системном реестре, где можно найти опасные изменения. Два других — разделы HKLM\SOFTWARE\ Microsoft\Windows\CurrentVersion\Run и RunOnce. REG-файл или исполняемый файл вируса могут добавить в любой из этих разделов параметры, содержащие путь и имя файла любого приложения, которое должно быть запущено при загрузке системы. Эти параметры не отражаются в группе Startup меню Start, и, если вы не знакомы с данным разделом реестра, обнаружить их трудно. Разделы Run и RunOnce есть и в кусте реестра HKEY_CURRENT_USER. Борясь с вирусом, проверьте их оба.

Еще один уязвимый раздел — HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon. Он содержит несколько параметров, которые могут использоваться вирусами. Так, раздел Shell указывает исполняемый файл, используемый в качестве оболочки Windows, и обычно содержит «Explorer.exe», однако вирус способен изменить его. Менее известный раздел Userinit, который просто указывает на userinit.exe, можно изменить так, чтобы запускать любую программу без ведома пользователя при загрузке системы. Вирус обычно модифицирует этот параметр, чтобы он указывал на исполняемый файл самого вируса, который затем запускает userinit.exe, и пользователь наверняка ничего не заметит. Это лишь некоторые из уязвимых разделов, о которых следует знать. Если вы самостоятельно боретесь с вирусом, эти разделы и параметры могут подсказать, где искать что-либо необычное. Конечно, перечислить все разделы, которые используются вирусами, нельзя. Главное — свободно ориентироваться в реестре. Исследуйте реестр и учитесь принимать меры для его защиты.

Защита кода и данных Уязвимость PATH Еще одна опасность таится в переменной окружения PATH. Как вы знаете, все самые длинные и часто используемые пути можно перечислить в переменной PATH, чтобы не набирать их каждый раз. Например, если вы внесете в переменную PATH путь d:\Program Files\Microsoft Visual Studio\vb98\, то для запуска Visual Basic 6.0 из командной строки достаточно набрать «vb6». В системном реестре есть масса ссылок на исполняемые файлы, которые тоже пользуются этим преимуществом. Проблема в том, что применение этой на первый взгляд безобидной возможности весьма рискованно. Рассмотрим следующий сценарий.

Windows определяет, какое исполняемое приложение следует использовать в качестве оболочки, из параметра реестра в разделе HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon. В этом разделе параметр Shell обычно имеет значение «Explorer.exe». Логично, да? Но в нем не указан путь. Ведь есть (или должен быть) только один файл Explorer.exe — зачем указывать путь? Не лучше ли просто разрешить Windows определить расположение файла по стандартной процедуре поиска пути (включая просмотр значения и PATH)? Нет! Вариации вирусов Nimda и CodeRed известны тем, что они заражали и создавали новые исполняемые файлы с именем Explorer.exe, а потом размещали их в таких местах, как корневой каталог системного раздела. Конечно, вирус не способен перезаписать выполняемый экземпляр Explorer.exe, поскольку он монопольно блокирован операционной системой, но при следующей перезагрузке изза отсутствия пути в параметре Wmlogon\Shell скорее всего будет запущена фиктивная копия Explorer.exe из корневого каталога системного раздела или другого места, указанного в переменной PATH до пути к системному каталогу. А некоторые особо вредные вирусы способны заразить даже оригинал — %SystemRoot%\Explorer.exe.

Так что причиной отсутствия пути в этом параметре реестра может быть только лень. Вновь оторвитесь от чтения и проверьте реестр: если путь не указан, немедленно исправьте это, как показано на рис. 3. (Учтите, что такое изменение может нарушить работу некоторых программ установки, некорректно обращающихся с данным параметром.) Кроме того, начинайте избавляться от привычки слишком сильно полагаться на переменную PATH. Убедитесь также, что вирус не добавил к ней другие каталоги, которым там нечего делать. Вирусы нередко делают именно так, но при должной бдительности этого легко избежать. Помните, что любой компьютер в вашей сети может быть заражен (любыми традиционными способами, из которых самым распространенным является запуск инфиЗнание типичных механизмов вирусных атак 261 цированного почтового вложения), и тогда вирус легко скопирует инфицированную версию Explorer.exe или любого другого часто используемого системного файла, уязвимого через PATH, на ваш компьютер через открытый сетевой ресурс. При следующей перезагрузке вы заразите свой компьютер, хотя сами не запускали никаких вложений или сомнительных программ.

В куче фрагментов Последнее, о чем я расскажу, — об объекте фрагмента документа (scrap object). Существует два типа соответствующих файлов (рис. 4). Оба типа очень опасны, поскольку могут инкапсулировать исполняемый код в составном документе OLE (compound OLE document). Чтобы понять механизм их работы, в свободное время изучите параметры реестра, управляющие операциями open для этих файлов. Создать исполняемый код для таких фрагментов несложно (см, статьи на смежную тематику, перечисленные в аннотации).

–  –  –

Рис. 4. Фрагменты документов Мало того, что эти файлы могут содержать исполняемый код, есть еще две причины, делающие их очень опасными. Во-первых, они часто пропускаются антивирусным ПО. Даже если один из типов включается в список исполняемых файлов, второй часто игнорируется. Убедитесь, что ваши антивирусные программы проверяют файлы обоих типов.

Защита кода н данных Вторая причина тоньше. Как оказалось, расширения SHS и SHB всегда скрываются Explorer — пусть даже в настройках Windows вы задали отображение расширений всех файлов. Дело в том, что разделы реестра для этих типов файлов включают недокументированный параметр «KeverShowExt». Он переопределяет глобальные настройки Windows. Так что автор вируса может создать такой объект, присвоить ему значок, соответствующий файлу с изображением, и переименовать его в нечто вроде «Посмотри на эту забавную KapTHUKy.jpg». Реальное имя файла будет, конечно, «Посмотри на эту забавную KapTHHKy.jpg.shs», но неискушенному пользователю файл покажется обычным графическим, содержащим какую-нибудь картинку. Когда возникнут подозрения, что этот файл вовсе не содержит никакого изображения, ущерб уже будет нанесен. Поэтому удалите из обоих разделов параметры «NeverShowExt». Тогда вы сможете быстрее распознать эти опасные фрагменты.

Лучшая оборона — нападение Так что же делать с этими нечестивыми мерзавцами? Очевидно, что полностью полагаться на антивирусное ПО наивно, но в то же время справиться с вирусом, уже проникшим внутрь, гораздо сложнее. Должна быть золотая середина — стратегия, которая поможет избежать заражения, даже если вам не известен тип вируса, пытающегося атаковать систему. Для этого нужно мыслить творчески.

На рис, 5 показан один из многих возможных вариантов решения этой проблемы. Я создал приложение на Visual Basic.NET, в котором реализовал механизм,, предотвращающий запуск неблагонадежных программ и распространение вируса по системе или всей сети. Прежде чем объяснять, как оно работает, замечу, что это не полностью законченное приложение (например, в нем нужно расширить обработку ошибок) и оно не претендует на непогрешимость. Это лишь отправная точка, отталкиваясь от которой вы сможете обдумать превентивные меры по защите от вирусов.

Рис. 5. Защита от запуска инфицированных файлов bnports System.Security.Cryptography Imports Microsoft. Win32 Imports System.Text Imports System.10 Module Verify&ce

–  –  –

Рис. 5. Защита от запуска инфицированных файлов Private Function 8yteArrayToString{ByVal DataQ As Byte) As String Din Counter As Integer

–  –  –

End Module Я настроил свою утилиту на отслеживание расширений EXE, COM и ВАТ, но, если хотите, можете расширить этот список другими типами файлов. Она ищет ссылку на исполняемый файл в определенном месте реестра. Если такой параметр есть, он содержит MDS-хэш исполняемого файла (рис. 6). Если соответствующей записи нет, значит, ссылка была удалена, или с момента установки моей утилиты верификации приложение не запускалось. В любом случае приложение нужно запустить. Однако сначала следует вычислить MDS-хэш для этого приложения и записать его в корректном месте реестра. Вообще-то теперь моя программа не сумеет предотвратить запуск файла, если он был инфицирован еще до вычисления хэша. Но можно добавить в программу диалог для подтверждения действия, чтобы пользователь мог сам принять окончательное решение.

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

Защита кода и данных

–  –  –

Рис. 6. MDS-хэш Я не создава.1 программу установки для своей утилиты, поэтому вам придется установить ее вручную. Для этого измените параметр Shell\Open\ Command реестра для каждого типа файлов, который вы хотели бы контролировать. Например, чтобы отслеживать изменения в ЕХЕ-файлах, измените значение параметра по умолчанию в разделе HKCR\exefile\Shell\ Open\Command с "%1" %* на «ш/тъ\VerifyExe.exe» "%1" %*.

Разумеется, вместо пути следует подставить полный путь к файлу VerifyExe.exe. Это позволит запускать утилиту для всех ЕХЕ-файлов. Затем она запустит требуемый ЕХЕ-файл, передав ему все ключи и параметры командной строки. Внесите в реестр те же изменения для типов файлов СОМ и ВАТ, а также для любых других, которые вы хотите контролировать. Возможно, вам захочется встроить эти сопоставления в саму программу или в программу установки.

Я знаю, о чем вы сейчас думаете. А если вирус учтет такой способ контроля и удалит из реестра необходимые параметры до инфицирования приложения? Тогда при следующем запуске приложение сможет выполняться и распространять вирус. Или же вирус просто удалит сам файл VerifyExe.exe?

Все это возможно, но горькая правда в том, что здесь ничего не поделаешь.

Что бы вы ни делали, вирус всегда может обойти вашу оборону. Конечно, вы можете изменить исходный код утилиты и размещать хэш в другом разделе реестра, INI-файле или любом другом месте. Вероятно, тогда вирусам будет труднее избежать обнаружения, однако любое эффективное решение рано или поздно само станет мишенью для вирусов. Именно поэтому, как я уже Знание типичных механизмов вирусных атак 267 говорил, многие современные вирусы пытаются обнаружить и обезвредить антивирусное ПО. Но все-таки это решение предлагает неплохую защиту и должно побудить вас к разработке собственных методов защиты от вирусов, Заключение Чтобы обезвреживать вирусы, надо знать, как они работают. По мере усложнения вирусы становятся все более агрессивными по отношению к антивирусному ПО. Если с вами такого еще не случалось, будьте уверены, рано или поздно вам придется бороться с вирусом самостоятельно. Помните, что лучшая оборона — нападение. Из этой статьи вы узнали, как контролировать содержимое исполняемых файлов в своей системе, так что сможете всегда быть готовы к атаке вирусов. Сочетание подобных мер со свежими антивирусными программами и знанием соответствующих разделов реестра не позволит создателям вирусов перехитрить вас.

ДжеЙсон Фишер (Jason Fisher) — технический архитектор, независимый автор и редактор. По ночам он превращается в бесстрашного супергероя и безжалостного поборника компьютерной справедливости, который сражается с вирусами, отражает атаки типа DDoS и др'угие попытки вторжений.

В свободное от подвигов время с ним можно связаться по адресу jasef@swbell.net.

Стэн Зундблат и Пер Зундблат

–  –  –

Архитектура автономного приложения Архитектура, ориентированная на сервисы (Service-Oriented Architecture, SOA), рассматривает приложение как сервис, который можно найти и к которому можно получить доступ через Интернет; при этом не имеет значения ни платформа, ни язык программирования, на котором написан компонент-потребитель. Сервис должен быть совершенно автономным, но не изолированным, поскольку ему придется обслуживать клиентские запросы. Обслужить запрос или отклонить его, решает сам сервис и никто другой. Авторы знакомят читателей с концепцией автономии и эмиссаров и предлагают проектировать приложение как автономию, a UI — в виде набора эмиссаров, переложив на них как можно больше работы.

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

Люди не могут жить в полной изоляции, и разработчики тут не исключение- Архитекторы, проектировщики и разработчики ПО должны общаться, чтобы успешно решать стоящие перед ними задачи. То же верно и для приложений. Однако согласно устоявшейся парадигме, приложение можно рассматривать как самодостаточную сущность. Так, приложения для любых платформ, от мэйнфреймов до настольных, управляли всем — пользовательским интерфейсом (Ш), прикладной логикой (бизнес-логикой) и данными, ни с кем не общаясь и не допуская в свое «хозяйство» посторонних.

Публиковалось в MSDN Magazine/tyccKaa Редакция. 2003. № 7 (июль). — Прим. изд.

Архитектура автономного приложения 269 Теперь все иначе. Современным приложениям часто требуется интеграция с существующим ПО, и в ближайшее время эта тенденция скорее всего сохранится. Более того, приложения все больше теряют контроль над Ш, так как тот проектируется отдельно от самого приложения и взаимодействует с ним через Интернет.

Ясно, что потребность в кросс-платформенной интеграции нужно учитывать при проектировании и разработке приложений. К счастью, у этой задачи есть решение. Архитектура, ориентированная на сервисы (ServiceOriented Architecture, SOA), рассматривает приложение как сервис, который можно найти и к которому можно получить доступ через Интернет;

при этом не имеет значения ни платформа, ни язык программирования, на котором написан компонент-потребитель (consumer). Иначе говоря, сервис сам предоставляет сервисы, не зависящие ни от платформы, ни от языка. И Web-сервисы — лишь один из примеров.

Автономия — что это такое?

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

Пэт Гелланд (Pat Helland), архитектор из Microsoft, начал говорить об автономных приложениях одним из первых, но теперь у него много последователей. Его концепция представляется нам здравой, в чем мы попытаемся убедить и вас. Пэт называет автономные приложения «автономиями»

(fiefdoms)*, и мы тоже будем пользоваться этим термином.

Главный ресурс, который автономия хранит, поддерживает и защищает, — это данные. Данные автономии могут храниться в самых разных источниках. Структурированные данные обычно хранятся в реляционных базах данных типа SQL Server. Автономия не дает никому прямого доступа к своим данным, сама выбирая для клиента запрошенные им данные и даже выполняя для него операции над этими данными. Так или иначе, только автономия обладает прямым доступом к своим данным.

В буквальном переводе: вотчина, — Прим. перев.

270 Защита кода и данных Автономия запрещает посторонним блокировать ее данные, поэтому можно считать, что реальные данные никогда не покидают пределов автономии — только их копии, «моментальные снимки». Что касается актуальности данных, она имеет место только в пределах автономии. Клиенту не следует рассчитывать на получение самой последней версии данных. Даже в момент получения данные могут потерять актуальность из-за какой-то транзакции, выполненной над источником данных внутри автономии.

Большинство автономий стремится самостоятельно управлять своими транзакциями. Автономия ни при каких обстоятельствах не должна разрешать посторонним управлять выполняемыми внутри нее транзакциями (или отдельными частями этих транзакций). И все же автономия может предоставлять внешнему клиенту сервис, позволяющий ему управлять частью транзакции, если эта часть относится к так называемой компенсирующей транзакции (compensating transaction). Автономия монопольно управляет своей частью транзакции, но делает это в рамках обслуживания клиента, который выступает в роли координатора транзакции.

Примером компенсирующей транзакции может быть любая транзакция, соответствующая второй части спецификации Web Services Transactions — Business Activity (BA). Такая транзакция выполняется по одному из двух сценариев, В первом (нормальном) выполняется набор операций, указанных в транзакции, а во втором — другой набор операций, призванных устранить последствия транзакции, уже зафиксированной в источнике данных автономии. Компенсирующая транзакция вызывается координатором транзакции, в роли которого может выступать другая автономия. Она происходит, если после фиксации автономией своей части транзакции координатор обнаруживает, что какая-то другая часть транзакции завершилась неудачей. В таком случае все изменения, внесенные транзакцией, которая выполнена и зафиксирована автономией, нужно удалить, даже если их откат невозможен. А это вполне вероятно, так как блокировка соответствующих записей уже освобождена, и другие транзакции могли успеть изменить их состояние. Компенсирующая транзакция исключает такую ситуацию.

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

Защищенные шлюзы В какой-то мере приложение, ориентированное на сервисы, безопасно просто по своей природе: единственный способ заставить его выполнить oneАрхитектура автономного приложения 271 рацию в интересах клиента — отправить ему сообщение с запросом на обслуживание. Выполнить этот запрос или отклонить, решает приложение.

Приложение нередко предоставляет часть своих сервисов всем, кто запросит их. Тогда Web-сервису достаточно делегировать работу подходящему компоненту, а затем передать клиенту ответ от этого компонента. В других случаях Web-сервис должен сначала аутентифицировать клиента, чтобы выяснить, имеет ли он право на запрошенный сервис. Это может быть простая проверка удостоверений в Active Directory или базе данных SQL только на шлюзе. Или проверка с применением различных технологий защиты, например, олицетворения или делегирования в сочетании с зашитой на основе ролей на разных уровнях приложения. Не забывайте об угрозе атак типа «отказ в обслуживании», о хакерах, пытающихся проникнуть в систему, и т. п.

В рамках инициативы по повышению безопасности приложений Microsoft опубликовала ряд документов по этой тематике. Один из самых важных — «Building Secure ASP.NET Applications» — издан Microsoft Press в этом году в виде книги. Вы можете скачать документ (http://msdn.microsoft.com/ library/en-us/dnnetsec/html/secnetipMSDN.asp) или купить книгу — в обоих источниках вы найдете массу полезных сведений обо всех аспектах защиты Web-приложений.

Архитектурный шаблон Очевидно, что автономия — это архитектурный шаблон (architecture pattern). Как и в случае других шаблонов, вашим коллегам должно быть понятно, о чем речь, если вы, будучи архитектором ПО, скажете им: «по-моему, следует проектировать это приложение как автономию». В этом и состоит одно из преимуществ шаблонов: они помогают обсуждать вопросы, связанные с архитектурой и проектированием, на более высоком уровне абстракции, не вдаваясь в ненужные на данном этапе детали.

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

Защита кода и данных Эмиссары Ряд автономий поддерживает UI для предоставляемых ими сервисов.

В таких автономиях может применяться один из шаблонов эмиссаров (emissary patterns) — эмиссар на основе либо Web Forms, либо Windows Forms. Эмиссар действует подобно торговому агенту или торговцу недвижимостью и предоставляет пользователю образец данных, позволяя выбрать один из вариантов. Эмиссар также в курсе большинства принятых в автономии бизнес-правил и может помочь пользователю составить запрос так, что он с большей вероятностью будет выполнен автономией.

Эмиссары также способны сохранять состояние пользовательского сеанса.

Типичный пример — Web-форма ASP.NET, которая сохраняет содержимое корзины покупателя между запросами и тем самым позволяет добавлять в корзину новые товары и хранить уже добавленные, пока не придет время оформления заказа.

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

Как же распределяются обязанности между автономией и ее эмиссарами?

Автономия имеет дело с разделяемыми (общими) данными (shared data).

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

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

Поэтому, переложив больше работы на эмиссаров и тем самым разгрузив автономию, вы заметно повысите масштабируемость приложения. Вспомним Amazon.com. Навигация по сайту, добавление книг и других товаров Архитектура автономного приложения 273 в корзину — все это можно отдать на откуп эмиссарам, а автономию можно задействовать не раньше, чем клиент щелкнет кнопку Submit, чтобы завершить покупку.

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

Проверка соответствия бизнес-правилам Некоторые запросы, поступающие в автономию, требуют сохранения или удаления данных. Автономия ни в коем случае не должна принимать их без тщательной проверки самого запроса на соответствие политикам безопасности, а его содержимого — бизнес-правилам. Именно поэтому реализация бизнес-правил и политик находится в компетенции автономий (по Гелланду), или сервисов (согласно спецификации SOA).

Слабое сопряжение с клиентами Автономия слабо сопряжена (loosely coupled) со своими клиентами. Обычно соединения между клиентом и автономией вовсе нет, пока клиент не инициирует его отправкой сообщения. Автономия обрабатывает сообщение и посылает клиенту ответ, в котором может быть результат запрошенного действия или сообщение об отказе в обслуживании. В любом случае соединение между клиентом и автономией разрывается сразу после ответа автономии — по аналогии с обменом сообщениями в HTTP. Как и в HTTP, соединение можно оставить открытым на весь сеанс, но обычно оно закрывается после одного цикла обмена сообщениями.

Слабое сопряжение очень важно для масштабирования, так как сводит к минимуму время, в течение которого клиент подключен к системе и использует ее ресурсы. Именно этим принципом руководствовались проектировщики службы Microsoft Transaction Services (MTS), которая в дальнейшем эволюционировала в СОМ+ Component Services, а теперь известна как.NET Enterprise Services.

Web-сервисы на основе XML Идеи, на которых базируется SOA, — транспарентность размещения и независимость от платформы и языка программирования, а Web-сервисы — идеальное средство для реализации этих идей. Поскольку Web-сервис публикуют в виде URL, его реальное размещение может изменяться Защита кода и данных произвольным образом, если только его провайдер поддерживает действительную ссылку на этот сервис.

Ну а раз Web-сервисы совершенно не зависят от платформы и языка программирования, для работы с ними клиентам достаточно поддерживать SOAP, XML и один из транспортных протоколов. Обычно это HTTP, но годится и SMTP или любой другой стандартный транспортный протокол Интернета.

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

Внутренние механизмы автономии должны базироваться на концепции слабого сопряжения (loose coupling) с клиентами. Вместо наборов объектов состояний в автономиях следует применять компоненты сервисов, не использующие состояния. По возможности надо передавать и обрабатывать данные в том виде, в каком они поступают от клиентов или отправляются им, т. е. в виде XML-потоков. Этому способствует,NET Framework с ее замечательным XML API для транспорта данных через автономию и для предоставления этих данных клиентам.

Эти API состоят из ADO.NET-объектов, называемых наборами данных XML (XML datasets). Средства ADO.NET для доступа к данным позволяют без труда выполнять выборку информации из произвольного числа таблиц базы данных в XML-набор данных. Такие наборы легко транспортируются между компонентами (и даже между процессами и компьютерами) и в конечном итоге доставляются потребителю. Содержимое XML-набора данных можно рассматривать как XML-документ, который крайне легко передать как ответ Web-сервиса XML. Наконец, хотя набор данных содержит данные в формате XML, использовать синтаксис XML для их чтения и записи вовсе не обязательно. Для доступа к его свойствам можно применять обычный объектно-ориентированный синтаксис вроде TrainerData.Trainers(3).LastName.

Порой против представления би;шес-сущностей в виде XML-наборов данных возражают, приводя примерно такие аргументы:

-«клиенту лучше не знать структуру базы данных». Действительно, было бы весьма опрометчиво позволить XML-набору данных копировать структуру базы данных.

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

Архитектура автономного приложения 275 Проектирование XML-наборов данных в соответствии с их использованием Рассмотрим реализацию компонента View Upcoming Racedays, отвечающего за вывод расписания скачек в приложении, которое мы использовали как пример в предыдущих статьях и книгах. Щелкнув ссылку, пользователь должен получить список предстоящих заездов. Для составления списка используются поля Date, Track, City и Country.

Зная, какие данные потребуются для составления списка, можно спроектировать соответствующий XML-набор данных. Идеальный проект такого объекта показан на рис. 1. Как видите, он состоит из единственной таблицы — RaceDayTable, которая содержит все нужные данные. За исключением RaceDayld все поля таблицы отображаются клиенту (рис. 2), а с помощью поля RaceDayld пользователи могут выбрать интересующий их день скачек и получить дополнительные сведения на отдельной странице.

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

RacedaysData RaceDayTable:DataTable Y ЯасеОауТаЫе RaceDayld:lnteger Date: Date Rac6TrackName:String City Name: String Country Name; String Рис. 1. XML-набор данных

Ради забавы взгляните на хранимую процедуру, которая с помощью SQLкоманды SELECT за один прием выбирает данные из четырех таблиц базы данных в один набор данных:

CREATE PROCEDURE GetFutureRacedays AS SELECT RacingProgramld As RaceDayld, Date, TrackName As RaceTrackName, CityName, CountryName FROM RacingPrograms As RP JOIN RaceTracks As RT ON (RP.RaceTrackld = RT.RaceTrackld) JOIN Cities As Ci ON (RT.Cityld = Ci.Cityld) JOIN Countries As Co ON (Ci.CountryCode = Co.CountryCode) WHERE Date GetDateO ORDER BY RacingProgramld Защита кода и данных

–  –  –

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

–  –  –

Рис. З. Таблицы базы данных Классы сущностей Теперь посмотрим, как разработчики, желающие скрыть от клиента структуру базы данных, проектировали бы свои объекты. Все шансы за то, что они прибегнут к одному из популярных шаблонов для проектирования объектов с поддержкой состояний. Он построен на моделировании проблемной области (domain model). Естественно, эта модель представляет объекты реального мира. В нашем случае это лошади, тренеры, жокеи и скачки.

Кстати, реальным источником данных для проблемной области является база данных. Именно там хранятся структурированные данные. Модель Архитектура автономного приложения 277 базы данных довольно точно представляет проблемную область, значит, это и есть модель проблемной области.

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

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

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

Увязка объектов и таблиц Почему возникает тенденция к такой же нормализации классов сущностей, как и для таблиц базы данных? В основном из-за увязки объектов в памяти и реляционных таблиц. За редким исключением авторы, ратующие за моделирование проблемной области на основе объектов, рекомендуют почти один в один увязывать классы в памяти и таблицы базы данных.

На рис. 4 показан упрощенный пример того, с чем столкнется клиент в такой ситуации. Кроме ключей и классов наборов, объектная модель является точной копией структуры базы данных. Стоит ли говорить, что для заполнения этих четырех объектов потребуется отнюдь не один оператор SELECT? Очевидно и то, что четыре цикла обмена данными с базой займут больше времени, чем один. Наконец, как быть с главной целью — изолировать клиент от структуры базы данных?

–  –  –

Из сказанного должно быть ясно, что предоставление клиентским приложениям XML-наборов данных — далеко не то же самое, что их привязка к базе данных. Более того, это прямо противоположные вещи! Однако нужно хорошо знать XML-наборы данных, чтобы в полной мере воспользоваться их преимуществами. Определяя XSD-схемы, исходите исключительно из структуры запросов, а о структуре базы данных можно вообще забыть.

Все это особенно важно для приложений, ориентированных на сервисы, — по крайней мере, для приложений, предоставляющих Web-сервисы. Такие приложения поддерживают программные интерфейсы, возвращающие клиентам XML-потоки или XML-документы. Структура XML-документа определяется XSD-схемой, то же верно для XML-набора данных, который фактически является XML-документом.

XML-наборы данных никогда не подключаются к базам данных Возможно, не все еще знают, что XML-набор данных (Dataset) никогда не подключается к базе данных — он просто не может этого. Для передачи данных между XML-набором данных и базой данных нужен какой-нибудь прокси, сопоставляющий таблицы набора данных с реляционными таблицами. Такой объект предоставляет ADO.NET, причем в нескольких версиях, ориентированных на разные СУБД. Называется он адаптером данных (data adapter) и применяется только для обмена информацией между источниками и наборами данных. Сам Dataset не имеет ни малейшего представления ни о базе данных, ни об операторах SQL, заполняющих его или передающих данные в источник.

В чем же причина путаницы? Почему многие уверены, что применение Dataset непременно ведет к зависимости от базы данных? Дело, наверное, в том, что XML-объект Dataset в каком-то смысле является заменой прежних наборов записей (объектов Recordset), применявшихся в классическом ADO, Remote Data Objects (RDO) и Data Access Objects (DAO).

В каждой из этих моделей Recordset напрямую подключался к источнику данных, например к реляционной базе данных. Единственное исключение — ADO-объект Recordset, который умел отсоединяться от базы данных, а затем вновь подключаться к ней.

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

Архитектура автономного приложения 279 Заключение Принимаясь за новый проект, подумайте о том, чтобы спроектировать приложение как автономию. Если у него будет UI, как и у большинства других приложений, попробуйте реализовать его в виде набора эмиссаров, переложив на них как можно больше работы. Эмиссары должны обращаться к автономии только при крайней необходимости. Например, они должны самостоятельно кэшировать эталонные данные (образцы данных) и поддерживать состояние сеансов. Такие приложения масштабируются лучше, чем приложения, постоянно работающие с серверными ресурсами, например с разделяемыми данными.

Эта стратегия поможет спроектировать автономию на базе компонентов, не использующих состояния, что обеспечит высокую масштабируемость и позволит максимально упростить приложение. Но иногда без компонентов, поддерживающих состояния, все же не обойтись. XML-объект Dataset в ADO.NET — прекрасная кандидатура на роль транспортера данных в большинстве приложений. В сочетании с адаптерами данных объекты Dataset великолепно работают с базами данных. XML-наборы данных полностью основаны на XML и без проблем пересекают границы между процессами и компьютерами. Они рассчитаны на поддержку связывания данных (data binding) — механизма, который во многих случаях предпочтителен для отображения данных на формах Web Forms и Windows Forms.

Если вы хотите подробнее изучить архитектурные шаблоны Пэта Гелланда и его концепции автономий и эмиссаров, послушайте его выступление по ссылке http://www.microsoft.com/usa/Webcasts/ondemand/892.asp вы не зря потратите свое время.

Стэн Зундблат (Sten Sundblad) и Пер Зундблат (Per Sundblad) — совладельцы шведской компании Sundblad & Sundblad ADB-Arkitektur, которая занимается разработками для.NET и специализируется на архитектуре и проектировании ПО. Стэн и Пер — авторы книг «Designing for Scalability with Microsoft Windows DNA» (Microsoft Press, 2000) и «Design Patterns for Scalable Microsoft.NET Applications-. (Sundblad & Sundblad, 2002). Подробнее об их деятельности можно узнать на сайте http://www.2xSundblad.com.

С ними можно связаться по адресам stens@2xSundblad.com и pers@2xSundblad.com соответственно.

Михаил Коготков-Лизин Защищенный вход Средства безопасной аутентификации через Microsoft.NET Passport Защищенный вход (secure sign-in) — новая функциональность в.NET Passport версии 2.0, службе единого входа и создания профилей (single sign-in and profile service). Эта функциональность особенно полезна для сайтов, содержащих конфиденциальную информацию, и везде, где безопасность имеет первостепенное значение, в том числе для сайтов банков, медицинских сайтов и т. д. Защищенный вход не менее безопасен, чем современная SSL-технология входа на Web-сайты, и практически полностью исключает возможность атак с повторением пакетов (replay attacks) и по словарю (dictionary attacks). В этой статье поясняется концепция защищенного входа и демонстрируется, как с минимальными усилиями реализовать его либо в ASP с использованием СОМ-объекта Passport.Manager, либо в ASP.NET на основе.NET-класса Passportfdentity.

Microsoft.NET Passport — это система единого унифицированного входа для навигации по сайтам, поддерживающим Passport, без необходимости отдельной регистрации на каждом из них. Такая функциональность стала популярной, поскольку экономит время и усилия при посещении сайтов, включенных в систему Passport.

Защищенный вход — функция Passport, которая обеспечивает более высокую безопасность по сравнению со стандартным входом. Это особенно важно для банков, брокерских контор, медицинских сайтов и других организаПубликовалось в MSDN Magazine/Русская Редакция. 2002. № 3 (сентябрь). — Прим. изд.

Средства безопасной аутентификации через Microsoft.NET Passport 281 ций, где хранятся конфиденциальные данные пользователей. Защищенный вход через Passport так же безопасен, как и любые SSL-технологии (Secure Sockets Layer) входа, применяемые на Web-сайтах в настоящее время.

Фактически реализация защищенного входа требует применения SSL, специальных параметров для функций входа через Passport и браузера с поддержкой HTTPS (этот протокол поддерживается почти всеми современными браузерами). Разработка сайта с поддержкой защищенного входа не сложнее, чем обычного сайта, — вам понадобится написать всего несколько дополнительных строк кода.

В этой статье я сравню разные подходы к регистрации на входе и опишу операции, нужные для поддержки защищенного входа на сайт. Я рассмотрю защищенный вход сквозь призму двух парадигм программирования, одна из которых основана на СОМ-объекте Passport.Manager, а другая на объекте Passport Identity, предоставляемом Microsoft.NET Framework.

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

Стандартный и защищенный вход Как уже говорилось, у стандартного входа через Passport и других механизмов проверки есть ряд общих проблем с безопасностью. Во-первых, уязвимость перед лобовыми атаками, при которых подбираются подходящие учетные данные. Чтобы уменьшить уязвимость перед атаками такого рода, на серверах входа для.NET Passport реализован механизм замедления (slow-down), отбивающий охоту к атакам с подбором паролей в попытке угадать верный. После пяти подряд неудачных попыток входа пользователя просят подождать пять минут. Это не блокирует пользователя, но ставит серьезную преграду на пути у злоумышленников, пытающихся получить доступ к какой-нибудь учетной записи.

Повторение пакетов — другой тип атаки, при которой перехватывается транзакция входа по открытому HTTP-соединению. В настоящее время служба Passport уязвима перед атаками с повторением пакетов даже несмотря на шифрование билета (ticket) и профиля, так как обмен ими осуществляется через открытое HTTP-соединение. Перехватив соответствующие пакеты и повторив их, хакер может подменить пользователя на тот период, пока не истечет срок действия его билета регистрации (login ticket).

С другой стороны, учетные данные (адрес электронной почты и пароль) передаются в доменный центр Passport (Passport domain authority) no HTTPS — так что они надежно защищены.

282 Защита кода и данных Чтобы избежать автоматической повторной аутентификации (silent reauthentication), сайты — участники системы Passport (далее — просто сайты-участники) м:огут требовать от пользователя заново вводить свое регистрационное имя и пароль независимо от текущего состояния аутентификации этого пользователя. Заставляя его повторно вводить свои учетные данные, сайт по сути запрещает доступ любому, кто не знает соответствующего имени и пароля.



Pages:     | 1 |   ...   | 2 | 3 || 5 |



Похожие работы:

«ГАЗЕТА РОССИЙСКОГО ПРОФЕССИОНАЛЬНОГО СОЮЗА ЛОКОМОТИВНЫХ БРИГАД ЖЕЛЕЗНОДОРОЖНИКОВ Выпуск № 8 (88) Август 2006 г. Решением мирового судьи судебного участка № 382 г. Москвы Чубаровой Н.В. удовлетворенны исковые требования членов Профсоюза РПЛБЖ – работников депо Москва-3 и Пушкино...»

«Ключевые рынки. Дневной фокус 5 декабря 2013 ИЗМЕНЕНИЯ НА КЛЮЧЕВЫХ РЫНКАХ Американские акции вчера снизились на 0,1% по индексу S&P500. При этом российские акции также продолжили падать, но более ощутимо. Индекс Р...»

«70 300 l ru инструкция 25-03-2016 1 Выплачивавший глянул, потом блицкриг прядения будет завивать. Обременительно дошедшая инкассация приступает встраивать. Букет не запрашивается. Иератические сильфоны будут высвобождать. Втридорога вмонтировавшая на...»

«”ЗАРЕГИСТРИРОВАН” “УТВЕРЖДЕНО” Регистрационно-лицензионная Общим собранием акционеров палата Мэрии г. Ярославля ОАО "Яргазсервис 27 июня 2002 Протокол № 1 Рег. номер 943-877 от 23 мая 2002 г. Председатель В.А. Гублев УСТАВ Открытого акционерного общества "Яргазсервис" (Новая редакц...»

«А.Ф. КОСТИН ВОСХОЖДЕНИЕ Страницы биографии молодого ЛЕНИНА Издание второе, дополненное Москва Издательство политической литературы шо К72 0103020000—192 К 079(02)—86 5 1 -8 6 © ПОЛИТИЗДАТ, 1986 г. Введение Мир знает Ленина и высоко ценит его вели­ чайшие заслуги перед человечеством. И это закономерно, ибо...»

«ЕВРАЗИЙСКИЙ ИНТЕГРАЦИОННЫЙ ПРОЕКТ: ЭФФЕКТЫ И ПРОБЛЕМЫ РЕАЛИЗАЦИИ Позиция ИЭ РАН АКТУАЛЬНОСТЬ ТЕМЫ • Чрезвычайно актуальной тему делает одобренная руководством стран ТС/ЕЭП задача перехода к более высокой стадии интеграции в 2015 г....»

«Программа школы-семинара "Волны-2017" Воскресенье Понедельник Вторник Среда Четверг Пятница Время Время 4 июня 5 июня 6 июня 7 июня 8 июня 9 июня 9.00 Регистрация Завтрак 9.00 10.00 10.00 Зал А Зал А Зал А Зал А Секция Секция Секция Секция Акусти...»

«ISSN: 2158-7051 ==================== INTERNATIONAL JOURNAL OF RUSSIAN STUDIES ==================== ISSUE NO. 2 ( 2013/1 ) ФУНКЦИЯ ЦВЕТА В ЛИРИЧЕСКИХ ТЕКСТАХ ДАВИДА САМОЙЛОВА НАТАЛЬЯ КОНОНОВА* Summary The article is devoted to the analysis of the meaning of colours in the D. Samoilow’s poetry. The goal of this research is to reveal and compare the seman...»

«ФГБОУ ВО "Марийский государственный университет" УТВЕРЖДАЮ ректор ФГБОУ ВО "Марийский государственный университет" _ М.Н. Швецов " " _ 2016 г. ПОЛИТИКА безопасности персональных данных, обрабатываемых в информацион...»

«УДК 550.388 М.В. ЛЯШЕНКО, канд. физ.-мат. наук, учёный секретарь, Институт ионосферы, Харьков ЗОНАЛЬНОЕ ЭЛЕКТРИЧЕСКОЕ ПОЛЕ И ПЕРЕНОС ПЛАЗМЫ ЗА СЧЕТ ЭЛЕКТРОМАГНИТНОГО ДРЕЙФА ВО ВРЕМЯ МАГНИТНОЙ БУРИ 5 – 6 АВГУСТА 2011...»

«Д О Г О В О Р №А-/_ на оказание услуг по обеспечению судоходства и пребывания судна(ов) в морских портах г. Санкт-Петербург " " _ 201г. Федеральное государственное унитарное предприятие "Росморпорт", именуемое в дальнейшем "Предприятие", в лице директора Северо-Западного ба...»

«Муратов Жанибек Кудайбакович канд. мед. наук, доцент Ошский государственный университет г. Ош, Кыргызстан ВЛИЯНИЕ ВЫСОКОГОРНЫХ ФАКТОРОВ НА ОРГАНИЗМ ЧЕЛОВЕКА Аннотация: автор статьи рассматривает различными факторами окружающей среды, при помощи которы...»

«Электронный журнал "Труды МАИ". Выпуск № 36 www.mai.ru/science/trudy/ УДК 504.054:629.78(03) Использование данных космического мониторинга для оценки рисков воздействия космодромов на окружающую природную сре...»

«УДК 629.424.3:621.436 А. А. Беляев, В. Т. Данковцев, В. А. Четвергов УПРАВЛЕНИЕ ДАВЛЕНИЕМ ВПРЫСКА ТОПЛИВА В ЦИЛИНДРЫ ТЕПЛОВОЗНЫХ ДИЗЕЛЕЙ В ЗАВИСИМОСТИ ОТ РЕЖИМОВ РАБОТЫ В статье предложено новое конструктивное решение, улучшающее количественные и ка...»

«С НАМИ НАДЕЖНЕЕ! Страховое общество РЕСО-Гарантия Октябрь 2016 Руководство компании Сергей Саркисов Николай Саркисов Президент Вице-президент Дмитрий Раковщик Игорь Черкашин Генеральный директор Первый заместитель Генерального директора Страховое публичное акционерное обще...»

«ИНСТРУКЦИЯ ПО МОНТАЖУ ПАНЕЛЬНЫХ ОГРАЖДЕНИЙ Содержание 1 Введение 1 Описание 2 Транспортирование и хранение 2 Техника безопасности 2 Инструмент 3 Подготовительные работы 3 Монтаж ограждения 3 Разметка межосевых размеров для столбов 4 Фундамент 4 Монтаж сто...»

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

«Мультиварка-скороварка RMC-PM330 АНТИ АР Г Я М В ЕС ЯЦЕ Руководство по эксплуатации RUS UKR KAZ UZB ROU LTU LVA EST A1 A2 / A3 C / УВАЖАЕМЫЙ ПОКУПАТЕЛЬ! Благодарим за то, что вы отдали предпочтение бытовой технике REDMOND. REDMOND — это качество, надежнос...»

«ДЕЛО № 13 (Решение от 27 июня 2007 года) 1. Рассмотрев заявление ответчика о нарушении истцом порядка досудебного урегулирования спора, состав Арбитражного суда признал его несостоятельным поскольку, контра...»

«Центральная избирательная комиссия Российской Федерации Российский центр обучения избирательным технологиям при Центральной избирательной комиссии Российской Федерации Выборы депутатов Государственной Думы Федер...»

«Новая коллекция 2012 года! Lexus Trike Original NEXT 2012 Lexus trike original NEXT 2012 bronza Капюшон bronza Lexus trike original NEXT 2012 bronza Один из самых узнаваемых в России велосипедов – Lexus trike original от RICH TOYS представляет новинки сезона 2012. Создавая совершенно новую моде...»

«Список опубликованных работ Дорохович Г.П. Формирование гонад в эмбриогенезе белой крысы и собаки // 1. структурная организация органов и регулирующих систем организма в норме, патологии и эксперименте. Заключительный отчет по 1 этапу № гос...»

«"Ноль сомнений" Расценки на услуги в сети Билайн для тарифного плана "Ноль сомнений" при подключении в Москве и Московской обл. (далее именуется "домашней сетью") Услуги, подключаемые по умолчанию: местная, междугородная, международная связь, прием/передача SMS,...»

«Документы Нового Завета: достоверны ли они? Брюс Фредерик Брюс Фредерик Оглавление Предисловие к пятому изданию Глава 1. Так ли это важно? Глава 2. Датировка и свидетельства в пользу истинности документо...»

«средства защиты и спасения на пожаре и ЧС Каталог продукции Информация о производителе и поставщике Группа компаний: 109316, г. Москва,ул.Сосинская, д.43, стр.8 Многоканальный телефон: +7 (495) 540-50-37 Тел.: +7 (495) 676-58-66, +7(495) 676-99-26 Факс-автомат: +7 (495) 729 46 08 E-mail: Shans@npk-phz.ru www.npk-p...»

«Муниципальное бюджетное общеобразовательное учреждение "Крупецкая средняя общеобразовательная школа" Рыльского района Курской области Основная образовательная программа для 1-4 классов ( 2014 / 2015 учебный год) д. Рыжевка, 2014 г Содержание Стр.1. Информационная справка о школе 2-3 2. Целевой раздел: 4-6...»

«АДМИНИСТРАЦИЯ ЗАРЕЧНОГО СЕЛЬСОВЕТА ТОГУЧИНСКОГО РАЙОНА НОВОСИБИРСКОЙ ОБЛАСТИ ПОСТАНОВЛЕНИЕ 01.09.2016 № 74 с. Заречное Об утверждении муниципальной программы "Военно-патриотическое воспитание детей и...»

«A3 Audi A3 | A3 Sportback Audi S3 Audi Vorsprung durch Technik Страница Восхищение 4 Audi A3/Audi A3 Sportback 30 Audi S3 Технологии 44 Audi connect 56 S tronic® 46 MMI® — мультимедийный интерфейс 58 quattro® 48 Эффективность Audi 60 Подвеск...»

«"Мал животно, подобен козляти": Единорог в древнерусской литературе и миниатюре Из всех мифических животных эпохи Средневековья особой популярностью пользовался единорог. Его изображения встречаются еще в Древней Индии, античные тракта...»








 
2017 www.book.lib-i.ru - «Бесплатная электронная библиотека - электронные ресурсы»

Материалы этого сайта размещены для ознакомления, все права принадлежат их авторам.
Если Вы не согласны с тем, что Ваш материал размещён на этом сайте, пожалуйста, напишите нам, мы в течении 1-2 рабочих дней удалим его.