SlideShare a Scribd company logo
Философия Application Security
Философия Application Security
Владимир Кочетков
/Positive Technologies/Application Inspector/Team Lead
CodeFreeze в Москве, 28.04.2016
:~$ whoami && whonotme
• .NET-разработчик, руководитель группы разработки анализаторов
компилируемых приложений в Positive Technologies
• Участник Positive Development User Group
• Исследователь в области защищенности приложений
• Участник RSDN
• Оторванный от реальности теоретик
• Упоротый параноик
3
Ништяки
4
WTF “AppSec”?
Application Security – предметная область обеспечения защищенности
приложений на этапах:
― проектирования;
― разработки;
― развертывания;
― эксплуатации;
5
WTF “AppSec”?
Application Security – предметная область обеспечения защищенности
приложений на этапах:
― проектирования;
― разработки;
― развертывания;
― эксплуатации;
сегодняшняя тема
6
Agenda (чего НЕ будет)
7
Вопрос: почему
квалифицированные
разработчики допускают
уязвимости?
8
Причины разработки уязвимого кода
― Низкая квалификация
― Человеческий фактор
― Отсутствие системного подхода
― Шаблонное мышление
9
Agenda
Что?
Теоретический минимум, необходимый для осознанной разработки
защищенного кода;
разбор известных уязвимостей.
Зачем?
Перестать следовать культу карго и
шаблонному подходу к вопросам
обеспечения защищенности.
10
Главный вопрос Жизни,
Вселенной и всего
остального…
11
…что такое "уязвимость"?
12
Что такое "уязвимость"?
«Недостаток (слабость) программного (программно-технического) обеспечения
средства или информационной системы в целом, который (которая) может быть
использована для реализации угроз безопасности информации» - ГОСТ Р 56546-
2015
13
Что такое "уязвимость"?
«Недостаток (слабость) программного (программно-технического) обеспечения
средства или информационной системы в целом, который (которая) может быть
использована для реализации угроз безопасности информации» - ГОСТ Р 56546-
2015
«В чем сила, брат?» (с)
14
Что такое "уязвимость"?
«Недостаток (слабость) программного (программно-технического) обеспечения
средства или информационной системы в целом, который (которая) может быть
использована для реализации угроз безопасности информации» - ГОСТ Р 56546-
2015
«В чем сила, брат?» (с)
«Набор входных данных, приводящий машину Тьюринга в запрещенную
конфигурацию» - Theoretical Computer Science
15
Что такое "уязвимость"?
«Недостаток (слабость) программного (программно-технического) обеспечения
средства или информационной системы в целом, который (которая) может быть
использована для реализации угроз безопасности информации» - ГОСТ Р 56546-
2015
«В чем сила, брат?» (с)
«Набор входных данных, приводящий машину Тьюринга в запрещенную
конфигурацию» - Theoretical Computer Science
16
Существующие определения не
дают ни малейшего
представления о технической
сущности уязвимости
17
Правильный вопрос: в чем
разница между защищенным и
уязвимым кодом?
18
Внимание, белый ящик!
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();
...
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();
...
Атакующий имеет возможность нарушить целостность
выходного потока данных (кода SQL-запроса), манипулируя
потоком входных данных (параметром HTTP-запроса),
приходящим в операцию выполнения SQL-кода.
20
Шаблон: чтобы избежать
уязвимости к SQL-инъекции
необходимо использовать
параметризацию запросов
21
Внимание, белый ящик!
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();
...
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();
...
Атакующий имеет возможность нарушить целостность
выходного потока данных (параметра SQL-запроса),
манипулируя потоком входных данных (параметром HTTP-
запроса), приходящим в операцию выполнения SQL-кода,
что может привести к нарушению правил предметной
области приложения.
23
Внимание, белый ящик!
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}
24
Users
Id
Nickname
Rating
MessageCount
TopicCount
Password
Внимание, белый ящик!
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
25
Users
Id
Nickname
Rating
MessageCount
TopicCount
Password
Внимание, белый ящик!
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
26
Users
Id
Nickname
Rating
MessageCount
TopicCount
Password
Атакующий имеет возможность
нарушить конфиденциальность
хранящегося потока данных,
манипулируя потоком входных
данных (параметром HTTP-запроса),
приводящим к нарушению правил
предметной области приложения.
Какой из фрагментов кода уязвим?
1)
[Authorize(Roles = "Foo")]
public ActionResult SomeAction()
{
...
return View();
}
2)
[Authorize(Roles = "Bar, Qux")]
public ActionResult SomeAction()
{
...
return View();
}
27
Какой из фрагментов кода уязвим?
1)
[Authorize(Roles = "Foo")]
public ActionResult SomeAction()
{
...
return View();
}
2)
[Authorize(Roles = "Bar, Qux")]
public ActionResult SomeAction()
{
...
return View();
}
Невозможно оценить защищенность кода,
не владея всеми предметными областями
приложения (в данном случае, правилами
предметной области контроля доступа).
28
Критерии уязвимости кода
определяются множеством
предметных областей
приложения
29
Предметные области
Второстепенные:
― защищенность;
― отказоустойчивость;
― опыт взаимодействия,
― производительность.
Основные:
― интернет-торговля;
― онлайн-банкинг;
― бухучет;
― … (тысячи их).
Каждое приложение реализует модели как основной предметной области, так и
множество моделей второстепенных предметных областей
Application Security –
второстепенная предметная
область
31
{Предметная область}
Application Security
32
Предметная область –
множество сущностей, их
инвариантов и отношений
33
Сущность
– абстракция объекта в некотором контексте, обладающая следующими
характеристиками:
• свойство – значимый атрибут абстрагируемого сущностью объекта;
• состояние– множество текущих значений всех свойств сущности;
• инвариант– множество допустимых состояний сущности.
Отношение – утверждение, определяющее взаимосвязь изменения состояний
сущностей.
34
Пример: логистика
Сущность: точки на карте города
• свойство: координаты – пара значений «широта-долгота»;
• инвариант: координаты принадлежат перекресткам города или строениям.
Сущность: маршрут
• свойство: путь - упорядоченное множество точек на карте города;
• инвариант: путь непрерывен, проходит по улицам города в соответствии с ПДД;
• отношение: оптимальность – длина пути минимальна для заданных начальной и
конечной точек.
Сущности: точка загрузки, точка доставки
• свойство: точка на карте города;
• инвариант: координаты принадлежат строениям.
35
Задача коммивояжёра
В терминах предметной области логистики:
построить оптимальный маршрут из точки
загрузки, проходящий через все точки доставки по
одному разу и возвращающийся в точку загрузки.
36
Задача коммивояжёра
В терминах предметной области логистики:
построить оптимальный маршрут из точки
загрузки, проходящий через все точки доставки по
одному разу и возвращающийся в точку загрузки.
В терминах предметной области теории графов:
Найти гамильтонов цикл минимального веса в
полном (дополненном ребрами бесконечной длины)
взвешенном графе.
37
goto fail;
38
Место действия: SSL/TLS
библиотека SecureTransport ->
sslKeyExchange.c
39
Процесс согласования соединения SSL/TLS
SSLProcessHandshakeRecord()
-> SSLProcessHandshakeMessage()
-> SSLProcessClientHello()
-> SSLProcessServerHello()
-> SSLProcessCertificate()
-> SSLProcessServerKeyExchange()
-> SSLDecodeSignedServerKeyExchange()
-> SSLDecodeXXKeyParams()
IF TLS 1.2 -> SSLVerifySignedServerKeyExchangeTls12()
OTHERWISE -> SSLVerifySignedServerKeyExchange()
40
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:
. . . 41
Лишний безусловный переход на
метку `fail` приводил к
нарушению правил предметной
области протокола SSL/TLS
42
Предметная область {Application}
Security
43
«Трясина Тьюринга» - не только
об эзотерических языках
44
Применимость теоремы Райса к
реальным системам – такая же
теоретизация, как и идея
описывать приложение в виде
конечного автомата
45
Приложение можно
рассматривать, как поток
управления, обрабатывающий
множество потоков данных
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
Потоки управления
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);
}
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);
}
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);
}
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);
}
61
Потоки управления всегда
являются производными от
потоков данных
62
Heartbleed
63
Место действия: библиотека
OpenSSL -> ssl/t1_lib.c ->
tls1_process_heartbeat()
64
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 bytes
3988 * message type, plus 2 bytes payload length, plus
3989 * payload, plus padding
3990 */
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);
65
Атакующий имел возможность,
манипулируя потоком входных
данных, нарушить целостность
выходного потока данных …
66
…, включая в него содержимое
до 64Kb кучи SSL-сервера
непосредственно за payload
67
68
Потоки данных
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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);
}
79
str1 ∈ {
Encoding.UTF8.GetString(Convert.FromBse64String(Request.Params["parm"])),
"Wrong Key!"
}
Множества значений всех
потоков данных в конкретной
точке потока выполнения
определяют состояние
приложения
80
Граф переходов между
состояниями приложения
определяет все возможные
потоки вычисления
81
Граф потоков вычисления
является семантически-
эквивалентной моделью
приложения
82
Предметная область Application
{Security}
83
Театр начинается с вешалки, а
уязвимость – с недостатка
84
Недостаток
- неэффективная реализация моделей предметных областей приложения и
контролей инвариантов их сущностей
Примеры контролей Application Security:
• предварительная обработка потоков данных;
• подтверждение аутентичности потоков вычисления;
• проверка прав доступа к потокам данных;
• обеспечение соответствия потока вычисления модели функциональной
предметной области;
• …
85
Угроза
- обусловленная недостатком возможность нарушить состояние защищенности
потока вычисления, лишив его одного из свойств:
• конфиденциальности;
• целостности;
• доступности;
• авторизованности;
• аутентичности;
• аппелируемости;
• подотчетности;
• достоверности;
• <нужное вписать>
86
Конфиденциальность
Свойство-состояния потока вычисления, при котором доступ к нему
осуществляется только сущностями, имеющими на это право.
87
Целостность
Свойство-состояние потока вычисления, при котором изменения в нем
осуществляются только сущностями, имеющими на это право.
88
Доступность
Свойство-состояние потока вычисления, при котором доступ к нему могут
осуществить все сущности, имеющие на это право.
89
Авторизованность
Свойство-состояние потока вычисления, при котором его источниками являются
только сущности, имеющие на это право.
90
Аутентичность
Свойство-состояние потока вычисления, при котором подтверждена подлинность
его источника.
91
Аппелируемость
Свойство-состояние потока вычисления, при котором его источник не может
отказаться от того, что он является таковым.
92
Уязвимость – состояние
приложения, в котором возможна
реализация угрозы
93
Невозможность реализации
угрозы в каждой точке потока
вычисления* является
инвариантом защищенности
приложения
94
* …пересекающего границу доверия
Уязвимость бизнес-логики–
состояние реализации угрозы
через нарушение правил
основной предметной области
приложения
95
То, что может сделать с потоками вычисления атакующий, нарушив инварианты
сущностей предметных областей, называется угрозой (threat)
То, где и благодаря чему он может это сделать, называется уязвимостью
(vulnerability), обусловленной недостатком (weakness)
То, как он может это сделать, называется атакой (attack)
То, с какой вероятностью у него это удастся и какие последствия может повлечь,
называется риском (risk)
Иными словами…
96
То, что не позволяет атакующему
провести атаку, обеспечивает
защищенность (security)
97
То, что минимизирует риск,
обеспечивает безопасность
(safety)
98
Акцентировать внимание
необходимо на причинах*, а не
на следствиях**!
* недостатки
** уязвимости, атаки или риски
99
Причинно-следственные связи
Недостаток Угроза
Уязвимость Атака
Риск
Незащищенность
Небезопасность
100
Промежуточные итоги
Разработка защищенного кода сводится к реализации контроля инвариантов
всех сущностей основной предметной области и области защищенности
приложения
Анализ защищенности кода сводится к оценке эффективности реализованных
контролей
Ни то, ни другое – невозможно без досконального изучения основной
предметной области и области защищенности приложения
101
Классификация
Классификация уязвимостей возможна по:
― предметной области; // защищенность приложения
― недостатку; // неэффективная предварительная обработка
потоков данных
― потоку вычисления; // интерпретация потока данных в поток выполнения
― угрозе; // нарушение целостности
// уязвимость к атакам инъекций (в зависимости от интерпретатора потока
данных: XSS, SQLi, XMLi,XPATHi, Path Traversal, LINQi,XXE и т.п.)
Формальные признаки уязвимостей к инъекциям
Дано: потенциально уязвимая операция (точка потока выполнения) PVO(text):
операция прямой или косвенной интерпретации текста text на формальном
языке.
Пусть text = transform(argument), где argument – поток данных множества
аргументов точки входа EP, а transform – функция промежуточных
преобразований.
Тогда приложение уязвимо к атаке инъекции в точке PVO, если существует и
достижимо хотя бы одно множество vector таких значений элементов EP, при
которых происходит изменение структуры синтаксического дерева текста text, не
предусмотренное правилами прочих предметных областей приложения.
103
Для защиты от атак инъекций в
любой язык необходимо и
достаточно обеспечить для
transform инвариант «vector –
пустое множество»
104
Shellshock
105
Место действия: интерпретатор
BASH
106
BASH использует окружение и
для хранения переменных
состояния, и для передачи
дочерним процессам текущих
определений функций
107
env var_fn='() { <your function> }'
108
Ошибка разбора и импорта
определения функции приводила
к выполнению кода, следующего
за определением функции прямо
во время импорта
109
env var_fn='() { <your function> }; <attacker
code here>'
110
Переменные состояния часто
являются производными потоков
входных данных
111
env var_fn='() { ignore this;}; echo vulnerable'
bash -c /bin/true
112
Проще перечислить, какие
системы/сервисы не были
подвержены Shellshock
113
Классификация
Классификация уязвимостей возможна по:
― предметной области; // защищенность приложения
― недостатку; // неэффективное подтверждение аутентичности
источника потока вычисления
― потоку вычисления; // интерпретация HTTP-запроса, приводящего к
изменению состояния приложения
― угрозе; // нарушение аутентичности
// уязвимость к атакам CSRF
Классификация
Классификация уязвимостей возможна по:
― предметной области; // онлайн-торговля
― недостатку; // неэффективный контроль использования погашенных
купонов на скидку
― потоку вычисления; // транзакция оплаты заказа
― угрозе; // нарушение авторизованности
// уязвимость к атакам на бизнес-логику (повторное использование купонов на
скидку)
Классификация
Классификация уязвимостей возможна по:
― предметной области; // защищенность приложения
― недостатку; // неэффективный контроль операций прямой записи
пользовательских потоков данных или их производных в память
― потоку вычисления; // интерпретация внутренних данных на стеке или
куче
― угрозе; // нарушение целостности
// уязвимость к атакам переполнения буфера
GHOST
117
Место действия: GNU C Library
(glibc) -> nss/digits_dots.c ->
__nss_hostname_digits_dots()
118
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); 119
Манипулируя потоком входных
данных, атакующий имел
возможность нарушить
целостность потоков данных на
стеке или в куче приложения
120
Дополнительные условия
― hostname должен состоять из цифр и точек;
― первый символ hostname должен быть цифрой;
― последний символ hostname не должен быть точкой;
― hostname должен быть достаточной длины, чтобы вызвать переполнение;
― hostname должен успешно разбираться как IPv4 адрес функцией inet_aton();
121
С учетом всех ограничений, был
разработан экплоит, для Exim,
позволяющий обойти механизмы
защиты ASLR и PIE и выполнить
произвольный код в системе
https://www.qualys.com/2015/01/27/cve-2015-0235/exim_ghost_bof.rb
122
Резюмируя: как разрабатывать
защищенные приложения, не
сходя при этом с ума?
123
124
Перестать следовать шаблонам
Обеспечить адекватный контроль
всех инвариантов Application
Security и предметной области
приложения 125
Вопросы?
Владимир Кочетков
vkochetkov@ptsecurity.com
@kochetkov_v
/Positive Technologies/Application Inspector/Team Lead
Философия Application Security
Ad

More Related Content

What's hot (20)

AppSec -- хакерский путь
AppSec -- хакерский путьAppSec -- хакерский путь
AppSec -- хакерский путь
Vladimir Kochetkov
 
Как разработать защищенное веб-приложение и не сойти при этом с ума (вебинар)
Как разработать защищенное веб-приложение и не сойти при этом с ума (вебинар)Как разработать защищенное веб-приложение и не сойти при этом с ума (вебинар)
Как разработать защищенное веб-приложение и не сойти при этом с ума (вебинар)
Vladimir Kochetkov
 
Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++
Yauheni Akhotnikau
 
Современный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыСовременный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтеры
corehard_by
 
C++ refelection and cats
C++ refelection and catsC++ refelection and cats
C++ refelection and cats
corehard_by
 
Очередной скучный доклад про логгирование
Очередной скучный доклад про логгированиеОчередной скучный доклад про логгирование
Очередной скучный доклад про логгирование
Python Meetup
 
Взломать сайт на ASP.NET
Взломать сайт на ASP.NETВзломать сайт на ASP.NET
Взломать сайт на ASP.NET
Positive Hack Days
 
Alexei Sintsov - "Between error and vulerability - one step"
Alexei Sintsov - "Between error and vulerability - one step"Alexei Sintsov - "Between error and vulerability - one step"
Alexei Sintsov - "Between error and vulerability - one step"
Andrew Mayorov
 
Формальные методы защиты приложений
Формальные методы защиты приложенийФормальные методы защиты приложений
Формальные методы защиты приложений
Positive Hack Days
 
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Yauheni Akhotnikau
 
200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кода200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кода
Andrey Karpov
 
Реактивный двигатель вашего Android приложения
Реактивный двигатель вашего Android приложенияРеактивный двигатель вашего Android приложения
Реактивный двигатель вашего Android приложения
Matvey Malkov
 
Fiche Révision POO
Fiche Révision POOFiche Révision POO
Fiche Révision POO
Asmaa BENGUEDDACH
 
SSL/TLS: история уязвимостей
SSL/TLS: история уязвимостейSSL/TLS: история уязвимостей
SSL/TLS: история уязвимостей
Positive Hack Days
 
Advanced Sql Injection
Advanced Sql InjectionAdvanced Sql Injection
Advanced Sql Injection
Dmitry Evteev
 
Unsafe: to be or to be removed?
Unsafe: to be or to be removed?Unsafe: to be or to be removed?
Unsafe: to be or to be removed?
Alexey Fyodorov
 
AppSec -- хакерский путь
AppSec -- хакерский путьAppSec -- хакерский путь
AppSec -- хакерский путь
Vladimir Kochetkov
 
Как разработать защищенное веб-приложение и не сойти при этом с ума (вебинар)
Как разработать защищенное веб-приложение и не сойти при этом с ума (вебинар)Как разработать защищенное веб-приложение и не сойти при этом с ума (вебинар)
Как разработать защищенное веб-приложение и не сойти при этом с ума (вебинар)
Vladimir Kochetkov
 
Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++
Yauheni Akhotnikau
 
Современный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыСовременный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтеры
corehard_by
 
C++ refelection and cats
C++ refelection and catsC++ refelection and cats
C++ refelection and cats
corehard_by
 
Очередной скучный доклад про логгирование
Очередной скучный доклад про логгированиеОчередной скучный доклад про логгирование
Очередной скучный доклад про логгирование
Python Meetup
 
Взломать сайт на ASP.NET
Взломать сайт на ASP.NETВзломать сайт на ASP.NET
Взломать сайт на ASP.NET
Positive Hack Days
 
Alexei Sintsov - "Between error and vulerability - one step"
Alexei Sintsov - "Between error and vulerability - one step"Alexei Sintsov - "Between error and vulerability - one step"
Alexei Sintsov - "Between error and vulerability - one step"
Andrew Mayorov
 
Формальные методы защиты приложений
Формальные методы защиты приложенийФормальные методы защиты приложений
Формальные методы защиты приложений
Positive Hack Days
 
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Yauheni Akhotnikau
 
200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кода200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кода
Andrey Karpov
 
Реактивный двигатель вашего Android приложения
Реактивный двигатель вашего Android приложенияРеактивный двигатель вашего Android приложения
Реактивный двигатель вашего Android приложения
Matvey Malkov
 
SSL/TLS: история уязвимостей
SSL/TLS: история уязвимостейSSL/TLS: история уязвимостей
SSL/TLS: история уязвимостей
Positive Hack Days
 
Advanced Sql Injection
Advanced Sql InjectionAdvanced Sql Injection
Advanced Sql Injection
Dmitry Evteev
 
Unsafe: to be or to be removed?
Unsafe: to be or to be removed?Unsafe: to be or to be removed?
Unsafe: to be or to be removed?
Alexey Fyodorov
 

Viewers also liked (8)

Безопасная разработка для руководителей
Безопасная разработка для руководителейБезопасная разработка для руководителей
Безопасная разработка для руководителей
Positive Development User Group
 
Построение процесса безопасной разработки
Построение процесса безопасной разработкиПостроение процесса безопасной разработки
Построение процесса безопасной разработки
Positive Development User Group
 
[1.4] «Ой, не шмогла». Обзор ограничений современных технологий в области ...
[1.4] «Ой, не шмогла». Обзор ограничений современных технологий в области ...[1.4] «Ой, не шмогла». Обзор ограничений современных технологий в области ...
[1.4] «Ой, не шмогла». Обзор ограничений современных технологий в области ...
OWASP Russia
 
Тестируем производительность с помощью Selenium
Тестируем производительность с помощью SeleniumТестируем производительность с помощью Selenium
Тестируем производительность с помощью Selenium
SQALab
 
Опыт организации тестирования безопасности Web приложений в компании
Опыт организации тестирования безопасности Web приложений в компанииОпыт организации тестирования безопасности Web приложений в компании
Опыт организации тестирования безопасности Web приложений в компании
SQALab
 
Waf.js: How to Protect Web Applications using JavaScript
Waf.js: How to Protect Web Applications using JavaScriptWaf.js: How to Protect Web Applications using JavaScript
Waf.js: How to Protect Web Applications using JavaScript
Denis Kolegov
 
Тестирование уязвимостей веб приложений
Тестирование уязвимостей веб приложенийТестирование уязвимостей веб приложений
Тестирование уязвимостей веб приложений
SQALab
 
Security as a new metric for Business, Product and Development Lifecycle
Security as a new metric for Business, Product and Development LifecycleSecurity as a new metric for Business, Product and Development Lifecycle
Security as a new metric for Business, Product and Development Lifecycle
Nazar Tymoshyk, CEH, Ph.D.
 
Безопасная разработка для руководителей
Безопасная разработка для руководителейБезопасная разработка для руководителей
Безопасная разработка для руководителей
Positive Development User Group
 
Построение процесса безопасной разработки
Построение процесса безопасной разработкиПостроение процесса безопасной разработки
Построение процесса безопасной разработки
Positive Development User Group
 
[1.4] «Ой, не шмогла». Обзор ограничений современных технологий в области ...
[1.4] «Ой, не шмогла». Обзор ограничений современных технологий в области ...[1.4] «Ой, не шмогла». Обзор ограничений современных технологий в области ...
[1.4] «Ой, не шмогла». Обзор ограничений современных технологий в области ...
OWASP Russia
 
Тестируем производительность с помощью Selenium
Тестируем производительность с помощью SeleniumТестируем производительность с помощью Selenium
Тестируем производительность с помощью Selenium
SQALab
 
Опыт организации тестирования безопасности Web приложений в компании
Опыт организации тестирования безопасности Web приложений в компанииОпыт организации тестирования безопасности Web приложений в компании
Опыт организации тестирования безопасности Web приложений в компании
SQALab
 
Waf.js: How to Protect Web Applications using JavaScript
Waf.js: How to Protect Web Applications using JavaScriptWaf.js: How to Protect Web Applications using JavaScript
Waf.js: How to Protect Web Applications using JavaScript
Denis Kolegov
 
Тестирование уязвимостей веб приложений
Тестирование уязвимостей веб приложенийТестирование уязвимостей веб приложений
Тестирование уязвимостей веб приложений
SQALab
 
Security as a new metric for Business, Product and Development Lifecycle
Security as a new metric for Business, Product and Development LifecycleSecurity as a new metric for Business, Product and Development Lifecycle
Security as a new metric for Business, Product and Development Lifecycle
Nazar Tymoshyk, CEH, Ph.D.
 
Ad

Similar to Философия Application Security (20)

Анализ ИБ и расследование инцидентов ИБ (учебный семинар)
Анализ ИБ и расследование инцидентов ИБ (учебный семинар)Анализ ИБ и расследование инцидентов ИБ (учебный семинар)
Анализ ИБ и расследование инцидентов ИБ (учебный семинар)
Alexey Kachalin
 
Классификация экономико-технических атак. Спикер: Григорий Васильков
Классификация экономико-технических атак. Спикер: Григорий ВасильковКлассификация экономико-технических атак. Спикер: Григорий Васильков
Классификация экономико-технических атак. Спикер: Григорий Васильков
Cyber Fund
 
Анализ защищенности Web-приложений, выявление уязвимостей в реальных условиях
Анализ защищенности Web-приложений, выявление уязвимостей в реальных условияхАнализ защищенности Web-приложений, выявление уязвимостей в реальных условиях
Анализ защищенности Web-приложений, выявление уязвимостей в реальных условиях
Dmitry Evteev
 
Владимир Кочетков. Как разработать защищенное веб-приложение и не сойти при э...
Владимир Кочетков. Как разработать защищенное веб-приложение и не сойти при э...Владимир Кочетков. Как разработать защищенное веб-приложение и не сойти при э...
Владимир Кочетков. Как разработать защищенное веб-приложение и не сойти при э...
Positive Hack Days
 
как разработать защищенное веб приложение и не сойти с ума. владимир кочетков
как разработать защищенное веб приложение и не сойти с ума. владимир кочетковкак разработать защищенное веб приложение и не сойти с ума. владимир кочетков
как разработать защищенное веб приложение и не сойти с ума. владимир кочетков
Positive Hack Days
 
SAST и Application Security: как бороться с уязвимостями в коде
SAST и Application Security: как бороться с уязвимостями в кодеSAST и Application Security: как бороться с уязвимостями в коде
SAST и Application Security: как бороться с уязвимостями в коде
Andrey Karpov
 
Статический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMergeСтатический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMerge
Tatyanazaxarova
 
Никита Галкин "Testing in Node.js World"
Никита Галкин "Testing in Node.js World"Никита Галкин "Testing in Node.js World"
Никита Галкин "Testing in Node.js World"
Fwdays
 
Cisco Social Network Security
Cisco Social Network SecurityCisco Social Network Security
Cisco Social Network Security
Cisco Russia
 
CodeFest 2011. Петунин Д. — Использование инструментов статического анализа п...
CodeFest 2011. Петунин Д. — Использование инструментов статического анализа п...CodeFest 2011. Петунин Д. — Использование инструментов статического анализа п...
CodeFest 2011. Петунин Д. — Использование инструментов статического анализа п...
CodeFest
 
разработка безопасного кода
разработка безопасного кодаразработка безопасного кода
разработка безопасного кода
Andrey Somsikov
 
CodeFest 2012. Сошников Д. — Разработка мобильных приложений на платформе Mic...
CodeFest 2012. Сошников Д. — Разработка мобильных приложений на платформе Mic...CodeFest 2012. Сошников Д. — Разработка мобильных приложений на платформе Mic...
CodeFest 2012. Сошников Д. — Разработка мобильных приложений на платформе Mic...
CodeFest
 
Pt devteev-risspa
Pt devteev-risspaPt devteev-risspa
Pt devteev-risspa
yaevents
 
"API «Битрикс24» — разбор с пристрастием". Александр Сербул, 1С-Битрикс
"API «Битрикс24» — разбор с пристрастием". Александр Сербул, 1С-Битрикс"API «Битрикс24» — разбор с пристрастием". Александр Сербул, 1С-Битрикс
"API «Битрикс24» — разбор с пристрастием". Александр Сербул, 1С-Битрикс
Yandex
 
Развитие систем анализа защищенности. Взгляд в будущее!
Развитие систем анализа защищенности. Взгляд в будущее!Развитие систем анализа защищенности. Взгляд в будущее!
Развитие систем анализа защищенности. Взгляд в будущее!
Dmitry Evteev
 
Угрозы ИБ - retail edition (2016)
Угрозы ИБ - retail edition (2016)Угрозы ИБ - retail edition (2016)
Угрозы ИБ - retail edition (2016)
Alexey Kachalin
 
Waf.js: как защищать веб-приложения с использованием JavaScript
Waf.js: как защищать веб-приложения с использованием JavaScriptWaf.js: как защищать веб-приложения с использованием JavaScript
Waf.js: как защищать веб-приложения с использованием JavaScript
Positive Hack Days
 
Будущее для безопасности интернета вещей и встраиваемых систем: Kaspersky Ope...
Будущее для безопасности интернета вещей и встраиваемых систем: Kaspersky Ope...Будущее для безопасности интернета вещей и встраиваемых систем: Kaspersky Ope...
Будущее для безопасности интернета вещей и встраиваемых систем: Kaspersky Ope...
Лаборатория Касперского
 
Aspect Oriented Approach
Aspect Oriented ApproachAspect Oriented Approach
Aspect Oriented Approach
Dmytro Chyzhykov
 
Решения HP для обеспечения информационной безопасности
Решения HP для обеспечения информационной безопасностиРешения HP для обеспечения информационной безопасности
Решения HP для обеспечения информационной безопасности
КРОК
 
Анализ ИБ и расследование инцидентов ИБ (учебный семинар)
Анализ ИБ и расследование инцидентов ИБ (учебный семинар)Анализ ИБ и расследование инцидентов ИБ (учебный семинар)
Анализ ИБ и расследование инцидентов ИБ (учебный семинар)
Alexey Kachalin
 
Классификация экономико-технических атак. Спикер: Григорий Васильков
Классификация экономико-технических атак. Спикер: Григорий ВасильковКлассификация экономико-технических атак. Спикер: Григорий Васильков
Классификация экономико-технических атак. Спикер: Григорий Васильков
Cyber Fund
 
Анализ защищенности Web-приложений, выявление уязвимостей в реальных условиях
Анализ защищенности Web-приложений, выявление уязвимостей в реальных условияхАнализ защищенности Web-приложений, выявление уязвимостей в реальных условиях
Анализ защищенности Web-приложений, выявление уязвимостей в реальных условиях
Dmitry Evteev
 
Владимир Кочетков. Как разработать защищенное веб-приложение и не сойти при э...
Владимир Кочетков. Как разработать защищенное веб-приложение и не сойти при э...Владимир Кочетков. Как разработать защищенное веб-приложение и не сойти при э...
Владимир Кочетков. Как разработать защищенное веб-приложение и не сойти при э...
Positive Hack Days
 
как разработать защищенное веб приложение и не сойти с ума. владимир кочетков
как разработать защищенное веб приложение и не сойти с ума. владимир кочетковкак разработать защищенное веб приложение и не сойти с ума. владимир кочетков
как разработать защищенное веб приложение и не сойти с ума. владимир кочетков
Positive Hack Days
 
SAST и Application Security: как бороться с уязвимостями в коде
SAST и Application Security: как бороться с уязвимостями в кодеSAST и Application Security: как бороться с уязвимостями в коде
SAST и Application Security: как бороться с уязвимостями в коде
Andrey Karpov
 
Статический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMergeСтатический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMerge
Tatyanazaxarova
 
Никита Галкин "Testing in Node.js World"
Никита Галкин "Testing in Node.js World"Никита Галкин "Testing in Node.js World"
Никита Галкин "Testing in Node.js World"
Fwdays
 
Cisco Social Network Security
Cisco Social Network SecurityCisco Social Network Security
Cisco Social Network Security
Cisco Russia
 
CodeFest 2011. Петунин Д. — Использование инструментов статического анализа п...
CodeFest 2011. Петунин Д. — Использование инструментов статического анализа п...CodeFest 2011. Петунин Д. — Использование инструментов статического анализа п...
CodeFest 2011. Петунин Д. — Использование инструментов статического анализа п...
CodeFest
 
разработка безопасного кода
разработка безопасного кодаразработка безопасного кода
разработка безопасного кода
Andrey Somsikov
 
CodeFest 2012. Сошников Д. — Разработка мобильных приложений на платформе Mic...
CodeFest 2012. Сошников Д. — Разработка мобильных приложений на платформе Mic...CodeFest 2012. Сошников Д. — Разработка мобильных приложений на платформе Mic...
CodeFest 2012. Сошников Д. — Разработка мобильных приложений на платформе Mic...
CodeFest
 
Pt devteev-risspa
Pt devteev-risspaPt devteev-risspa
Pt devteev-risspa
yaevents
 
"API «Битрикс24» — разбор с пристрастием". Александр Сербул, 1С-Битрикс
"API «Битрикс24» — разбор с пристрастием". Александр Сербул, 1С-Битрикс"API «Битрикс24» — разбор с пристрастием". Александр Сербул, 1С-Битрикс
"API «Битрикс24» — разбор с пристрастием". Александр Сербул, 1С-Битрикс
Yandex
 
Развитие систем анализа защищенности. Взгляд в будущее!
Развитие систем анализа защищенности. Взгляд в будущее!Развитие систем анализа защищенности. Взгляд в будущее!
Развитие систем анализа защищенности. Взгляд в будущее!
Dmitry Evteev
 
Угрозы ИБ - retail edition (2016)
Угрозы ИБ - retail edition (2016)Угрозы ИБ - retail edition (2016)
Угрозы ИБ - retail edition (2016)
Alexey Kachalin
 
Waf.js: как защищать веб-приложения с использованием JavaScript
Waf.js: как защищать веб-приложения с использованием JavaScriptWaf.js: как защищать веб-приложения с использованием JavaScript
Waf.js: как защищать веб-приложения с использованием JavaScript
Positive Hack Days
 
Будущее для безопасности интернета вещей и встраиваемых систем: Kaspersky Ope...
Будущее для безопасности интернета вещей и встраиваемых систем: Kaspersky Ope...Будущее для безопасности интернета вещей и встраиваемых систем: Kaspersky Ope...
Будущее для безопасности интернета вещей и встраиваемых систем: Kaspersky Ope...
Лаборатория Касперского
 
Решения HP для обеспечения информационной безопасности
Решения HP для обеспечения информационной безопасностиРешения HP для обеспечения информационной безопасности
Решения HP для обеспечения информационной безопасности
КРОК
 
Ad

Философия Application Security

  • 2. Философия Application Security Владимир Кочетков /Positive Technologies/Application Inspector/Team Lead CodeFreeze в Москве, 28.04.2016
  • 3. :~$ whoami && whonotme • .NET-разработчик, руководитель группы разработки анализаторов компилируемых приложений в Positive Technologies • Участник Positive Development User Group • Исследователь в области защищенности приложений • Участник RSDN • Оторванный от реальности теоретик • Упоротый параноик 3
  • 5. WTF “AppSec”? Application Security – предметная область обеспечения защищенности приложений на этапах: ― проектирования; ― разработки; ― развертывания; ― эксплуатации; 5
  • 6. WTF “AppSec”? Application Security – предметная область обеспечения защищенности приложений на этапах: ― проектирования; ― разработки; ― развертывания; ― эксплуатации; сегодняшняя тема 6
  • 7. Agenda (чего НЕ будет) 7
  • 9. Причины разработки уязвимого кода ― Низкая квалификация ― Человеческий фактор ― Отсутствие системного подхода ― Шаблонное мышление 9
  • 10. Agenda Что? Теоретический минимум, необходимый для осознанной разработки защищенного кода; разбор известных уязвимостей. Зачем? Перестать следовать культу карго и шаблонному подходу к вопросам обеспечения защищенности. 10
  • 11. Главный вопрос Жизни, Вселенной и всего остального… 11
  • 13. Что такое "уязвимость"? «Недостаток (слабость) программного (программно-технического) обеспечения средства или информационной системы в целом, который (которая) может быть использована для реализации угроз безопасности информации» - ГОСТ Р 56546- 2015 13
  • 14. Что такое "уязвимость"? «Недостаток (слабость) программного (программно-технического) обеспечения средства или информационной системы в целом, который (которая) может быть использована для реализации угроз безопасности информации» - ГОСТ Р 56546- 2015 «В чем сила, брат?» (с) 14
  • 15. Что такое "уязвимость"? «Недостаток (слабость) программного (программно-технического) обеспечения средства или информационной системы в целом, который (которая) может быть использована для реализации угроз безопасности информации» - ГОСТ Р 56546- 2015 «В чем сила, брат?» (с) «Набор входных данных, приводящий машину Тьюринга в запрещенную конфигурацию» - Theoretical Computer Science 15
  • 16. Что такое "уязвимость"? «Недостаток (слабость) программного (программно-технического) обеспечения средства или информационной системы в целом, который (которая) может быть использована для реализации угроз безопасности информации» - ГОСТ Р 56546- 2015 «В чем сила, брат?» (с) «Набор входных данных, приводящий машину Тьюринга в запрещенную конфигурацию» - Theoretical Computer Science 16
  • 17. Существующие определения не дают ни малейшего представления о технической сущности уязвимости 17
  • 18. Правильный вопрос: в чем разница между защищенным и уязвимым кодом? 18
  • 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(); ... 19
  • 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-кода. 20
  • 21. Шаблон: чтобы избежать уязвимости к SQL-инъекции необходимо использовать параметризацию запросов 21
  • 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(); ... 22
  • 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-кода, что может привести к нарушению правил предметной области приложения. 23
  • 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} 24 Users Id Nickname Rating MessageCount TopicCount Password
  • 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 25 Users Id Nickname Rating MessageCount TopicCount Password
  • 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 26 Users Id Nickname Rating MessageCount TopicCount Password Атакующий имеет возможность нарушить конфиденциальность хранящегося потока данных, манипулируя потоком входных данных (параметром HTTP-запроса), приводящим к нарушению правил предметной области приложения.
  • 27. Какой из фрагментов кода уязвим? 1) [Authorize(Roles = "Foo")] public ActionResult SomeAction() { ... return View(); } 2) [Authorize(Roles = "Bar, Qux")] public ActionResult SomeAction() { ... return View(); } 27
  • 28. Какой из фрагментов кода уязвим? 1) [Authorize(Roles = "Foo")] public ActionResult SomeAction() { ... return View(); } 2) [Authorize(Roles = "Bar, Qux")] public ActionResult SomeAction() { ... return View(); } Невозможно оценить защищенность кода, не владея всеми предметными областями приложения (в данном случае, правилами предметной области контроля доступа). 28
  • 29. Критерии уязвимости кода определяются множеством предметных областей приложения 29
  • 30. Предметные области Второстепенные: ― защищенность; ― отказоустойчивость; ― опыт взаимодействия, ― производительность. Основные: ― интернет-торговля; ― онлайн-банкинг; ― бухучет; ― … (тысячи их). Каждое приложение реализует модели как основной предметной области, так и множество моделей второстепенных предметных областей
  • 31. Application Security – второстепенная предметная область 31
  • 33. Предметная область – множество сущностей, их инвариантов и отношений 33
  • 34. Сущность – абстракция объекта в некотором контексте, обладающая следующими характеристиками: • свойство – значимый атрибут абстрагируемого сущностью объекта; • состояние– множество текущих значений всех свойств сущности; • инвариант– множество допустимых состояний сущности. Отношение – утверждение, определяющее взаимосвязь изменения состояний сущностей. 34
  • 35. Пример: логистика Сущность: точки на карте города • свойство: координаты – пара значений «широта-долгота»; • инвариант: координаты принадлежат перекресткам города или строениям. Сущность: маршрут • свойство: путь - упорядоченное множество точек на карте города; • инвариант: путь непрерывен, проходит по улицам города в соответствии с ПДД; • отношение: оптимальность – длина пути минимальна для заданных начальной и конечной точек. Сущности: точка загрузки, точка доставки • свойство: точка на карте города; • инвариант: координаты принадлежат строениям. 35
  • 36. Задача коммивояжёра В терминах предметной области логистики: построить оптимальный маршрут из точки загрузки, проходящий через все точки доставки по одному разу и возвращающийся в точку загрузки. 36
  • 37. Задача коммивояжёра В терминах предметной области логистики: построить оптимальный маршрут из точки загрузки, проходящий через все точки доставки по одному разу и возвращающийся в точку загрузки. В терминах предметной области теории графов: Найти гамильтонов цикл минимального веса в полном (дополненном ребрами бесконечной длины) взвешенном графе. 37
  • 39. Место действия: SSL/TLS библиотека SecureTransport -> sslKeyExchange.c 39
  • 40. Процесс согласования соединения SSL/TLS SSLProcessHandshakeRecord() -> SSLProcessHandshakeMessage() -> SSLProcessClientHello() -> SSLProcessServerHello() -> SSLProcessCertificate() -> SSLProcessServerKeyExchange() -> SSLDecodeSignedServerKeyExchange() -> SSLDecodeXXKeyParams() IF TLS 1.2 -> SSLVerifySignedServerKeyExchangeTls12() OTHERWISE -> SSLVerifySignedServerKeyExchange() 40
  • 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: . . . 41
  • 42. Лишний безусловный переход на метку `fail` приводил к нарушению правил предметной области протокола SSL/TLS 42
  • 44. «Трясина Тьюринга» - не только об эзотерических языках 44
  • 45. Применимость теоремы Райса к реальным системам – такая же теоретизация, как и идея описывать приложение в виде конечного автомата 45
  • 46. Приложение можно рассматривать, как поток управления, обрабатывающий множество потоков данных 46
  • 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); } 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); } 48
  • 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); } 49
  • 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); } 50
  • 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); } 51
  • 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); } 52
  • 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); } 53
  • 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); } 54
  • 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); } 55
  • 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); } 56
  • 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); } 57
  • 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); } 58
  • 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); } 59
  • 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); } 60
  • 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); } 61
  • 62. Потоки управления всегда являются производными от потоков данных 62
  • 64. Место действия: библиотека OpenSSL -> ssl/t1_lib.c -> tls1_process_heartbeat() 64
  • 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 bytes 3988 * message type, plus 2 bytes payload length, plus 3989 * payload, plus padding 3990 */ 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); 65
  • 66. Атакующий имел возможность, манипулируя потоком входных данных, нарушить целостность выходного потока данных … 66
  • 67. …, включая в него содержимое до 64Kb кучи SSL-сервера непосредственно за payload 67
  • 68. 68
  • 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); } 69
  • 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); } 70
  • 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); } 71
  • 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); } 72
  • 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); } 73
  • 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); } 74
  • 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); } 75
  • 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); } 76
  • 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); } 77
  • 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); } 78
  • 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); } 79 str1 ∈ { Encoding.UTF8.GetString(Convert.FromBse64String(Request.Params["parm"])), "Wrong Key!" }
  • 80. Множества значений всех потоков данных в конкретной точке потока выполнения определяют состояние приложения 80
  • 81. Граф переходов между состояниями приложения определяет все возможные потоки вычисления 81
  • 82. Граф потоков вычисления является семантически- эквивалентной моделью приложения 82
  • 84. Театр начинается с вешалки, а уязвимость – с недостатка 84
  • 85. Недостаток - неэффективная реализация моделей предметных областей приложения и контролей инвариантов их сущностей Примеры контролей Application Security: • предварительная обработка потоков данных; • подтверждение аутентичности потоков вычисления; • проверка прав доступа к потокам данных; • обеспечение соответствия потока вычисления модели функциональной предметной области; • … 85
  • 86. Угроза - обусловленная недостатком возможность нарушить состояние защищенности потока вычисления, лишив его одного из свойств: • конфиденциальности; • целостности; • доступности; • авторизованности; • аутентичности; • аппелируемости; • подотчетности; • достоверности; • <нужное вписать> 86
  • 87. Конфиденциальность Свойство-состояния потока вычисления, при котором доступ к нему осуществляется только сущностями, имеющими на это право. 87
  • 88. Целостность Свойство-состояние потока вычисления, при котором изменения в нем осуществляются только сущностями, имеющими на это право. 88
  • 89. Доступность Свойство-состояние потока вычисления, при котором доступ к нему могут осуществить все сущности, имеющие на это право. 89
  • 90. Авторизованность Свойство-состояние потока вычисления, при котором его источниками являются только сущности, имеющие на это право. 90
  • 91. Аутентичность Свойство-состояние потока вычисления, при котором подтверждена подлинность его источника. 91
  • 92. Аппелируемость Свойство-состояние потока вычисления, при котором его источник не может отказаться от того, что он является таковым. 92
  • 93. Уязвимость – состояние приложения, в котором возможна реализация угрозы 93
  • 94. Невозможность реализации угрозы в каждой точке потока вычисления* является инвариантом защищенности приложения 94 * …пересекающего границу доверия
  • 95. Уязвимость бизнес-логики– состояние реализации угрозы через нарушение правил основной предметной области приложения 95
  • 96. То, что может сделать с потоками вычисления атакующий, нарушив инварианты сущностей предметных областей, называется угрозой (threat) То, где и благодаря чему он может это сделать, называется уязвимостью (vulnerability), обусловленной недостатком (weakness) То, как он может это сделать, называется атакой (attack) То, с какой вероятностью у него это удастся и какие последствия может повлечь, называется риском (risk) Иными словами… 96
  • 97. То, что не позволяет атакующему провести атаку, обеспечивает защищенность (security) 97
  • 98. То, что минимизирует риск, обеспечивает безопасность (safety) 98
  • 99. Акцентировать внимание необходимо на причинах*, а не на следствиях**! * недостатки ** уязвимости, атаки или риски 99
  • 100. Причинно-следственные связи Недостаток Угроза Уязвимость Атака Риск Незащищенность Небезопасность 100
  • 101. Промежуточные итоги Разработка защищенного кода сводится к реализации контроля инвариантов всех сущностей основной предметной области и области защищенности приложения Анализ защищенности кода сводится к оценке эффективности реализованных контролей Ни то, ни другое – невозможно без досконального изучения основной предметной области и области защищенности приложения 101
  • 102. Классификация Классификация уязвимостей возможна по: ― предметной области; // защищенность приложения ― недостатку; // неэффективная предварительная обработка потоков данных ― потоку вычисления; // интерпретация потока данных в поток выполнения ― угрозе; // нарушение целостности // уязвимость к атакам инъекций (в зависимости от интерпретатора потока данных: XSS, SQLi, XMLi,XPATHi, Path Traversal, LINQi,XXE и т.п.)
  • 103. Формальные признаки уязвимостей к инъекциям Дано: потенциально уязвимая операция (точка потока выполнения) PVO(text): операция прямой или косвенной интерпретации текста text на формальном языке. Пусть text = transform(argument), где argument – поток данных множества аргументов точки входа EP, а transform – функция промежуточных преобразований. Тогда приложение уязвимо к атаке инъекции в точке PVO, если существует и достижимо хотя бы одно множество vector таких значений элементов EP, при которых происходит изменение структуры синтаксического дерева текста text, не предусмотренное правилами прочих предметных областей приложения. 103
  • 104. Для защиты от атак инъекций в любой язык необходимо и достаточно обеспечить для transform инвариант «vector – пустое множество» 104
  • 107. BASH использует окружение и для хранения переменных состояния, и для передачи дочерним процессам текущих определений функций 107
  • 108. env var_fn='() { <your function> }' 108
  • 109. Ошибка разбора и импорта определения функции приводила к выполнению кода, следующего за определением функции прямо во время импорта 109
  • 110. env var_fn='() { <your function> }; <attacker code here>' 110
  • 111. Переменные состояния часто являются производными потоков входных данных 111
  • 112. env var_fn='() { ignore this;}; echo vulnerable' bash -c /bin/true 112
  • 113. Проще перечислить, какие системы/сервисы не были подвержены Shellshock 113
  • 114. Классификация Классификация уязвимостей возможна по: ― предметной области; // защищенность приложения ― недостатку; // неэффективное подтверждение аутентичности источника потока вычисления ― потоку вычисления; // интерпретация HTTP-запроса, приводящего к изменению состояния приложения ― угрозе; // нарушение аутентичности // уязвимость к атакам CSRF
  • 115. Классификация Классификация уязвимостей возможна по: ― предметной области; // онлайн-торговля ― недостатку; // неэффективный контроль использования погашенных купонов на скидку ― потоку вычисления; // транзакция оплаты заказа ― угрозе; // нарушение авторизованности // уязвимость к атакам на бизнес-логику (повторное использование купонов на скидку)
  • 116. Классификация Классификация уязвимостей возможна по: ― предметной области; // защищенность приложения ― недостатку; // неэффективный контроль операций прямой записи пользовательских потоков данных или их производных в память ― потоку вычисления; // интерпретация внутренних данных на стеке или куче ― угрозе; // нарушение целостности // уязвимость к атакам переполнения буфера
  • 118. Место действия: GNU C Library (glibc) -> nss/digits_dots.c -> __nss_hostname_digits_dots() 118
  • 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); 119
  • 120. Манипулируя потоком входных данных, атакующий имел возможность нарушить целостность потоков данных на стеке или в куче приложения 120
  • 121. Дополнительные условия ― hostname должен состоять из цифр и точек; ― первый символ hostname должен быть цифрой; ― последний символ hostname не должен быть точкой; ― hostname должен быть достаточной длины, чтобы вызвать переполнение; ― hostname должен успешно разбираться как IPv4 адрес функцией inet_aton(); 121
  • 122. С учетом всех ограничений, был разработан экплоит, для Exim, позволяющий обойти механизмы защиты ASLR и PIE и выполнить произвольный код в системе https://www.qualys.com/2015/01/27/cve-2015-0235/exim_ghost_bof.rb 122
  • 123. Резюмируя: как разрабатывать защищенные приложения, не сходя при этом с ума? 123
  • 124. 124
  • 125. Перестать следовать шаблонам Обеспечить адекватный контроль всех инвариантов Application Security и предметной области приложения 125