Обнаружение уязвимостей в webприложениях, написанных на Python, средствами динамического анализа исходных кодов Заливин Д.А. Козлов Д.Д. Петухов А.А. Наиболее распространенные вебуязвимости 70% сайтов открыты для взлома* *IEEE Security and Privacy, vol.4, no.4 2006 2 Пример уязвимости S1: $skip = $_GET["skip"]; S2: if ($skip < 0) S3: $skip = 0; S4: $QueryOffset = $skip. ", 10"; S5: mysql_connect(); S6: mysql_select_db("myDB"); S7: $request= "SELECT fld_Text FROM news LIMIT ".$QueryOffset; S8: $result=mysql_query($request); Нормальный запрос: SELECT fld_Text FROM news LIMIT 0, 10 Однако при skip=“10; DELETE FROM news;” будет выполнен запрос: SELECT fld_Text FROM news LIMIT 10; DELETE FROM news; 3 Существующие методы обнаружения уязвимостей Тестирование на проникновение Динамический анализ Задаются шаблоны значений HTTP-параметров Задаются шаблоны ожидаемых ответов Проводится сканирование Tainted mode Есть для Perl, Ruby, PHP Статический анализ Tainted mode на графе потоков данных программы Есть для Java, PHP 4 Цель работы Выявление уязвимостей, связанных с некорректной обработкой входных данных в web-приложениях на языке Python посредством динамического анализа исходных кодов 5 Предположения Все данные, полученные через HTTP-запросы, считаются ненадежными Все ресурсы, локальные по отношению к webприложению, считаются надежными Ненадежные данные могут стать надежными вследствие специальной обработки 6 Уязвимость Ненадежные данные не должны использоваться при построении HTTP-ответов Ненадежные данные не должны сохраняться в локальных хранилищах данных Ненадежные данные не должны использоваться при конструировании команд к внешним по отношению к Web-приложению сервисам Ненадежные данные не должны использоваться при формировании исходного кода для интерпретации на лету 7 Tainted mode S1 $skip S2 S1: $skip = $_GET["skip"]; S2: if ($skip < 0) S3: $skip = 0; $skip S3 S4 $skip S4: $QueryOffset = $skip. ", 10"; S5: mysql_connect(); S6: mysql_select_db("myDB"); $QueryOffset S5 S6 S7: $request= "SELECT fld_Text FROM news LIMIT ".$QueryOffset; S8: $result=mysql_query($request); S7 $request Поток управления Поток данных S8 8 Tainted mode Конфигурация Список конструкций, возвращающих ввод пользователя параметры запросов, значения cookie, заголовки запросов в примере: массив $_GET Список критических к вводу функций работа с СУБД, ФС, почтой, интерпретатором ОС системные вызовы вывод HTML в браузер клиента в примере: mysql_connect, mysql_select_db, mysql_query Список конструкций, фильтрующих ввод пользователя кодирование служебных символов (> &gthn;) экранирование служебных символов (“ \”) приведение к типу (строку к целому) в примере: $Skip = 0 9 Tainted mode Алгоритм S8 mysql_query Алгоритм: Для каждого аргумента каждой критической к вводу функции Fj построить граф зависимостей по данным В каждом графе выделить пути от корня Fj ко всем переменным, инициализируемым от пользовательского ввода, Xi Если среди выделенных путей существует путь без вершины с фильтрацией ввода, сигнализировать о возможной уязвимости Уязвимость - это отсутствие проверки для входного параметра Xi относительно критической к вводу функции Fj, {(Xi, Fj)} S6 S4 S3 S1 $skip=0 $skip=$_GET[“skip”] 10 Реализация 1) 2) 3) 4) 5) Модификация встроенных строковых типов Присваивание входным данным метки Taint Распространение метки Taint Снятие метки Taint Реагирование на Taint данные 11 Модификация встроенных типов Встроенные в язык Python структуры для представления строк дополнены полем меткой Taint, сигнализирующей, прошла ли эта строка проверку на корректность или нет 12 Присваивание входным данным метки Taint Строка, полученная от пользователя Помечена как Taint Internet UserString = req.readline() True Str=“Строковая константа” False Флаг Taint устанавливается, если строковая переменная инициализируется от данных HTTPзапроса 13 Распространение метки Taint Строка, полученная от пользователя Помечена как Taint Internet UserString = req.readline() True Str=“Строковая константа” False ConcSrt = UserString + Str ConcStr True - Если при конкатенации хотя бы одна строка имеет флаг Taint, то результат также будет иметь флаг Taint Флаг Taint устанавливается, если строковая переменная получает свое значение от других переменных с поднятым флагом taint 14 Снятие метки Taint Строка, полученная от пользователя Помечена как Taint Internet UserString = req.readline() True Str=“Строковая константа” False ConcSrt = UserString + Str Обработка строки ConcStr True ConcSrt.sanitize() ConcStr False - Если при конкатенации хотя бы одна строка имеет флаг Taint, то результат также будет иметь флаг Taint После проверки на коррректность метка Taint со строки снимается Флаг Taint снимается, если строковая переменная проходит функцию проверки на корректность данных 15 Реагирование на Taint данные Строка, полученная от пользователя Помечена как Taint Internet UserString = req.readline() True Str=“Строковая константа” False ConcSrt = UserString + Str Чувствительная функция ConcStr True ConcSrt.sensitive() Exception Если при конкатенации хотя бы одна строка имеет флаг Taint, то результат также будет иметь флаг Taint Если taint-строка попадает в критическую функцию, то генерируется исключение 16 Результаты 1) 2) 3) Разработан метод динамического анализа для обнаружения уязвимостей, связанных с некорректной обработкой пользовательского ввода Произведена его реализация путем модификации интерпретатора Python Проведена настройка метода на специфику технологии mod_python 17 Tainted mode Недостатки метода Относительность «опасных» символов Реализация фильтрации пользователем Для различных критических к пользовательскому вводу функций опасны различные конструкции Существует много альтернативных способов произвести фильтрацию пользовательского ввода Ошибки в алгоритмах фильтрации Ручная перенастройка метода при применении различных фреймворков Поиск фильтрующих функций во фреймворке Поиск оберток критических функций во фреймворке 18 Спасибо за внимание! Вопросы? 19