【问题标题】:One-line alternative for xp_cmdshell? I tried several thingsxp_cmdshell 的单行替代方案?我尝试了几件事
【发布时间】:2012-04-07 17:59:56
【问题描述】:

您好 Microsoft SQL Server 大师,

嗯,我有一个 Microsoft SQL Server 2000,如下所述:

Microsoft SQL Server  2000 - 8.00.2039 (Intel X86) 
May  3 2005 23:18:38 
Copyright (c) 1988-2003 Microsoft Corporation
Desktop Engine on Windows NT 5.2 (Build 3790: Service Pack 2)

我需要从这个 Microsoft SQL Server 执行操作系统命令,我通过下面的查询检查了我是否具有系统管理员权限,它返回“1”,这证实了我的权限。

SELECT IS_SRVROLEMEMBER('sysadmin', 'sa');

我尝试了传统的 xp_cmdshell,但没有任何反应,只是为了确保它正常工作,我尝试了著名的:

EXEC xp_cmdshell 'dir c:\'; EXEC master.dbo.xp_cmdshell 'dir c:\';
EXEC master..xp_cmdshell "dir c:\";

而且都没有返回任何内容,这让我相信 xp_cmdshell 不可用。我知道 xp_cmdshell 在 Microsoft SQL Server 2005 中默认禁用,但在 2000 中没有,无论如何,我尝试以相同的方式重新启用它但失败了。

我查看了互联网,发现这种方法可以为 Microsoft SQL Server 2000 重新启用 xp_cmdshell:

exec sp_addextendedproc 'xp_cmdshell', 'xplog70.dll'

exec sp_addextendedproc xp_cmdshell, 'C:\Program Files\Microsoft SQL Server\MSSQL\Binn\xplog70.dll'

但是,它仍然不起作用。我发现另一篇文章告诉我有时管理员会删除这些文件,我认为这可能是我的情况,文章说如果它被删除,我可以执行“xp_msver”,在我的情况下它也不会返回任何内容。

参考:http://support.microsoft.com/kb/891984

我还尝试了我在互联网上找到的这个查询,以查看 xp_cmdshell 是否存在并且它没有返回任何内容(但这可能是我奇怪的 SQL 客户端的限制,请参见下文)。

if exists (select * from dbo.sysobjects where id = object_id(N’[dbo].[ xp_cmdshell]‘) and OBJECTPROPERTY(id, N’IsExtendedProc’) = 1);

所以,我真的遇到了麻烦,我在 Google 进行了研究,发现了潜在的解决方案,例如 Job agent、SSIS 包、CLR 存储过程、sp_OACreate(和朋友)和 SQLCMD,但没有任何效果。也许我做错了,但我的另一个限制是我只能从一个跳转框(Linux)访问这个 Microsoft SQL Server 2000,它有一个非常奇怪的 sql-server 客户端,不接受多行查询,因此,我无法成功尝试以下潜在的解决方案:

1# 工作代理

DECLARE @jobID uniqueidentifier, @cmd varchar(1000) 

SET @cmd = 'netstat -na > c:\connections.txt'

EXEC msdb.dbo.sp_add_job @job_name = '_tmp_MakeDirectory', @enabled  = 1, @start_step_id = 1, @owner_login_name='sa', @job_id = @jobID OUTPUT 

EXEC msdb.dbo.sp_add_jobstep @job_id = @jobID, @step_name = 'Create Backup Folder', @step_id = 1, @subsystem = 'CMDEXEC', @command = @cmd

EXEC msdb.dbo.sp_add_jobserver @job_id = @jobID

EXEC msdb.dbo.sp_start_job @job_id = @jobID, @output_flag = 0 

WAITFOR DELAY '000:00:05' -- Give the job a chance to complete

IF EXISTS (SELECT name FROM msdb.dbo.sysjobs WHERE name = '_tmp_MakeDirectory')
BEGIN
     EXEC msdb.dbo.sp_delete_job @job_name = '_tmp_MakeDirectory'
END

2#SQLCMD

CREATE PROCEDURE SQLCMD_TEST
AS
    !!MKDIR "netstat -na > c:\connections.txt"
    :OUT "C:\TEST\test.TXT"
    SELECT @@VERSION AS 'SERVER VERSION'
    !!DIR
GO
    SELECT @@SERVERNAME AS 'SERVER NAME'
GO 


EXEC SQLCMD_TEST

很遗憾,我没有其他方法可以访问此 Microsoft SQL Server,我知道这不是最好的方法,但就是这样,我无能为力。因此,我需要一个解决方案来在具有所有这些限制的 Microsoft SQL Server 2000 上执行操作系统命令。请问有人可以将上述两种方法中的任何一种移植到一个单行查询中吗?

非常欢迎任何其他带有示例的建议。

非常感谢。

问候。

【问题讨论】:

  • 运行最后两个选项之一时看到的错误是什么?
  • "... 就我而言,另一个限制是我只能从具有非常奇怪的不接受的 sql-server 客户端的 jump-box (Linux) 访问此 Microsoft SQL Server 2000多行查询,...”这听起来很像 Injection-Hacking。
  • 嗨文斯。我没有看到任何答案,它只是返回到提示。有什么想法吗?
  • "PRINT 'Foo'" 有用吗?
  • 我不是。严重地。 PRINT 命令是否正常工作对于诊断此问题非常重要。 xp_cmdshell IS 完全有可能工作,但是您的 Linux 客户端只是没有向您显示输出。 PRINT 发送与 sp_cmdshell 相同类型的输出(非表格,辅助通道),因此这是一个很好的测试。 (仅供参考,大多数简单的客户端不会捕获这种输出)。

标签: sql sql-server sql-server-2008 tsql sql-server-2000


【解决方案1】:

在 CLR 支持出现之前,我曾经使用 xp_cmdshell。不幸的是,您的版本远离 CLR 支持 (SQL Server 2005) 和 system.io 命名空间。但是,您可以创建自己的扩展存储过程,该过程可以访问文件系统并创建目录。更多信息请看这里:http://www.devarticles.com/c/a/SQL-Server/Extended-Stored-Procedures-Intro-And-10-Cool-Examples/

顺便说一下,xp_cmdshell 是一个扩展存储过程。

【讨论】:

  • 感谢 Brian 的帮助,我说服了我的客户安装 sqsh,现在我的帖子中描述的方法之一奏效了。顺便说一句,这个 CLR 支持以及创建你自己的 xp_cmdshell 似乎非常有趣,如果你有工作示例并想在这里发布我很确定它会对某人有所帮助。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-05
  • 2023-04-05
相关资源
最近更新 更多