#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. Но на случай, если кто-нибудь знает о допустимых подзапросах, которые могут помочь мне достичь цели, пожалуйста, опубликуйте.
Редактировать: следовало бы также добавить это.
В системе уже есть несколько защит.
- Это значение передается в SP как параметризованное значение.
Но в целом есть одна слабость
-
Единственное слабое место, которое я вижу, которое я пытаюсь использовать, — это построение строки 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 — это просто использовать параметризованные запросы, а не создавать операторы с конкатенацией строк из ненадежных источников.