SQL2000下非sysadmin固定服务器角色的成员执行xp_cmdshell
------------------------------------------------------
-- 11/11/2009 2:32:18 PM
-- Happyflystone
-- blog: http://blog.csdn.net/happyflystone
-- Microsoft SQL Server 2000 - 8.00.2039 (Intel X86)
-- May 3 2005 23:18:38
-- Copyright (c) 1988-2003 Microsoft Corporation
-- Personal Edition on Windows NT 5.2 (Build 3790: Service Pack 2)
-- 转载注明出处及相关信息。
------------------------------------------------------
首先我们增加一个login并缺省test_db数据库。
--add login
use master
Go
EXEC sp_addlogin 'njslt', 'njslt', 'test_db'
Go
use test_db
Go
EXEC sp_adduser 'njslt', 'njslt', 'db_owner'
Go
/*
这儿一定要执行以下的过程哦,否则会:
服务器: 消息229,级别14,状态5,过程xp_cmdshell,行1
拒绝了对对象'xp_cmdshell'(数据库'master',所有者'dbo')的EXECUTE 权限。
*/
use master
Go
EXEC sp_adduser 'njslt', 'njslt', 'db_ddladmin'
Go
GRANT exec ON xp_cmdshell TO njslt
GO
接着我们以njslt连接数据库,并打开查询分析器,执行如下角本:
exec master..xp_cmdshell 'dir c:'
/*
消息50001,级别1,状态50001
由于LogonUserW 返回错误1326,执行xp_cmdshell 失败。
请确保运行SQL Server 的服务帐户具有适当的特权。
有关详细信息,请在联机丛书中搜索与xp_sqlagent_proxy_account 相关的主题。
*/
好,问题出来了,默认情况下,只有 sysadmin 固定服务器角色的成员才能执行此扩展存储过程。但是,也可以授予其他用户执行此存储过程的权限。
当作为 sysadmin 固定服务器角色成员的用户唤醒调用 xp_cmdshell 时,将在运行 SQL Server 服务的安全上下文中执行 xp_cmdshell。当用户不是 sysadmin 组的成员时,xp_cmdshell 将模拟使用 xp_sqlagent_proxy_account 指定的 SQL Server 代理程序的代理帐户。如果代理帐户不能用,则 xp_cmdshell 将失败。这只是针对于 Microsoft® Windows NT® 4.0 和 Windows 2000。在 Windows 9.x 上,没有模拟,且 xp_cmdshell 始终在启动 SQL Server 的 Windows 9.x 用户的安全上下文下执行。
记得以前有人问题这个问题时,我当时想当然的回答了利用SETUSER来临时切换安全上下文,所以我第一反应想用这个来实现,结果发现失败了,那如何来解决这个问题呢。我做了两种方法,大家看看:
一、提升用户,加入固定服务器角色
根据联机帮助提示,xp_cmdshell只有是sysadmin固定服务器角色成员才可以,那我加它进sysadmin角色里,但是一定要注意sysadmin角色在SQLSERVER里可是能进行任何活动的哦,这是不是有安全隐患?
以SA登录执行:
exec sp_addsrvrolemember 'njslt', 'sysadmin'
GO
二、 模拟使用 xp_sqlagent_proxy_account 指定的 SQL Server 代理程序的代理帐户
DECLARE
@winuser sysname,
@password sysname,
@Nsql varchar(1000);
-- 在操作系统中为xp_cmdshell 代理帐户建立windows 用户
SELECT
@user = N'xpcmdshell',
@password = N'xpcmdshell',
@Nsql = 'NET USER "' + @winuser + '" "' + @password + '" /ADD';
EXEC xp_cmdshell @Nsql;
go
-- 建立xp_cmdshell 代理帐户
EXEC master.dbo.xp_sqlagent_proxy_account N'SET',
N'',
@user,
@password
这时你在刚才以njslt连接用查询分析器再试试,xp_cmdshell有结果了。
--删除测试环境:
--drop db user,login , windows user
/*
use test_db
go
sp_dropuser 'njslt'
go
use master
go
sp_dropuser 'njslt'
go
sp_droplogin 'njslt'
go
DECLARE
@user sysname,
@password sysname,
@sql varchar(1000);
SELECT
@user = N'xpcmdshell',
@password = N'xpcmdshell',
@sql = 'NET USER ' + @user + ' /delete';
select @sql
EXEC xp_cmdshell @sql;
*/