Прикладная теория Application Security

Preview:

Citation preview

Прикладная теория Application Security

Владимир Кочетков/Positive Technologies/Application Inspector/Team Lead

Образовательная программа «Практическая безопасность»

3

AgendaЧто?

Теоретический минимум, необходимый для осознанной разработки или анализа защищенности кода

Зачем?

Перестать следовать культу карго

4

Главный вопрос Жизни, Вселенной и всего остального…

5

…что такое "уязвимость"?

6

Что такое "уязвимость"?«Недостаток (слабость) программного (программно-технического) обеспечения средства или информационной системы в целом, который (которая) может быть использована для реализации угроз безопасности информации» - ГОСТ Р 56546-2015

7

Что такое "уязвимость"?«Недостаток (слабость) программного (программно-технического) обеспечения средства или информационной системы в целом, который (которая) может быть использована для реализации угроз безопасности информации» - ГОСТ Р 56546-2015 «В чем сила, брат?» (с)

8

Что такое "уязвимость"?«Недостаток (слабость) программного (программно-технического) обеспечения средства или информационной системы в целом, который (которая) может быть использована для реализации угроз безопасности информации» - ГОСТ Р 56546-2015 «В чем сила, брат?» (с)

«Набор входных данных, приводящий машину Тьюринга в запрещенную конфигурацию» - Computer Science

9

Что такое "уязвимость"?«Недостаток (слабость) программного (программно-технического) обеспечения средства или информационной системы в целом, который (которая) может быть использована для реализации угроз безопасности информации» - ГОСТ Р 56546-2015 «В чем сила, брат?» (с)

«Набор входных данных, приводящий машину Тьюринга в запрещенную конфигурацию» - Computer Science

10

Существующие определения не дают ни малейшего представления о технической сущности уязвимости

11

Правильный вопрос: в чем разница между защищенным и уязвимым кодом?

12

Что такое "уязвимость"?var cmd = new SqlCommand("SELECT Value FROM Discounts WHERE CouponCode LIKE '" + Request["CouponCode"] + "'");var connection = new SqlConnection(connectionString);connection.Open();cmd.Connection = connection;var couponValue = cmd.ExecuteScalar();...

13

Что такое "уязвимость"?var cmd = new SqlCommand("SELECT Value FROM Discounts WHERE CouponCode LIKE '" + Request["CouponCode"] + "'");var connection = new SqlConnection(connectionString);connection.Open();cmd.Connection = connection;var couponValue = cmd.ExecuteScalar();...

Атакующий имеет возможность нарушить целостность выходного потока данных (кода SQL-запроса), манипулируя потоком входных данных (параметром HTTP-запроса), приходящим в операцию выполнения SQL-кода.

14

Что такое "уязвимость"?var cmd = new SqlCommand("SELECT Value FROM Discounts WHERE CouponCode LIKE @CouponCode");cmd.Parameters.AddWithValue("@CouponCode ", Request["CouponCode"]);var connection = new SqlConnection(connectionString);connection.Open();cmd.Connection = connection;var couponValue = cmd.ExecuteScalar();...

15

Что такое "уязвимость"?var cmd = new SqlCommand("SELECT Value FROM Discounts WHERE CouponCode = @CouponCode");cmd.Parameters.AddWithValue("@CouponCode ", Request["CouponCode"]);var connection = new SqlConnection(connectionString);connection.Open();cmd.Connection = connection;var couponValue = cmd.ExecuteScalar();...

Атакующий имеет возможность нарушить целостность выходного потока данных (параметра SQL-запроса), манипулируя потоком входных данных (параметром HTTP-запроса), приходящим в операцию выполнения SQL-кода, что может привести к нарушению правил предметной области приложения.

16

Что такое "уязвимость"?1)

[Authorize(Roles = "All")]public ActionResult SomeAction(){ ... return View();}

2)

[Authorize(Roles = "Baz, Qux")]public ActionResult SomeAction(){ ... return View();}

17

Что такое "уязвимость"?1)

[Authorize(Roles = "All")]public ActionResult SomeAction(){ ... return View();}

2)

[Authorize(Roles = "Baz, Qux")]public ActionResult SomeAction(){ ... return View();}

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

18

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

Примеры предметных областейВторичные:

― защищенность;― отказоустойчивость;― опыт взаимодействия,― производительность.

Основные:

― интернет-торговля;― онлайн-банкинг;― бухучет;― … (тысячи их).

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

20

Application Security – вторичная предметная область

21

Предметная область Application Security

22

Сущность– абстракция реального объекта в некотором контексте, обладающая следующими характеристиками:

• свойство – значимый атрибут абстрагируемого сущностью объекта или одноместное отношение;

• состояние– множество текущих значений всех свойств сущности;

• инвариант– множество допустимых состояний сущности.

Отношение – утверждение, определяющее взаимосвязь изменения состояний сущностей.

23

Предметная область – множество сущностей, их инварианты и отношения

24

Пример: логистикаСущность: точки на карте города

• свойство: координаты – пара значений «широта-долгота»;• инвариант: координаты принадлежат перекресткам города или

строениям.

Сущность: маршрут• свойство: путь - упорядоченное множество точек на карте города;• инвариант: путь непрерывен и проходит по улицам города в

соответствии с ПДД;• отношение: оптимальность – длина пути минимальна для одних и

тех же начальной и конечной точек.

Сущности: точка загрузки, точка доставки• свойство: точка на карте города

25

Задача коммивояжёраВ терминах предметной области логистики:

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

26

Задача коммивояжёраВ терминах предметной области логистики:

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

В терминах предметной области теории графов:

Найти гамильтонов цикл минимального веса в полном (дополненном ребрами бесконечной длины) взвешенном графе.

27

Предметная область Application Security

28

«Трясина Тьюринга» - не только об эзотерических языках

"Modeling Computer Insecurity" (Sophie Engle, Sean Whalen and Matt Bishop):

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

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

Вычислимость проблемы защищенности

Статическая оценка защищенности программы является неразрешимой проблемой.

Определение защищенности текущего состояния программы, очевидно, разрешимо

30

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

31

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

32

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

33

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

34

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

35

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

36

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

37

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

38

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

39

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

40

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

41

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

42

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

43

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

44

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

45

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

46

Потоки управленияvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

47

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

48

Потоки данныхvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

49

Потоки данныхvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

50

Потоки данныхvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

51

Потоки данныхvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

52

Потоки данныхvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

53

Потоки данныхvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

54

Потоки данныхvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

55

Потоки данныхvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

56

Потоки данныхvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

57

Потоки данныхvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

58

Потоки данныхvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

string str1;if (name + "in" == "admin"){ if (key1 == "validkey") { str1 = Encoding.UTF8.GetString(data); } else { str1 = "Wrong key!"; }

Response.Write(str1);}

str1 ∈ {Encoding.UTF8.GetString(Convert.FromBse64String(Request.Params["parm"])),"Wrong Key!"}

59

Множества значений всех потоков данных в конкретной точке потока выполнения определяют состояние приложения

60

Граф переходов между состояниями приложения определяет все возможные потоки вычисления

61

Граф потоков вычисления является семантически-эквивалентной моделью приложения

62

Предметная область Application Security

63

Театр начинается с вешалки, а уязвимость – с недостатка

64

Недостаток- неэффективная реализация моделей предметных областей приложения и контролей инвариантов их сущностей

Примеры контролей Application Security:

• предварительная обработка потоков данных;• подтверждение аутентичности потоков вычисления;• проверка прав доступа к потокам данных;• обеспечение соответствия потока вычисления модели

функциональной предметной области;• …

65

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

• конфиденциальности;• целостности;• доступности;• авторизованности;• аутентичности;• аппелируемости;• подотчетности;• достоверности;• <нужное вписать>

66

КонфиденциальностьСостояние потока вычисления, при котором доступ к нему осуществлен только сущностями, имеющими на это право.

A

E

B

67

ЦелостностьСостояние потока вычисления, при котором изменения в нем осуществлены только сущностями, имеющими на это право.

A

E

B

C

68

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

A B

69

АвторизованностьСостояние потока вычисления, при котором его источниками являются только сущности, имеющие на это право.

E

B

A

70

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

‘A’

B

A

71

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

A B

72

Уязвимость – состояние приложения, в котором возможна реализация угрозы

73

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

* …пересекающего границу доверия

74

Уязвимость бизнес-логики–состояние реализации угрозы через нарушение правил основной предметной области приложения

75

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

То, где и благодаря чему он может это сделать, называется уязвимостью (vulnerability), обусловленной недостатком (weakness)

То, как он может это сделать, называется атакой (attack)

То, с какой вероятностью у него это удастся и какие последствия может повлечь, называется риском (risk)

Иными словами…

76

То, что не позволяет атакующему провести атаку, обеспечивает защищенность (security)

77

То, что минимизирует риск, обеспечивает безопасность (safety)

78

Акцентировать внимание разработчикам и пентестерам необходимо на причинах*, а не на следствиях**!

* недостатки** уязвимости, атаки или риски

79

Причинно-следственные связи

Недостаток Угроза

Уязвимость Атака

Риск

Незащищенность

Небезопасность

80

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

Анализ защищенности кода сводится к оценке эффективности реализованных контролей

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

КлассификацияКлассификация уязвимостей возможна по:

― предметной области; // защищенность приложения― недостатку; // неэффективная предварительная

обработка потоков данных― потоку вычисления; // формирующие первообразные

потоков выполнения― угрозе; // нарушение целостности

// уязвимость к атакам инъекций (в зависимости от интерпретатора потока данных: XSS, SQLi, XMLi, XPATHi, Path Traversal, LINQi, XXE и т.п.)

КлассификацияКлассификация уязвимостей возможна по:

― предметной области; // защищенность приложения― недостатку; // неэффективное подтверждение

аутентичности источника потока вычисления― потоку вычисления; // HTTP-запрос, приводящий к

изменению состояния приложения― угрозе; // нарушение аутентичности

// уязвимость к атакам CSRF

КлассификацияКлассификация уязвимостей возможна по:

― предметной области; // онлайн-торговля― недостатку; // неэффективный контроль

использования погашенных купонов на скидку― потоку вычисления; // транзакция оплаты заказа― угрозе; // нарушение авторизованности

// уязвимость к атакам на бизнес-логику (повторное использование погашенных купонов)

84

Что будет, если поиграть в алхимию с критериями классификации?

85

Вопросы?

Владимир Кочетков

vkochetkov@ptsecurity.com@kochetkov_v

/Positive Technologies/Application Security/Application Inspector/Compiling and Low-Level Applications Analysis/Team Lead

Recommended