Внедрение SQL — допустимых подзапросов в T-SQL В

#sql-server #sql-injection

#sql-сервер #sql-инъекция

Вопрос:

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

Обычный синтаксис оператора таков

 select * from tableX where ID IN (select userId from tableY where colX='Y')
  

Я бы хотел передать sql stmt через querystring, чтобы удалить всех пользователей в таблице.

Возможно ли это сделать, если этот введенный sql выполняется в операторе IN.

Это то, чего я хочу достичь

 select * from tableX where ID IN (delete tableY) 
  

или

 select * from tableX where ID IN (update tableX set ID=100 where 1=1)
  

или

 select * from tableX where ID IN  (exec(N'delete tableY'))
  

Я продолжаю получать странные синтаксические ошибки. Может быть, это не соответствует спецификации sql. Но на случай, если кто-нибудь знает о допустимых подзапросах, которые могут помочь мне достичь цели, пожалуйста, опубликуйте.

Редактировать: следовало бы также добавить это.

В системе уже есть несколько защит.

  1. Это значение передается в SP как параметризованное значение.

Но в целом есть одна слабость

  1. Единственное слабое место, которое я вижу, которое я пытаюсь использовать, — это построение строки sql в SP с использованием переданного значения.

    установите @where = @where ‘ИДЕНТИФИКАТОР В (‘ @htmlEncodedParametrizedParam ‘)

Итак, все, что мне нужно для взлома этого кода, — это отправить только чистую строку sql (no ; или ), которая может использоваться в операторе IN .

Edit2: закодировано для проверки ответа @Dan. Безрезультатно.

 Create procedure HackTest 
  @qsVal nvarchar(200) = ''
As
Begin 
    declare @sql as nvarchar(1000)
    set @sql = 'select * from AdventureWorks2008.Person.Person'   'where PersontType IN ('   @qsVal   ')'
    exec sp_executesql @sql
end
  

Ниже приведен запрос и то, что профилировщик MS Sql server записал для этих запросов

 --http://localhost:11727/SampleSite/Default.aspx?a=NULL);delete tableY;--
exec hackTest @qsVal='NULL);delete tableY;--'

--http://localhost:11727/SampleSite/Default.aspx?a=NULL);update tableX set ID=100;--
exec hackTest @qsVal='NULL);update tableX set ID=100;--'
  

Комментарии:

1. Обычно люди пытаются узнать о том, как предотвратить атаки с использованием SQL-инъекций. Интересно, что вы спрашиваете, как его достичь… Если ваш вопрос вызван неуверенностью в том, находится ли ваш существующий внешний запрос под угрозой такой атаки, я предлагаю вам вложить свою энергию в его защиту от инъекций. Однако, если вы действительно планируете атаку, я еще не уверен, что вы заслуживаете помощи… В любом случае это интересная головоломка.

2. @stakx- я взламываю себя :). Крайние случаи.

3. Хорошо, пока вы делаете это ради удовольствия … иначе вы бы потратили свое время. В конце концов, существуют довольно простые способы предотвращения атак с использованием SQL-инъекций.

4. @htmlEncodedParametrizedParam ? Почему в нем указано кодирование html ?

5. Попробуйте включить события sp:stmtcompleted, чтобы увидеть, что делает ваш SP. Это выдает ошибку или просто ничего не делает?

Ответ №1:

Нет, IN оператор разрешает только подзапрос или список выражений:

 test_expression [ NOT ] IN 
    ( subquery | expression [ ,...n ]
    ) 
  

Таким образом, вы не можете использовать DELETE UPDATE там оператор or, а только SELECT оператор.

Однако, поскольку SQL Server поддерживает пакеты, вы можете просто добавить свой собственный оператор после SELECT оператора:

 SELECT … ; DELETE 

Ответ №2:

вы можете имитировать несколько запросов, например, это ваш запрос, параметр будет заменен позже вашей программой:

 SELECT * FROM tableX WHERE ID IN (<somestring>)
  

если вы должны были заменить этим текстом:

 1); DROP TABLE tableY;--
  

вы получите исполняемый запрос, подобный этому:

 SELECT * FROM tableX WHERE ID IN (1); DROP TABLE tableY;--)
  

Ответ №3:

Если приложение создает оператор SQL с конкатенацией строк, например:

 selectQuery = "select * from tableX where ID IN ("   queryString   ")";
  

Эту конкретную уязвимость SQL injection можно использовать, добавив «NULL);», за которым следует вводимый оператор SQL, а затем маркер комментария. Пример строковых значений запроса:

 NULL);delete tableY;--
NULL);update tableX set ID=100;--
  

Конечно, никогда не следует передавать инструкцию SQL через строку запроса. Лучшая защита от внедрения SQL — это просто использовать параметризованные запросы, а не создавать операторы с конкатенацией строк из ненадежных источников.