Download - Современные подходы к SAST

Transcript
Page 1: Современные подходы к SAST
Page 2: Современные подходы к SAST

Современные подходы к SAST

Владимир КочетковCompilable Applications Analyzers Development / Team Lead

Positive Technologies

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

Page 3: Современные подходы к SAST

Disclaimer

Контент данного доклада предоставляется на правах грязной фантазии на тему SAST и, хотя он действительно имеет пересечение с PT AI, речь пойдет не столько о конкретном проекте, сколько о технологиях, которые лежат и/или могли бы лежать в его основе.

Page 4: Современные подходы к SAST

Идеальный сферический SAST в вакууме:

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

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

― поддержка нескольких подходов к статическому анализу;

― работа с невалидным исходным кодом;

Page 5: Современные подходы к SAST

Идеальный сферический SAST в вакууме:― «еще один SAST, только лучше» - не нужен, нужен ?AST, с

требованиями SAST, но лишенный его ограничений, накладываемых тьюринговой моделью вычислений;

― анализ по универсальному представлению кода, в которое будут транслироваться исходники на всех поддерживаемых языках;

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

Page 6: Современные подходы к SAST

Теоретические пределы SAST

«Не существует программы, разрешающей нетривиальные свойства программ» - теорема Райса-Успенского

Page 7: Современные подходы к SAST

Теоретические пределы SAST

«Не существует программы, разрешающей нетривиальные свойства программ» - теорема Райса-Успенского

==«Статический анализ защищенности программы невозможен»

Page 8: Современные подходы к SAST

Теоретические пределы SAST

«Не существует программы, разрешающей нетривиальные свойства программ» - теорема Райса-Успенского

==«Статический анализ защищенности программы невозможен»

Но «программа» != «реальное приложение»

Page 9: Современные подходы к SAST

Проблема останова (внезапно) разрешима для:― малых машин Тьюринга TM(k,l): k=2,l=3 ; k=2,l=2 ; k=3,l=2 ;

k=4,l=2 , где k - число состояний, l – количество символов входного алфавита;

Page 10: Современные подходы к SAST

Проблема останова (внезапно) разрешима для:― малых машин Тьюринга TM(k,l): k=2,l=3 ; k=2,l=2 ; k=3,l=2 ;

k=4,l=2 , где k - число состояний, l – количество символов входного алфавита;

― программ машины Тьюринга с ограниченной памятью или стековых автоматов с ограниченным стеком: поиск циклов в графе состояний эквивалентного конечного автомата с Sn*x вершинами, где S – размер входного алфавита, n – объем памяти, x – число допустимых состояний программы;

Page 11: Современные подходы к SAST

Проблема останова (внезапно) разрешима для:― малых машин Тьюринга TM(k,l): k=2,l=3 ; k=2,l=2 ; k=3,l=2 ;

k=4,l=2 , где k - число состояний, l – количество символов входного алфавита;

― программ машины Тьюринга с ограниченной памятью или стековых автоматов с ограниченным стеком: поиск циклов в графе состояний эквивалентного конечного автомата с Sn*x вершинами, где S – размер входного алфавита, n – объем памяти, x – число допустимых состояний программы;

― произвольных конечных автоматов.

Page 12: Современные подходы к SAST

Следовательно, возможен и анализ защищенности для фрагментов кода, попадающих под эти критерии

Page 13: Современные подходы к SAST

Анализ в частных случаях― код без циклов и рекурсии -> конечный или стековый автомат;

― цикл или рекурсия, условие выхода которых не зависит от входных данных -> конечный или стековый автомат;

― цикл или рекурсия, условие выхода которых зависит от входных данных, ограниченной длины -> машина Тьюринга или стековый автомат с ограниченной памятью;

все остальное –> увы и ах (только динамика, только хардкор).

Page 14: Современные подходы к SAST

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

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

данных.

Пределы DAST

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

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

Page 15: Современные подходы к SAST

Но, разве кто-то сказал, что нужно выполнять ВСЮ программу?

Page 16: Современные подходы к SAST

«Выполнять отдельные фрагменты программы на всех возможных наборах их входных данных» – звучит, как план

Page 17: Современные подходы к SAST

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

Page 18: Современные подходы к SAST

Традиционные доступные представления― AST (абстрактное синтаксическое дерево);

― CFG (граф потока управления);

― DFG (граф потоков данных);

― PDG (граф зависимостей программы);

― CPG (граф свойств кода);

― ???

Page 19: Современные подходы к SAST

AST (абстрактное синтаксическое дерево)

Page 20: Современные подходы к SAST

CFG (граф потока управления)

Page 21: Современные подходы к SAST

DFG (граф потока данных)

Page 22: Современные подходы к SAST

DFG (граф потока данных)

Page 23: Современные подходы к SAST

DFG (граф потока данных)

Page 24: Современные подходы к SAST

DFG (граф потока данных)

Page 25: Современные подходы к SAST

DFG (граф потока данных)

Page 26: Современные подходы к SAST

DFG (граф потока данных)

Page 27: Современные подходы к SAST

DFG (граф потока данных)

Page 28: Современные подходы к SAST

PDG (граф зависимостей программы)

Page 29: Современные подходы к SAST

CPG (граф свойств кода)

Page 30: Современные подходы к SAST

Даже CPG не представляет достаточной информации для верификации результатов анализа

Page 31: Современные подходы к SAST

Нужно дополнить CPG информацией, необходимой для построения экплоитов и патчей/рекомендаций по исправлению

Page 32: Современные подходы к SAST

Возможные типы статического анализа― Сигнатурный (по AST, сводится к задаче о поиске поддеревьев

в дереве):• быстрый, даже при полном переборе;• не учитывает семантику кода;

― Классический taint-анализ (по CPG, сводится к задачам обхода графа и поиска в нем путей):• просто быстрый;• не учитывает условия достижимости, работает только с

известными функциями;― Анализ модели вычисления (по дополненному CPG и DFG,

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

незнакомыми функциями;• экспоненциально медленный.

Page 33: Современные подходы к SAST

Построение унифицированного представления кода и сигнатурный анализ

(Иван Кочуркин)

Page 34: Современные подходы к SAST

Taint-анализ

Page 35: Современные подходы к SAST

Taint-анализvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

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

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

Response.Write(str1);}

Page 36: Современные подходы к SAST

Taint-анализvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

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

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

Response.Write(str1);}

Page 37: Современные подходы к SAST

Taint-анализvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

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

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

Response.Write(str1);}

Page 38: Современные подходы к SAST

Taint-анализvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

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

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

Response.Write(str1);}

Page 39: Современные подходы к SAST

Taint-анализvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

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

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

Response.Write(str1);}

Page 40: Современные подходы к SAST

Taint-анализvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

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

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

Response.Write(str1);}

Page 41: Современные подходы к SAST

Taint-анализvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

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

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

Response.Write(str1);}

Page 42: Современные подходы к SAST

Taint-анализvar name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];

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

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

Response.Write(str1);}

Page 43: Современные подходы к SAST

― невозможно автоматизировать верификацию результатов;

― не учитываются условия достижимости опасной операции;

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

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

Недостатки taint-анализа

Page 44: Современные подходы к SAST

Абстрактная интерпретация: символическое выполнение

Page 45: Современные подходы к SAST

AI, SE и PE

Абстрактная интерпретация (AI) – интерпретация семантики кода без его выполнения в рамках некоторой семантической модели.

Символическое выполнение (SE) – абстрактная интерпретация кода в рамках семантической модели потоков данных и потоков управления.

Частичное выполнение (PE) – конкретное выполнение отдельных фрагментов кода в заданном контексте.

Page 46: Современные подходы к SAST

SE на пальцах

(x – неизвестная переменная, sqrt – неизвестная функция)

2x^2 + 4 = 122x^2 = 12 - 42x^2 = 12 - 4x^2 = (12 - 4) / 2x = sqrt((12 - 4) / 2)x = sqrt((8) / 2)x = sqrt(4)x = 2

Page 47: Современные подходы к SAST

PT SEКонтекстуальное символическое выполнение – символическое выполнение кода с целью построения контекстуального графа символического выполнения (SECG).

SECG изоморфен CPG, но позволяет также получить формулу достижимости любых значений потоков данных в любой точке потока выполнения.

Формула достижимости опасных потоков данных в точке выполнения опасной операции – формула уязвимости.

По формуле уязвимости строится уравнение, решение которого позволяет построить контекстный вектор атаки.

Page 48: Современные подходы к SAST

Symbolic Execution Context Graph

ε �֜ {}

Page 49: Современные подходы к SAST

Symbolic Execution Context Graph

ε �֜ { parm' א { ε �֜ Request.Params["parm1"] } }

Page 50: Современные подходы к SAST

Symbolic Execution Context Graph

Request.Params["cond1"] == "true" �֜ { parm' א { ε �֜ Request.Params["parm1"] } }

Page 51: Современные подходы к SAST

Symbolic Execution Context Graph

Request.Params["cond1"] != "true" �֜ { parm' א { Request.Params["cond1"] != "true" �֜ Request.Params["parm1"] } }

Page 52: Современные подходы к SAST

Symbolic Execution Context Graph

Request.Params["cond1"] != "true" && Request.Params["cond2"] == "true" �֜ { parm' א { Request.Params["cond1"] != "true" �֜ Request.Params["parm1"] } }

Page 53: Современные подходы к SAST

Symbolic Execution Context Graph

Request.Params["cond1"] != "true" && Request.Params["cond2"] != "true" �֜ { parm' א { Request.Params["cond1"] != "true" �֜ Request.Params["parm1"] } }

Page 54: Современные подходы к SAST

Symbolic Execution Context Graph

Request.Params["cond1"] != "true" �֜ { parm' א { Request.Params["cond2"] == "true" �֜ Request.Params["parm2"] || Request.Params["cond2"] != "true" �֜ "<div>Harmless value</div>" } }

Page 55: Современные подходы к SAST

ОК, модель построена. Но как ее анализировать? Как строить формулы и для каких вершин?

Page 56: Современные подходы к SAST

Формальные признаки инъекции― Потенциально уязвимая операция PVO(text): операция прямой

или косвенной интерпретации текста text на формальном языке

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

― Существует и достижимо хотя бы одно множество таких значений элементов EP, при которых происходит изменение структуры синтаксического дерева значения text, достигающего PVO

Page 57: Современные подходы к SAST

Формализуемость уязвимостей к атакам

Строго формализуемые Слабо формализуемые Injections Access Control

Buffer Overflow Session ManagementHeap Overflow CSRFInteger Overflow Concurrency

Memory Management Domain(Logical)

… …

Page 58: Современные подходы к SAST

Request.Params["cond1"] != "true" �֜ { parm' א { Request.Params["cond2"] == "true" �֜ Request.Params["parm2"] || Request.Params["cond2"] != "true" �֜ "<div>Harmless value</div>" } }

Symbolic Execution Context Graph

По SECG для каждой PVO выводится формула уязвимости

Page 59: Современные подходы к SAST

Формула уязвимостиRequest.Params["cond1"] != "true" ⇒

Response.Write( "<a href=\"" + parm ∈ { Request.Params["cond2"] == "true" ⇒ Request.Params["parm2"] ; Request.Params["cond2"] != "true" ⇒ "<div>Harmless value</div>" } + "\">" )

Page 60: Современные подходы к SAST

Формула уязвимостиRequest.Params["cond1"] != "true" ⇒

Response.Write( "<a href=\"" + parm ∈ { Request.Params["cond2"] == "true" ⇒ Request.Params["parm2"] } + "\">" )

Page 61: Современные подходы к SAST

Формула уязвимостиRequest.Params["cond1"] != "true"&&Request.Params["cond2"] == "true" ⇒

Response.Write( "<a href=\"" + Request.Params["parm2"] + "\">" )

Page 62: Современные подходы к SAST

Формула уязвимостиRequest.Params["cond1"] != "true"&&Request.Params["cond2"] == "true" ⇒

Response.Write( "<a href=\"" + Request.Params["parm2"] + "\">" )

Значение Request.Params["parm2"], определяемое типом точки инъекции, приводит к выходу за пределы токена

Page 63: Современные подходы к SAST

<a href=" ">

Тип точки инъекции вычисляется синтаксической эвристикой в результате прохода по уязвимому выражению в обе стороны от

нее или с помощью парсеров дополненных грамматик

Вычисление типа точки инъекции

Page 64: Современные подходы к SAST

Формула уязвимостиRequest.Params["cond1"] != "true"&&Request.Params["cond2"] == "true" &&(Request.Params["parm2"] == "\"><script>alert(0)</script>" || Request.Params["parm2"] == "\"onmouseover=\"alert(0)") ⇒

Response.Write( "<a href=\"" + Request.Params["parm2"] + "\">" )

Page 65: Современные подходы к SAST

Формула уязвимостиRequest.Params["cond1"] != "true"&&Request.Params["cond2"] == "true" &&(Request.Params["parm2"] == "\"><script>alert(0)</script>" || Request.Params["parm2"] == "\"onmouseover=\"alert(0)") ⇒

Response.Write( "<a href=\"" + Request.Params["parm2"] + "\">" )

В результате нахождения значений неизвестных в условии формулы, строится

символический вектор атаки

м

м

Page 66: Современные подходы к SAST

Символический вектор атакиУязвимое выражение:"<a href=\"" + Request.Params["parm2"] + "\">"

Тип точки инъекции:HTML: 2-quoted attribute value

Векторные переменные:Request.Params["parm2"] = "\"><script>alert(0)</script>"

Условные переменные:Request.Params["cond1"] = "__AI_akhivldp"Request.Params["cond2"] = "true"

Page 67: Современные подходы к SAST

А как же ограничения тьюринговой модели?

Page 68: Современные подходы к SAST

Частичное выполнение и обратные функции

var name = Request.Params["name"];var key1 = Request.Params["key1"];var parm = Request.Params["parm"];var data = string.IsNullOrEmpty(parm) ? new char[0]: Convert.FromBase64String(parm);

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

Page 69: Современные подходы к SAST

Частичное выполнение и обратные функции

string.IsNullOrEmpty("<script>alert(/XSS/)</script") =>

str1 = Encoding.UTF8.GetString( Convert.FromBase64String( "<script>alert(/XSS/)</script" ) )

Page 70: Современные подходы к SAST

Частичное выполнение и обратные функции

true =>

str1 = Convert.ToBase64String ( Encoding.UTF8.GetBytes( "<script>alert(/XSS/)</script" ) )

Page 71: Современные подходы к SAST

Частичное выполнение и обратные функции

true =>

str1 = Convert.ToBase64String ( […] // массив непечатных байт )

Page 72: Современные подходы к SAST

Частичное выполнение и обратные функции

true =>

str1 = PHNjcmlwdD5hbGVydCgvWFNTLyk8L3NjcmlwdA==

Page 73: Современные подходы к SAST

Частичный фаззингПусть Tf – множество трансформирующих функций с известной семантикой с мощностью n.

Пусть С – множество всех сочетаний из n по k (k=1..3 хватит всем).

Тогда, для заданной строки s имеем возможных преобразований – элементов размеченного множества St.

Тогда, имея результат преобразования s с помощью исследуемой функции f, можем выполнить поиск его значения в St , тем самым, определяя семантику f.

Page 74: Современные подходы к SAST

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

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

Это позволит интерпретировать значительный процент циклов и рекурсивных вызовов.

Все прочие неинтерпретированные фрагменты должны быть включены в дополнительные условия уязвимости.

Page 75: Современные подходы к SAST

Вопросы?

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

[email protected]@kochetkov_v

Compilable Applications Analyzers Development / Team LeadPositive Technologies

Page 76: Современные подходы к SAST

Использованные материалы― «Modeling and Discovering Vulnerabilities with Code Property

Graphs», Fabian Yamaguchi , Nico Golde , Daniel Arp and Konrad Rieck, https://goo.gl/zSuq1U

― «Modeling Computer Insecurity», Sophie Engle, Sean Whalen and Matt Bishop, http://goo.gl/B9izbc

Page 77: Современные подходы к SAST