Защита баз данных

Автор работы: Пользователь скрыл имя, 02 Октября 2009 в 19:14, Не определен

Описание работы

В реферате содержится информация о современных методах защиты баз данных.

Файлы: 1 файл

ЯП.docx

— 217.65 Кб (Скачать файл)

       Еще один метод определения версии MySQL сервера состоит в использовании  функции version(), которая возвращает строку с текущей версией. Этот метод  можно применять в случаях, если какие либо причины мешают использовать предыдущий метод. Например, происходит фильтрация символов /.

       К примеру, если запрос http://localhost/test.php?id=1+AND+(version()+like+’4%’) возвратит страницу, соответствующую  идентификатору id=1, то можно однозначно судить о том, что MySQL сервер имеет  четвертую версию.

       Если  применение кавычек мешает фильтрация, то вместо строки можно использовать функцию, которая в качестве значения вернет необходимую строку. Можно  использовать char(), функцию, которая  возвращает строку, соответствующую  из символов с ASCII кодами которые приняты  в качестве аргументов.

       Пример. Запрос http://localhost/test.php?id=1+AND+(version()+like+char(25,34)), будет аналогичен предыдущему, но не будет содержать кавычек.

       Пользуясь этим примером можно выявить и  полную версию СУБД MySQL, либо последовательно  подбирая все символы, либо пользуясь  дихотомическим поиском, используя  сравнение строк в лексикографическом порядке.

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

       Даже, если инъекция происходит в произвольном запросе в произвольном месте, выяснить MySQl это или нет, и версию MySQL аналогичным  образом можно, например внедряя  внутри этих скобок значения, которые  однозначно “испортят” запрос.

       http://localhost/test.php?id=1+/*!40000+AND+blablabla+*/, и нападающий сможет узнать, выполнились  ли инструкции (которые не являются  синтаксически верными инструкциями MySQL), или нет, по тому, нормально  функционирует скрипт при таком  запросе (инструкции были восприняты  как комментарий), или нет (инструкции  были проинтерпретированы как  часть запроса).

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

       Инъекция  после where

       SQL инъекция после ключевого слова  where является одним из наиболее  распространенных случаев. SQL запрос  в этом случае имеет примерно  следующий вид select … from … where … rowN=$row …, где вставляется  в запрос без надлежащей фильтрации.

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

       Допустим  имеет место SQL инъекция в скрипте http://localhost/test.php?id=1, который выводит  в броузер некоторую информацию о соответствующем пользователе. Естественно, пароль пользователя не выводиться. Покажем, каким образом в MySQL 3 можно  узнать как пароль произвольного  пользователя, так и пароль целевого пользователя. Считаем, что пароль храниться  в открытом виде в той же таблице, в которой и хранятся и остальные  параметры пользователя. Те, имя  этой таблицы явно участвует в  запросе.

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

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

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

       Вряд  ли, более чем в одной таблице  будут присутствовать такие столбцы, как login или pass и т.п, так что подбирать  имя таблицы в большинстве  случаев не необходимо.

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

       http://localhost/test.php?id=1+or+password=’abc’

       http://localhost/test.php?id=1+or+pass=’abc’

       http://localhost/test.php?id=1+or+passwd=’abc’

       http://localhost/test.php?id=1+or+u.password=’abc’

       http://localhost/test.php?id=1+or+user.password=’abc’

       

       Если  результатом одного из представленных запросов будет страница, идентичная странице с переданным идентификатором id=1, то это будет свидетельствовать  о том, что имя столбца, и, возможно, имя таблицы найдено успешно.

       Допустим, интересующее нас имя столбца  – pass,те второй запрос вернул положительный  результат.

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

       http://localhost/test.php?id=9999999+or+pass+like+’a%’  (-)

       http://localhost/test.php?id=9999999+or+pass+like+’b%’  (-)

       

       http://localhost/test.php?id=9999999+or+pass+like+’p%’  (+)

       http://localhost/test.php?id=9999999+or+pass+like+’pa%’  (+)

       http://localhost/test.php?id=9999999+or+pass+like+’paa%’  (-)

       

       http://localhost/test.php?id=9999999+or+pass+like+’pas%’  (+)

       

       http://localhost/test.php?id=9999999+or+pass+like+’pas21m1%’  (+)

       http://localhost/test.php?id=9999999+or+pass+like+’pas21m1_%’  (-)

       Запись, соответствующая идентификатору 9999999, не существует в базе данных, в этом стоит убедиться заранее.

       Плюсом  отмечен положительный результат  запроса. Положительным считается  результат, выводящий параметры  хоть какого то пользователя в броузер. Отрицательный (-) результат имеет  место в случае, если выведена страница, идентичная передачи id=9999999, те пустая страница.

       При этом может выводиться как один результат, так и несколько (все найденные), в зависимости от того, как написан  скрипт. Вывод параметров какого либо пользователя в броузер при каком  либо запросе следует интерпретировать именно как то, что его пароль удовлетворяет этим условиям.

       То  что предпоследний запрос выдал  положительный результат, а последний  – отрицательный следует интерпретировать, что все символы пароля успешно  подобраны. Действительно, если бы остался  неподобранным хотя бы один символ справа то он совпал бы с символом нижнего  слеша, а, возможно, остальные символы  совпали бы с символом процент.

       При подборе символов пароля таким способом следует помнить, что в пароле могут присутствовать как символы  английского алфавита, так и цифры  и другие символы. В случае, если в пароле присутствует символ _ или %, то при их подборе внутри like, эти  символы следует мнемонизировать  обратной косой.

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

       Действительно, в описанной нами ситуации скорее всего будет выведен первый случайный  пользователь, пароль которого удовлетворяет  данным условиям. А о том, удовлетворяют  эти условия целевому пользователю или нет мы никогда не узнаем, так он должен был бы вывестись  вторым.

       Те, если выводятся все результаты запроса, либо, играя с limit, все же можно  узнать пароль целевого пользователя, но это может быть сопряжено с  некоторыми трудностями.

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

       Например, идентифицировать некоторую запись администратора можно было бы так:

       http://localhost/test.php?id=9999999+or+(id=1), или

       http://localhost/test.php?id=9999999+or+(login=’admin’)

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

       http://localhost/test.php?id=9999999+or+(id=1+AND+pass+like+’a%’) http://localhost/test.php?id=9999999+or+(id=1+AND+pass+like+’b%’)

       и так далее.

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

       http://localhost/test.php?id=9999999+or+(id=1+AND+pass+>=+’k’) (-)

       http://localhost/test.php?id=9999999+or+(id=1+AND+pass+>=+’g’) (+)

       http://localhost/test.php?id=9999999+or+(id=1+AND+pass+>=+’h’) (-)

       http://localhost/test.php?id=9999999+or+(id=1+AND+pass+>=+’fk’)

       и так далее, последовательно перебирать каждую букву.

       Стоит отметить, что в любом описанном  в этой статье случае, строковую  константу, заключенную в кавычки, можно заменить на функцию char(), с  соответствующими аргументами.

       Инъекция  после order by

       В нередких случаях внедрение произвольного  кода возможна после ключевого слова order by. Наиболее часто подобная инъекция возможна, когда скрипт принимает  в качестве параметра имя столбца, по которому следует произвести упорядочивание, и вставляет его в запрос без  предварительной фильтрации.

       Так как ключевое слово where согласно синтаксису SQL должно находиться перед order by, таким  образом, невозможно внедрение булевых  функций, ограничивающих вывод с  целью получения информации о  значениях некоторых записей.

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

       Допустим, скрипт http://localhost/test2.php?order=id выводит  список пользователей системы, упорядочив их по id, причем значение переменной order вставляется в скрипт без надлежащей фильтрации.

       Стоит вспомнить, что в MySQL булевы значения приводятся к целым значениям, соответственно 0 и 1.

       Заметим следующую особенность, http://localhost/test2.php?order=(-id*1) упорядочит строки от большего id к меньшему, и это понятно, так как упорядочивание происходит по противоположной функции.

       Одновременно http://localhost/test2.php?order=(-id*0) выведет записи в естественном порядке, без всякого  упорядочивания. Скорее всего, это будет  тот порядок, в котором записи добавлялись в базу данных, и скорее всего, это будет порядок по возрастанию id. Это поведение также объяснимо. В этом случае упорядочивание происходит по функции, которая константно равна  нулю на всем множестве полей, те, для  любой записи в БД, значение (-id*0) одинаково и равно нулю. Т.е, никакого упорядочивания произведено не будет.

Информация о работе Защита баз данных