127

Философия Application Security

Embed Size (px)

Citation preview

Page 1: Философия Application Security
Page 2: Философия Application Security

Философия Application Security

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

CodeFreeze в Москве, 28.04.2016

Page 3: Философия Application Security

3

:~$ whoami && whonotme• .NET-разработчик, руководитель группы разработки

анализаторов компилируемых приложений в Positive Technologies

• Участник Positive Development User Group

• Исследователь в области защищенности приложений

• Участник RSDN

• Оторванный от реальности теоретик

• Упоротый параноик

Page 4: Философия Application Security

4

Ништяки

Page 5: Философия Application Security

5

WTF “AppSec”?Application Security – предметная область обеспечения защищенности приложений на этапах:

― проектирования;

― разработки;

― развертывания;

― эксплуатации;

Page 6: Философия Application Security

6

WTF “AppSec”?Application Security – предметная область обеспечения защищенности приложений на этапах:

― проектирования;

― разработки;

― развертывания;

― эксплуатации;

сегодняшняя тема

Page 7: Философия Application Security

7

Agenda (чего НЕ будет)

Page 8: Философия Application Security

8

Вопрос: почему квалифицированные разработчики допускают уязвимости?

Page 9: Философия Application Security

9

Причины разработки уязвимого кода

― Низкая квалификация

― Человеческий фактор

― Отсутствие системного подхода

― Шаблонное мышление

Page 10: Философия Application Security

10

AgendaЧто?

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

разбор известных уязвимостей.

Зачем?Перестать следовать культу карго и шаблонному подходу к вопросам обеспечения защищенности.

Page 11: Философия Application Security

11

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

Page 12: Философия Application Security

12

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

Page 13: Философия Application Security

13

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

Page 14: Философия Application Security

14

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

Page 15: Философия Application Security

15

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

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

Page 16: Философия Application Security

16

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

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

Page 17: Философия Application Security

17

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

Page 18: Философия Application Security

18

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

Page 19: Философия Application Security

19

Внимание, белый ящик!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();...

Page 20: Философия Application Security

20

Внимание, белый ящик!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-кода.

Page 21: Философия Application Security

21

Шаблон: чтобы избежать уязвимости к SQL-инъекции необходимо использовать параметризацию запросов

Page 22: Философия Application Security

22

Внимание, белый ящик!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();...

Page 23: Философия Application Security

23

Внимание, белый ящик!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();...

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

Page 24: Философия Application Security

24

Внимание, белый ящик!var fieldName = Request["field"] ?? "Id"; var minValue = int.Parse(Request["min"] ?? "0"); var maxValue = int.Parse(Request["max"] ?? "0");

var queryTemplate = string.Format( "SELECT Id, Nickname, Rating, MessageCount, TopicCount FROM Users WHERE {0} >= @minValue AND {0} <= @maxValue ORDER BY {0}", fieldName.Replace("'", string.Empty). Replace(" ", string.Empty). Replace("\\", string.Empty). Replace(",", string.Empty). Replace("(", string.Empty). Replace(")", string.Empty),);

var selectCommand = string.Format(queryTemplate, debugStr);

var cmd = new SqlCommand(selectCommand, dataConnection);

cmd.Parameters.Add(new SqlParameter("@minValue", minValue));cmd.Parameters.Add(new SqlParameter("@maxValue", maxValue));

/users/filter.aspx?field={fieldName}&min={minBalue}&max={maxValue}

Users

Id

Nickname

Rating

MessageCount

TopicCountPassword

Page 25: Философия Application Security

25

Внимание, белый ящик!var fieldName = Request["field"] ?? "Id"; var minValue = int.Parse(Request["min"] ?? "0"); var maxValue = int.Parse(Request["max"] ?? "0");

var queryTemplate = string.Format( "SELECT Id, Nickname, Rating, MessageCount, TopicCount FROM Users WHERE {0} >= @minValue AND {0} <= @maxValue ORDER BY {0}", fieldName.Replace("'", string.Empty). Replace(" ", string.Empty). Replace("\\", string.Empty). Replace(",", string.Empty). Replace("(", string.Empty). Replace(")", string.Empty),);

var selectCommand = string.Format(queryTemplate, debugStr);

var cmd = new SqlCommand(selectCommand, dataConnection);

cmd.Parameters.Add(new SqlParameter("@minValue", minValue));cmd.Parameters.Add(new SqlParameter("@maxValue", maxValue));

/users/filter.aspx?field=password&min=a&max=a

Users

Id

Nickname

Rating

MessageCount

TopicCountPassword

Page 26: Философия Application Security

26

Внимание, белый ящик!var fieldName = Request["field"] ?? "Id"; var minValue = int.Parse(Request["min"] ?? "0"); var maxValue = int.Parse(Request["max"] ?? "0");

var queryTemplate = string.Format( "SELECT Id, Nickname, Rating, MessageCount, TopicCount FROM Users WHERE {0} >= @minValue AND {0} <= @maxValue ORDER BY {0}", fieldName.Replace("'", string.Empty). Replace(" ", string.Empty). Replace("\\", string.Empty). Replace(",", string.Empty). Replace("(", string.Empty). Replace(")", string.Empty),);

var selectCommand = string.Format(queryTemplate, debugStr);

var cmd = new SqlCommand(selectCommand, dataConnection);

cmd.Parameters.Add(new SqlParameter("@minValue", minValue));cmd.Parameters.Add(new SqlParameter("@maxValue", maxValue));

/users/filter.aspx?field=password&min=a&max=a

Users

Id

Nickname

Rating

MessageCount

TopicCountPassword

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

Page 27: Философия Application Security

27

Какой из фрагментов кода уязвим?1)

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

2)

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

Page 28: Философия Application Security

28

Какой из фрагментов кода уязвим?1)

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

2)

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

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

Page 29: Философия Application Security

29

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

Page 30: Философия Application Security

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

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

Основные:

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

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

Page 31: Философия Application Security

31

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

Page 32: Философия Application Security

32

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

Page 33: Философия Application Security

33

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

Page 34: Философия Application Security

34

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

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

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

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

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

Page 35: Философия Application Security

35

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

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

строениям.

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

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

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

Сущности: точка загрузки, точка доставки• свойство: точка на карте города;• инвариант: координаты принадлежат строениям.

Page 36: Философия Application Security

36

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

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

Page 37: Философия Application Security

37

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

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

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

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

Page 38: Философия Application Security

38

goto fail;

Page 39: Философия Application Security

39

Место действия: SSL/TLS библиотека SecureTransport -> sslKeyExchange.c

Page 40: Философия Application Security

40

Процесс согласования соединения SSL/TLSSSLProcessHandshakeRecord() -> SSLProcessHandshakeMessage() -> SSLProcessClientHello() -> SSLProcessServerHello() -> SSLProcessCertificate() -> SSLProcessServerKeyExchange() -> SSLDecodeSignedServerKeyExchange() -> SSLDecodeXXKeyParams() IF TLS 1.2 -> SSLVerifySignedServerKeyExchangeTls12() OTHERWISE -> SSLVerifySignedServerKeyExchange()

Page 41: Философия Application Security

41

sslKeyExchange.c:SSLVerifySignedServerKeyExchange. . .hashOut.data = hashes + SSL_MD5_DIGEST_LEN;hashOut.length = SSL_SHA1_DIGEST_LEN;if ((err = SSLFreeBuffer(&hashCtx)) != 0) goto fail;if ((err = ReadyHash(&SSLHashSHA1, &hashCtx)) != 0) goto fail;if ((err = SSLHashSHA1.update(&hashCtx, &clientRandom)) != 0) goto fail;if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0) goto fail;if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0) goto fail; goto fail;if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0) goto fail;

err = sslRawVerify(...);. . .fail:. . .

Page 42: Философия Application Security

42

Лишний безусловный переход на метку `fail` приводил к нарушению правил предметной области протокола SSL/TLS

Page 43: Философия Application Security

43

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

Page 44: Философия Application Security

44

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

Page 45: Философия Application Security

45

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

Page 46: Философия Application Security

46

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

Page 47: Философия Application Security

47

Потоки управления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);}

Page 48: Философия Application Security

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);}

Page 49: Философия Application Security

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);}

Page 50: Философия Application Security

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);}

Page 51: Философия Application Security

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);}

Page 52: Философия Application Security

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);}

Page 53: Философия Application Security

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);}

Page 54: Философия Application Security

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);}

Page 55: Философия Application Security

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);}

Page 56: Философия Application Security

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);}

Page 57: Философия Application Security

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);}

Page 58: Философия Application Security

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);}

Page 59: Философия Application Security

59

Потоки управления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);}

Page 60: Философия Application Security

60

Потоки управления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);}

Page 61: Философия Application Security

61

Потоки управления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);}

Page 62: Философия Application Security

62

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

Page 63: Философия Application Security

63

Heartbleed

Page 64: Философия Application Security

64

Место действия: библиотека OpenSSL -> ssl/t1_lib.c -> tls1_process_heartbeat()

Page 65: Философия Application Security

65

tls1_process_heartbeat()3972 /* Read type and payload length first */3973 hbtype = *p++;3974 n2s(p, payload);3975 pl = p;. . .3984 unsigned char *buffer, *bp;3985 int r;3986 3987 /* Allocate memory for the response, size is 1 bytes3988 * message type, plus 2 bytes payload length, plus3989 * payload, plus padding3990 */3991 buffer = OPENSSL_malloc(1 + 2 + payload + padding);3992 bp = buffer;. . .3994 /* Enter response type, length and copy payload */3995 *bp++ = TLS1_HB_RESPONSE;3996 s2n(payload, bp);3997 memcpy(bp, pl, payload);

Page 66: Философия Application Security

66

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

Page 67: Философия Application Security

67

…, включая в него содержимое до 64Kb кучи SSL-сервера непосредственно за payload

Page 68: Философия Application Security

68

Page 69: Философия Application Security

69

Потоки данных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);}

Page 70: Философия Application Security

70

Потоки данных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);}

Page 71: Философия Application Security

71

Потоки данных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);}

Page 72: Философия Application Security

72

Потоки данных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);}

Page 73: Философия Application Security

73

Потоки данных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);}

Page 74: Философия Application Security

74

Потоки данных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);}

Page 75: Философия Application Security

75

Потоки данных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);}

Page 76: Философия Application Security

76

Потоки данных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);}

Page 77: Философия Application Security

77

Потоки данных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);}

Page 78: Философия Application Security

78

Потоки данных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);}

Page 79: Философия Application Security

79

Потоки данных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!"}

Page 80: Философия Application Security

80

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

Page 81: Философия Application Security

81

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

Page 82: Философия Application Security

82

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

Page 83: Философия Application Security

83

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

Page 84: Философия Application Security

84

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

Page 85: Философия Application Security

85

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

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

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

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

Page 86: Философия Application Security

86

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

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

Page 87: Философия Application Security

87

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

Page 88: Философия Application Security

88

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

Page 89: Философия Application Security

89

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

Page 90: Философия Application Security

90

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

Page 91: Философия Application Security

91

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

Page 92: Философия Application Security

92

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

Page 93: Философия Application Security

93

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

Page 94: Философия Application Security

94

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

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

Page 95: Философия Application Security

95

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

Page 96: Философия Application Security

96

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

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

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

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

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

Page 97: Философия Application Security

97

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

Page 98: Философия Application Security

98

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

Page 99: Философия Application Security

99

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

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

Page 100: Философия Application Security

100

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

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

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

Риск

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

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

Page 101: Философия Application Security

101

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

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

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

Page 102: Философия Application Security

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

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

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

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

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

Page 103: Философия Application Security

103

Формальные признаки уязвимостей к инъекциямДано: потенциально уязвимая операция (точка потока выполнения) PVO(text): операция прямой или косвенной интерпретации текста text на формальном языке.

Пусть text = transform(argument), где argument – поток данных множества аргументов точки входа EP, а transform – функция промежуточных преобразований.

Тогда приложение уязвимо к атаке инъекции в точке PVO, если существует и достижимо хотя бы одно множество vector таких значений элементов EP, при которых происходит изменение структуры синтаксического дерева текста text, не предусмотренное правилами прочих предметных областей приложения.

Page 104: Философия Application Security

104

Для защиты от атак инъекций в любой язык необходимо и достаточно обеспечить для transform инвариант «vector – пустое множество»

Page 105: Философия Application Security

105

Shellshock

Page 106: Философия Application Security

106

Место действия: интерпретатор BASH

Page 107: Философия Application Security

107

BASH использует окружение и для хранения переменных состояния, и для передачи дочерним процессам текущих определений функций

Page 108: Философия Application Security

108

env var_fn='() { <your function> }'

Page 109: Философия Application Security

109

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

Page 110: Философия Application Security

110

env var_fn='() { <your function> }; <attacker code here>'

Page 111: Философия Application Security

111

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

Page 112: Философия Application Security

112

env var_fn='() { ignore this;}; echo vulnerable' bash -c /bin/true

Page 113: Философия Application Security

113

Проще перечислить, какие системы/сервисы не были подвержены Shellshock

Page 114: Философия Application Security

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

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

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

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

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

Page 115: Философия Application Security

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

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

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

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

Page 116: Философия Application Security

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

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

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

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

― угрозе; // нарушение целостности

// уязвимость к атакам переполнения буфера

Page 117: Философия Application Security

117

GHOST

Page 118: Философия Application Security

118

Место действия: GNU C Library (glibc) -> nss/digits_dots.c -> __nss_hostname_digits_dots()

Page 119: Философия Application Security

119

nss/digits_dots.c 36 __nss_hostname_digits_dots (const char *name, struct hostent *resbuf, 37 char **buffer, size_t *buffer_size, 38 size_t buflen, struct hostent **result, 39 enum nss_status *status, int af, int *h_errnop). . . 85 size_needed = (sizeof (*host_addr) 86 + sizeof (*h_addr_ptrs) + strlen (name) + 1);. . .101 *buffer_size = size_needed;102 new_buf = (char *) realloc (*buffer, *buffer_size);. . .121 host_addr = (host_addr_t *) *buffer;122 h_addr_ptrs = (host_addr_list_t *)123 ((char *) host_addr + sizeof (*host_addr));124 h_alias_ptr = (char **) ((char *) h_addr_ptrs + sizeof (*h_addr_ptrs));125 hostname = (char *) h_alias_ptr + sizeof (*h_alias_ptr);. . .157 resbuf->h_name = strcpy (hostname, name);

Page 120: Философия Application Security

120

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

Page 121: Философия Application Security

121

Дополнительные условия― hostname должен состоять из цифр и точек;

― первый символ hostname должен быть цифрой;

― последний символ hostname не должен быть точкой;

― hostname должен быть достаточной длины, чтобы вызвать переполнение;

― hostname должен успешно разбираться как IPv4 адрес функцией inet_aton();

Page 122: Философия Application Security

122

С учетом всех ограничений, был разработан экплоит, для Exim, позволяющий обойти механизмы защиты ASLR и PIE и выполнить произвольный код в системе https://www.qualys.com/2015/01/27/cve-2015-0235/exim_ghost_bof.rb

Page 123: Философия Application Security

123

Резюмируя: как разрабатывать защищенные приложения, не сходя при этом с ума?

Page 124: Философия Application Security

124

Page 125: Философия Application Security

125

Перестать следовать шаблонам

Обеспечить адекватный контроль всех инвариантов Application Security и предметной области приложения

Page 126: Философия Application Security

Вопросы?

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

[email protected]@kochetkov_v

/Positive Technologies/Application Inspector/Team Lead

Page 127: Философия Application Security