Файл: Служба безопасности и аутентификации баз данных (Анализ сетевой защищенности СУБД Oracle).pdf
Добавлен: 29.03.2023
Просмотров: 99
Скачиваний: 1
«Двухэтажную» конструкцию Oracle полезно превратить в «трехэтажную». Такая конструкция существенно усложнит для криптоаналитика атаку с накоплением, основанную на парадоксе дней рождений, а также атаку с анализом промежуточных ключей.
Кроме того, «трехэтажная» конструкция замедлит скорость вычисления хеша, что замедлит скорость силовой атаки, и тем самым повысит стойкость криптосистемы. Это стандартное требование к хеш-функциям, гласящее, что «хеш-функция должна вычисляться медленно». Если хеш-функция вычисляется быстро, то хакер тоже ее вычислит быстро, и быстро осуществит перебор паролей. Медленный однонаправленный алгоритм не сильно замедлит одноразовое вычисление пароля, при подключении к БД, но существенно затруднит противнику перебор всевозможных паролей. Наиболее популярное решение - это многократное итеративное использование хеш-функций. Например, в Unix-системах однонаправленная функция шифрования применяется итеративно несколько раз, чтобы обеспечить достаточно большое время отклика.
- Не игнорировать различие между заглавными и строчными символами. В этом
пункте нет вообще никаких принципиальных сложностей. Расширение множества допустимых паролей позволит скомпенсировать на десяток-другой лет возможные успехи в вычислительной технике и криптоанализе.
После вышеописанных изменений криптосхему корпорации Oracle следует подвергнуть сертификации. Это повысит доверие к ПО Oracle. Для такого популярного продукта как СУБД Oracle официальное признание и подтверждение его надежности со стороны компетентных организаций является важным моментом, как при его эксплуатации, так и при продвижении на рынке. В худшем случае, слабое звено будет выявлено, и заменено более стойким.
В качестве варианта по построению защищенной СУБД, интересно было бы генерировать уникальное значение ключа для каждой инсталляции СУБД. Дело в том, что для некоторых ИС с повышенными требованиями к безопасности очень желательно иметь возможность скомпилировать своего собственного клиента с зашитым в нем уникальным ключом, т.е. клиента, способного подключаться только к своей «родной» БД, оснащенной таким же ключом. Понятно, что обычный клиент со стандартным ключом никогда не подключится к такой БД. Несмотря на все возникающие сложности, предлагаемая конструкция дает сильную гарантию безопасности информации в БД.
Для повышения безопасности нужно проводить аудит учетных записей на наличие стандартных паролей, периодически просматривать учетные записи на предмет использования и периодически отключать устаревшие, ввести как административные, так и программные ограничения на длину и сложность пароля.
Глава II. Анализ внутренней безопасности СУБД Oracle.
Главный источник угроз, специфичных для СУБД, лежит в самой природе баз данных. Основным средством взаимодействия с СУБД является язык SQL - мощный непроцедурный инструмент определения и манипулирования данными. Хранимые процедуры добавляют к этому репертуару управляющие конструкции. Механизм правил дает возможность выстраивать сложные, трудные для анализа цепочки действий, позволяя попутно неявным образом передавать право на выполнение процедур, даже не имея, строго говоря, полномочий на это. В результате потенциальный злоумышленник получает в свои руки мощный и удобный инструментарий, а все развитие СУБД направлено на то, чтобы сделать этот инструментарий еще мощнее и удобнее.
Обычно в СУБД применяется произвольное управление доступом, когда владелец объекта передает права доступа к нему (чаще говорят - привилегии) по своему усмотрению. Привилегии могут передаваться субъектам (отдельным пользователям), группам, ролям или всем пользователям.
Группа - это именованная совокупность пользователей. Объединение субъектов в группы облегчает администрирование баз данных и, как правило, строится на основе формальной или фактической структуры организации. Каждый пользователь может входить в несколько групп. Когда пользователь тем или иным способом инициирует сеанс работы с базой данных, он может указать, от имени какой из своих групп он выступает. Кроме того, для пользователя обычно определяют подразумеваемую группу.
Роль - это еще один возможный именованный носитель привилегий. С ролью не ассоциируют перечень допустимых пользователей - вместо этого роли защищают паролями. В момент начала сеанса с базой данных можно специфицировать используемую роль (обычно с помощью флагов или эквивалентного механизма) и ее пароль, если таковой имеется.
Привилегии роли имеют приоритет над привилегиями пользователей и групп. Иными словами, пользователю как субъекту не обязательно иметь права доступа к объектам, обрабатываемым приложениям с определенной ролью.
Отметим, что в СУБД Oracle под ролью понимается набор привилегий. Такие роли служат средством структуризации привилегий и облегчают их модификацию.
Совокупность всех пользователей именуется как PUBLIC. Придание привилегий PUBLIC - удобный способ задать подразумеваемые права доступа.
При анализе внутренней безопасности СУБД были выявлены такие проблемы, как редкий выход обновлений, нетривиальная установка и угроза серьезных сбоев при интеграции с другими системами после установки обновлений. Даже после обновлений более половины уязвимостей так и остаются незакрытыми, и получить аутентификационные данные не составляет труда.
2.1.Повышение привилегий
Повышение привилегий - это эксплуатация уязвимостей в компьютерной системе для получения доступа к ресурсам, которые обычно защищены от приложения или пользователя. Результатом является то, что приложение выполняет какие-либо действия в контексте безопасности другого пользователя, разработчика, системного администратора или суперпользователя.
Внедрение SQL-кода (SQL injection) — один из распространённых способов взлома сайтов и программ, работающих с базами данных, основанный на внедрении в запрос произвольного SQL-кода.
Внедрение SQL может дать возможность атакующему выполнить произвольный запрос к базе данных (например, прочитать содержимое любых таблиц, удалить, изменить или добавить данные), получить возможность чтения и/или записи локальных файлов и выполнения произвольных команд на атакуемом сервере.
Атака типа внедрения SQL может быть возможна из-за некорректной обработки входящих данных, используемых в SQL-запросах.
Разработчик прикладных программ, работающих с базами данных, должен знать о таких уязвимостях и принимать меры противодействия внедрению SQL.
2.2. Принцип атаки внедрения SQL.
Допустим, серверное ПО, получив входной параметр id, использует его для создания SQL-запроса. Рассмотрим следующий PHP-скрипт:
# Предыдущий код скрипта.$id = $_REQUEST['id'];
$res = mysql_query ("SELECT * FROM news WHERE id_news = $id");
# Следующий код скрипта...
Если на сервер передан параметр id, равный 5 (например, так: http://example.org/script.php?id=5), то выполнится следующий SQL-запрос:
SELECT * FROM news WHERE id_news = 5
Но если злоумышленник передаст в качестве параметра id строку -1 OR 1=1 (например, так: http://example.org/script.php?id=-1+OR+1=1), то выполнится запрос:
SELECT * FROM news WHERE id_news = -1 OR 1=1
Таким образом, изменение входных параметров путём добавления в них конструкций языка SQL вызывает изменение в логике выполнения SQL-запроса (в данном примере вместо новости с заданным идентификатором будут выбраны все имеющиеся в базе новости, поскольку выражение 1=1 всегда истинно).
2.3. Внедрение в строковые параметры.
Предположим, серверное ПО, получив запрос на поиск данных в новостях параметром search_text, использует его в следующем SQL-запросе (здесь параметры экранируются кавычками):
search_text = $_REQUEST ['search_text'];
res = mysql_query ("SELECT id_news, news_date, news_caption, news_text, news_id_author
FROM news WHERE news_caption LIKE ('%search_text%')");
Сделав запрос вида http://example.org/script.php?search_text=Test мы получим выполнение следующего SQL-запроса:
SELECT id_news, news_date, news_caption, news_text, news_id_author FROM news
WHERE news_caption LIKE ('%Test%')
Но, внедрив в параметр search_text символ кавычки (который используется в запросе), мы можем кардинально изменить поведение SQL-запроса. Например, передав в качестве параметра search_text значение ')+and+(news_id_author='1, мы вызовем к выполнению запрос:
SELECT id_news, news_date, news_caption, news_text, news_id_author FROM news
WHERE news_caption LIKE ('%') AND (news_id_author='1%')
Язык SQL позволяет объединять результаты нескольких запросов при помощи оператора UNION. Это предоставляет злоумышленнику возможность получить несанкционированный доступ к данным.
Рассмотрим скрипт отображения новости (идентификатор новости, которую необходимо отобразить, передается в параметре id):
res = mysql_query("SELECT id_news, header, body, author FROM news WHERE id_news = " . _REQUEST['id']);
Если злоумышленник передаст в качестве параметра id конструкцию -1 UNION SELECT 1,username,password,1 FROM admin, это вызовет выполнение SQL-запроса
SELECT id_news, header, body, author FROM news WHERE id_news = -1 UNION SELECT 1,username,password,1 FROM admin
Так как новости с идентификатором -1 заведомо не существует, из таблицы news не будет выбрано ни одной записи, однако в результат попадут записи, несанкционированно отобранные из таблицы admin в результате инъекции SQL.
2.4. Расщепление SQL-запроса.
Для разделения команд в языке SQL используется символ ; (точка с запятой), внедряя этот символ в запрос, злоумышленник получает возможность выполнить несколько команд в одном запросе, однако не все диалекты SQL поддерживают такую возможность.
Например, если в параметры скрипта \id = _REQUEST['id']; res = mysql_query("SELECT * FROM news WHERE id_news = id");
злоумышленником передается конструкция, содержащая точку с запятой, например 12;INSERT INTO admin (username, password) VALUES ('HaCkEr', 'foo'); то в одном запросе будут выполнены 2 команды
SELECT * FROM news WHERE id_news = 12;
INSERT INTO admin (username, password) VALUES ('HaCkEr', 'foo');
и в таблицу admin будет несанкционированно добавлена запись HaCkEr.
Предположим, что код, генерирующий запрос (на языке программирования Паскаль), выглядит так: statement := 'SELECT * FROM users WHERE name = "' + userName + '"; Чтобы внедрение кода было невозможно, требуется брать в кавычки все строковые параметры. В самом параметре заменяют кавычки на \", апостроф на \', обратную косую черту на \\ (это называется «экранировать спецсимволы»). Это можно делать таким кодом:
statement := 'SELECT * FROM users WHERE name = ' + QuoteParam(userName) + ';';
function QuoteParam(s : string) : string; { на входе — строка; на выходе — строка в кавычках и с заменёнными спецсимволами }var i : integer; Dest : string; begin Dest := '"'; for i:=1 to length(s) do case s[i] of '''' : Dest := Dest + '\'''; '"' : Dest := Dest + '\"'; '\' : Dest := Dest + '\\';
else Dest := Dest + s[i]; end; QuoteParam := Dest + ; end;
Для PHP фильтрация может быть такой: <? query = "SELECT * FROM users WHERE user='".mysql_real_escape_string(user)."'
2.5. Фильтрация целочисленных параметров.
Возьмём другой запрос:statement := 'SELECT * FROM users WHERE id = ' + id + ';';
В данном случае поле id имеет числовой тип, и его нельзя брать в кавычки. Поэтому «заковычивание» и замена спецсимволов на escape-последовательности не проходит. В таком случае помогает проверка типа; если переменная id не является числом, запрос вообще не должен выполняться. Например, на Delphi для противодействия таким инъекциям помогает код: id_int := StrToInt(id);
statement := 'SELECT * FROM users WHERE id = ' + IntToStr(id_int) + ';';
В случае ошибки функция StrToInt вызовет исключение EConvertError, и в его обработчике можно будет вывести сообщение об ошибке. Двойное преобразование обеспечивает корректную реакцию на числа в формате $132AB (шестнадцатеричная система счисления). На стандартном Паскале, не умеющем обрабатывать исключения, код несколько сложнее. Для PHP этот метод будет выглядеть так: query = 'SELECT * FROM users WHERE id = ' . intval(id).
Для внесения изменений в логику выполнения SQL-запроса требуется внедрение достаточно длинных строк. Так, минимальная длина внедряемой строки в вышеприведённых примерах составляет 8 символов ("1 OR 1=1"). Если максимальная длина корректного значения параметра невелика, то одним из методов защиты может быть максимальное усечение значений входных параметров.
Например, если известно, что поле id в вышеприведённых примерах может принимать значения не более 9999, можно «отрезать лишние» символы, оставив не более четырёх: statement := 'SELECT * FROM users WHERE id = ' + LeftStr(id, 4) + ';';
2.6. Использование параметризованных запросов.
Многие сервера баз данных поддерживают возможность отправки параметризованных запросов. При этом параметры внешнего происхождения отправляются на сервер отдельно от самого запроса либо автоматически экранируются клиентской библиотекой. Для этого используются
- на Delphi — свойство TQuery.Params;
Например var sql, param : string; begin sql := 'select :text as value from dual';
param := 'alpha'; Query1.Sql.Text := sql; Query1.ParamByName('text').AsString := param;
Query1.Open; ShowMessage(Query1['value']); end;
- на Perl — через DBI::quote или DBI::prepare;
- на Java — через класс PreparedStatement;
- на C# — свойство SqlCommand.Parameters;
- на PHP (при работе с MySQL) — функции mysql_escape_string, mysql_real_escape_string, addslashes.
- на Parser — язык сам предотвращает атаки подобного рода.
2.7. Обход Oracle dbms_assert.
Используя специально сформированные параметры (в двойных кавычках) можно обойти проверку правильности пакета dbms_assert и внедрить SQL код. Уязвимость можно эксплуатировать в большинстве версий Oralce (8.1.7.4 – 10.2.0.2), исправление появилось только в июле 2006 года.
Для защиты пакетов Oracle PL/SQL от большого количества SQL инъекции, Oracle разработал новый пакет пол названием dbms_assert в Oracle 10g Release 2. Этот пакет был ретропортирован с Oracle Critical Patch Update (CPU) в октябре 2005 года на все поддерживаемые базы данных (с 8.1.7.4 до 10.1.0.5).