在所有的数据库注入中,只有access数据库的注入是最基础的,因为微软为其定义为小型数据库,所以没有那么多复杂的功能,适用于各种小型企业建站。

 

                                                                              常见的select查询

  在第一章我们已经讲过了关于sql查询基础,而在上几节我们也阐述了关于sql查询的多种用法。这里我们利用奋网名片 v2.2系统实现一个完整的利用SQL注入过程。

    奋网是小型名片发布系统,其下载地址为:http://down.chinaz.com/soft/26685.htm(大家也可以到光盘相关中查找),下载完成后解压缩拖拽的iis中在本机访问http://192.168.1.23/index.asp会显示程序首页。

点击北京链接会发现地址栏中出现了变量,直接在后面加入“’”返回错误,初步判断有注入漏洞。

如图发现错误信息中有乱码,那么就在浏览器空白区域右键,在编码菜单中选择“简体中文”就会识别错误信息了。(这个时候由于编码问题其他位置会出现乱码大家不用管只要我们的需要的错误信息返回正确即可)

在这里我们可以看到几条信息,第一错误信息上位JET database基本可以肯定为access数据库。第二出现字符串语法错误有可能存在注入漏洞。第三我们提交的字符串被单引号包含着说明是字符型。接下来利用字符型判断语句“' and '1'='1”和“'and '1'='2”测试。会发现“' and '1'='1”返回正确而“' and '1'='2”返回错误肯定存在注入漏洞。

接下来利用SQL查询判断来猜解管理员的账号密码(由于本套系统并没把管理员账号密码写入数据库中,所以我们猜解其发布信息),因为是源代码所以我们可以看数据库表。

可以看到数据库只有一个表位info,而我们猜解的流程就是:判断数据库表名判断数据库列名>判断列名字段个数>字段猜解

注入语法如下:

   猜解表名

and exists(select * from [表名])

   猜解列名

and exists (select [字段名] from [表名])

   猜解表中记录个数

and (select Count(1) from [表名] where 1=1) between num1 and num2

   猜解列名长度

           and (select top 1 len([字段名1]) from (Select Top 1 [字段名1],[字段名2],...,[字段名n] from [表名] where 1=1 order by [字段名1],[字段名2],...,[字段名n])  order by [字段名1] desc,[字段名2] desc,...,[字段名n] desc ) between num1 and num2

   猜解列名内容

           and (select top 1 asc(mid(cstr(字段名1),1,1)) from (Select Top 1 [字段名1],[字段名2],...,[字段名n] from [表名] where 1=1 order by [字段名1],[字段名2],...,[字段名n]) order by [字段名1] desc,[字段名2] desc,...,[字段名n] desc ) between num1 and num2

 

这里我们猜解info表名的id列内信息。首先判断数据库表名是否存在。在URL后输入“and exists (select * from info) and '1'='1”发现返回正常。

我们再随意输入一个表名“and exists (select * from admin) and '1'='1”发现返回错误并且错误写着找不到输入表admin,这就说明不存在admin表但是存在info表。

继续猜解列名,修改sql语句为“and exists (select admin from info) and '1'='1”,猜解info表中是否有一个叫admin的列。

发现返回错误信息,说明并没有admin的列名,继续查看有没有id这样的列名。发现返回正确信息说明存在着id列名,利用同样的语句发现还存在“company”和“tel”这两个表。

 

接下来获取表中总共有多少条信息,利用二分法获取用户信息个数(二分法:假设数据是按升序排序的,对于给定值x,从序列的中间位置开始比较,如果当前位置值等于x,则查找成功;若x小于当前位置值,则在数列的前半段中查找;若x大于当前位置值则在数列的后半段中继续查找

,直到找到为止。)。语句为“' and (select Count(1) from [info] where 1=1) between 0 and 100 and '1'='1”,其作用是查询info表的列的个数是否在0-100之间(包括100),这里我们假设info表中有100条信息,而上面的代码就是查询信息是否超过100条,当超过100条时则会产生错误返之则会返回正确信息。其中count()函数的作用是返回指定列的值的数目,这里是设置的“1”我们还可以利用随意的列名比如id来替换或者直接利用通配符“*”来作为获取列。输入如上代码发现其并没有产生错误,那么说明info表的信息个数小于等于100,接下来利用二分法查找个数是否在0~50之间等,循环下去发现当查找个数为0~1则返回错误而0~2则返回正确,那么可以肯定表中有2条信息。