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

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

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

Доклад Владимира Кочеткова (Positive Technologies), посвященный системному подходу к устранению уязвимостей такого типа как инъекции, на Security Meetup Mail.ru Group.

Positive Development User Group

September 25, 2017
Tweet

More Decks by Positive Development User Group

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