且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

再探偏移注射

更新时间:2022-09-19 22:08:49

转自t00ls

关于Union偏移注射这个东西,最早貌似是lake2大黑客提出来的,以前一直当他是鸡肋,没去关注过,直到昨天遇到一个mysql 4.1的点。
表,列都猜出来了,就差数据。因为他的参数是按“,”分割的,所以在注射的时候必须避开逗号,这样一来普通的union就用不成了,想暴力猜解也不行,因为substring也得用到逗号。无奈中想起join语句,偏移注射里面有一个很重要的技巧就是用join语句来控制字段数和数据显示的位置。麻烦的地方在于很多时候你根本不知道目标系统的环境,表里到底有多少列,数据类型什么的,怎么把他拼装到凑齐字段数,只能靠乱猜。
目标网站order by 7正常,order by 8无返回,那么一共是7个字段,按照通常的做法,应该是先and 1=2 union select 1,2,3,4,5,6,7#来看看情况,这里因为要避开逗号,就必须用到join语句。但是不知道用户表一共有几列,没有关系,我们可以用select * from ((select username from users)as a join (select username from users)as b on a.username=b.username),把select出部分字段的结果集当做一个表,然后来join到一起,这样只要把(select username from users)as a重复7次,就可以把字段补齐。
上面的语句在mysql5里面可以正常执行,也可以用到union子句中,可是在mysql4里就报语法错误,看来4.x不支持这么复杂的嵌套。修改了一下:
select * from users as a join (select id from users) as b on a.id=b.id
这样在4.1里可以正常执行,4.0因为不支持子语句,简单的说就是不支持()里带select,所以就木有办法鸟。
但是这样又有问题鸟,因为第一个select后面必须跟*,否则只会返回第一列。Mysql的join语句默认应该是inner join,也就是内连接,我尝试换成left join或者right join都不行,我记得mysql4应该是支持左连接和右连接的,搞不懂这里为什么行不通。这么一来又必需猜目标表的字段数了,而且目标表的字段数必需<=语句里select出的字段数才行,也受显示数据字段的制约。好处就是不知道列名也没关系,可以用常数来代替,即select 1,2,3,4,5 union select * from users as a join (select 1 from users) as b join (select 1 from users) as c on a.id=1
这样就完全避开了“,”,select出来的数据里可能会有很多重复,用distinct关键字过滤掉即可。
如果目标表的字段>前面选择的字段也没关系,因为必需保证最前面的字段是*,找一个字段少一点的表,即select * from news as a join (select username from users) as b,不过这个东西受到扫出来的表名,字段数,显示数据字段的制约,比较鸡肋了。
以上语句在mysql里测试成功,如果要在access或者mssql里使用,估计得另外调试。这个跟以前提出来那个偏移注射有些区别,也姑且算另外一种意义上的偏移注射吧。核心思想就是不断的join来补齐字段,从而避开,。

最郁闷的是,最后竟然是用fckeditor搞定shell的,真没技术含量,一下午白研究了-_-

刚才在外面骑车的时候,突然想到,之前的语句select * from users as a join (select id from users) as b on a.id=b.id前面必须要用到*是因为他并没有把这个select * from users as a作为一个整体来解析,而是将users as a跟后面的join到一起了,即select * from (users as a join (select id from users) as b on a.id=b.id),当然前面要用*,才能返回子语句里所有的列数了。
那么改写成select distinct * from (select 1 from users)as a join (select 2 from users)as b即可,然后依次像后面join补齐字段,最后把合适的地方换成用户名密码字段即可。mysql 4.1下测试成功,当然还是需要知道列名,呵呵