Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Итак, в вашем коде нашли уязвимость к инъекции... (mail.ru)

Итак, в вашем коде нашли уязвимость к инъекции... (mail.ru)

Слайды доклада с Security Meetup Mail.ru Group

Vladimir Kochetkov

September 15, 2017
Tweet

More Decks by Vladimir Kochetkov

Other Decks in Programming

Transcript

  1. Заголовок Positive Development User Group — сообщество разработчиков и других

    IT- специалистов, которые стремятся создавать безопасные приложения. https://t.me/ru_appsec Positive Development User Group
  2. Заголовок Руководитель отдела исследований по анализу защищённости приложений Positive Technologies

    AppSec- и CS-исследователь (формальные методы анализа и защиты кода) https://about.me/vladimir.kochetkov [email protected] :~$ whoami
  3. Заголовок • Информация об обнаруженной уязвимости, как правило, включает в

    себя: • Классификацию уязвимости • Оценку риска • Эксплоит или вектор атаки • Общие рекомендации по устранению Задача пентестера или багхантера – найти и сообщить о хотя бы одном возможном сценарии атаки на обнаруженную уязвимость Задача разработчика – сделать невозможными любые атаки на неё Вводные данные
  4. Заголовок 1. Понять суть уязвимости 2. Определить недостаток 3. Устранить

    недостаток 4. Подтвердить исправление План устранения уязвимости
  5. Заголовок if (Request.Params["cond1"] == "true") { return; } if (Request.Params["cond2"]

    == "true") { parm = Request.Params["parm"]; } else { parm = "//default/url"; } Response.Write($"<a href='//host/a/b/{parm}'>{parm}</a>"); Точка входа cond1 Точка входа cond2 Точка входа parm Точка выхода parm Граница окружения AppSec-модель приложения
  6. Заголовок $"<a href='//host/a/b/{parm}'>{parm}</a>" ../../c $"<a href='//host/a/b/../../c'>…" 'onclick='alert(0) $"<a href=''onclick='alert(0)'>…" '><script>alert(0)</script>

    $"<a href=''><script>alert(0)</script>…" <script>alert(0)</script> $"…<script>alert(0)</script></a>" Возможные векторы инъекции
  7. Заголовок Пусть: • PVF(tG ) – потенциально уязвимая точка выхода

    данных, выполнение которой приводит к разбору текста tG в соответствии с грамматикой G в синтаксическое дерево AST • A – множество AST, получаемых при разборе каждого возможного tG • D – множество входных данных • tG = f(x), x ∈ D Критерий уязвимости к атакам инъекции (1/2)
  8. Заголовок Тогда: приложение уязвимо к атакам инъекции, если в A

    содержится хотя бы одна пара неизоморфных (отличающихся друг от друга структурой) AST Критерий уязвимости к атакам инъекции (2/2)
  9. Заголовок Неизоморфные деревья разбора элементов De The Essence of Command

    Injection Attacks in Web Applications (http://web.cs.ucdavis.edu/~su/publications/popl06.pdf)
  10. Заголовок • Интерпретируемый код • Разметка • ID внешних ресурсов

    • Что угодно, с числом токенов > 1 Инъекция возможна в любые нетривиальные грамматики
  11. Заголовок Gcond1' = ANY Согласованность грамматик потоков данных (1/2) if

    (Request.Params["cond1"] == "true") { return; } if (Request.Params["cond2"] == "true") { parm = Request.Params["parm"]; } else { parm = "//default/url"; } Response.Write($"<a href='//host/a/b/{parm}'>{parm}</a>"); Gparm = ANY Gparm = URL Gparm = URL ∪ ANY Gcond2' = ANY
  12. Заголовок Gcond1' = ANY Согласованность грамматик потоков данных (2/2) if

    (Request.Params["cond1"] == "true") { return; } if (Request.Params["cond2"] == "true") { parm = Request.Params["parm"]; } else { parm = "//default/url"; } Response.Write($"<a href='//host/a/b/{parm}'>{parm}</a>"); Gparm = ANY Gparm = URL Gparm = URL ∪ ANY Gcond2' = ANY
  13. Заголовок Недостаток, приводящий к инъекции • Причиной инъекции всегда является

    несогласованность грамматик входных и выходных данных • Для устранения недостатка необходимо её обеспечить
  14. Заголовок • Входные данные должны согласовываться с бизнес-логикой приложения за

    счёт: • Типизации • Валидации • Синтаксической • Семантической • Выходные данных должны согласовываться с грамматикой принимающей стороны за счёт санитизации Подходы к согласованию грамматик
  15. Заголовок Синтаксическая валидация – проверка строковых данных на соответствие какой-либо

    грамматике: var url_regex = "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?"; if (!Regex.IsMatch(Request.Params["url"], url_regex)) { throw new ValidationException(); } Синтаксическая валидация
  16. Заголовок Семантическая валидация – проверка строковых данных на корректность с

    точки зрения логики приложения: var request = WebRequest.Create(Request.Params["url"]) { Method = "HEAD" }; if (request.GetResponse().StatusCode != HttpStatusCode.OK) { throw new ValidationException(); } Семантическая валидация
  17. Заголовок Санитизация – преобразование строковых данных к формату какого-либо токена

    заданной грамматики var parm_text = Request.Params["parm"]; var parm_1 = HtmlEncode(UrlEncode(parm_text)); var parm_2 = HtmlEncode(parm_text); Response.Write( $"<a href='//host/a/b/{parm_1}'>{parm_2}</a>" ); Санитизация
  18. Заголовок В случае вложенных грамматик, например: t, t ∈ De

    ⇒ JavaScriptstring ⇒ HTMLattribute , санитизацию необходимо проводить последовательно, в обратном порядке: EncodeHTML (EncodeJavaScript (t)) Санитизация вложенных грамматик
  19. Заголовок • Входные данные – как можно ближе к точке

    их входа, с учётом: • принципа необходимости и достаточности их грамматик; • приоритетности подходов: 1. типизация; 2. семантическая валидация; 3. синтаксическая валидация. • Выходные данных – как можно ближе к точке их выхода, с учётом: • грамматики принимающей стороны; • возможной вариативности их грамматик в различных точках выполнения; • минимального (в идеале – нулевого) влияния согласования на прочие ветки потока вычисления. Точки согласования грамматик: правила
  20. Заголовок • Параметризация (типизация данных в точке выхода) • Использование

    встраиваемого RASP (санитизация и валидация в точке выхода) Точки согласования грамматик: исключения
  21. Заголовок Gcond1' = BOOL Пример согласования грамматик if (bool.Parse(Request.Params["cond1"])) {

    return; } if (bool.Parse(Request.Params["cond2"])) { parm = Request.Params["parm"]; } else { parm = "//default/url"; } Response.Write( $"<a href='//host/a/b/{HtmlEncode(UrlEncode(parm))}'>{HtmlEncode(parm)}</a>"); Gparm = ANY Gparm = URL Gparm = URL ∪ HTMLtext Gcond2' = BOOL
  22. Заголовок LibProtection – библиотека с открытым кодом (под MIT- лицензией),

    позволяющая встроить в приложение защиту от атак инъекций, за счёт: • Автоматической санитизации входных данных там, где это возможно • Автоматической валидации входных данных относительно выходной грамматики там, где невозможна санитизация LibProtection (1/4)
  23. Заголовок Поддерживаемые языки: • C#, F#, Nemerle, VB.NET, C++ (Q4

    2017) • PHP, Java, Scala, Groovy, Kotlin (Q1 2018) • Python, Ruby, Go (H2 2018) Поддерживаемые грамматики: SQL (Microsoft SQL Server, Oracle, Database, Oracle MySQL), HTML, EcmaScript, CSS, URL, Path, XML LibProtection (2/4)
  24. Заголовок • Векторы от пентестеров и багхантеров – не использовать!

    http://host/entry_point/?name=%2f..%2fWeb.Config File.Delete($"\\temp_data\\{name}"); • Использовать набор векторов атаки, приводящих к ошибке парсинга: "\..\filename?", “<filename>" и т.п. • Каждый вектор – отдельный тест-кейс на отсутствие исключений при передаче модулю в качестве входных данных Юнит-тестирование инъекций: exceptions-based
  25. Заголовок • Используется любой набор векторов атаки и токенизатор соответствующей

    грамматики • Перед каждой PVF устанавливается утверждение на количество токенов в её аргументе: var pvfArgument = $"\\temp_data\\{name}"; Debug.Assert(Tokenize(pvfArgument) == 4); File.Delete(pvfArgument); • Каждый вектор – тест-кейс на отсутствие нарушения утверждений. Юнит-тестирование инъекций: tokenization-based