在做滲透測試任務時,我們常常會碰到一些直連SQL Server資料庫的桌面應用。但偶爾也會碰到一些後端為SQL Server的應用,並且其只允許來自預定義的主機名或應用程式列表的連接。這些類型的限制通常是通過登錄觸發器來強制執行的。在本文中,我將向大家展示如何利用連接字符串屬性欺騙主機名和應用程式名稱來繞過這些限制。示例中將會包括SSMS和PowerUpSQL。這對於那些繼承了舊式桌面應用的滲透測試人員和開發人員非常有用。
什麼是登錄觸發器?登錄觸發器將為響應LOGON事件而激發存儲過程。與 SQL Server實例建立用戶會話時將引發此事件。 登錄觸發器將在登錄的身份驗證階段完成之後且用戶會話實際建立之前激發。 因此,來自觸發器內部且通常將到達用戶的所有消息(例如錯誤消息和來自PRINT語句的消息)會傳送到SQL Server錯誤日誌。 如果身份驗證失敗,將不激發登錄觸發器。
安裝SQL Server如果你還沒有安裝SQL Server,請進行如下操作:
1.下載並安裝SQL Server
2.下載並安裝SQL Server Management Studio Express(SSMS)
創建一個主機名限制登錄觸發器以下是在家庭實驗環境中設置觸發器的說明,該觸發器將根據連接的工作站名稱來限制訪問。
1.使用SSMS以sysadmin身份登錄到新的SQL Server實例。
2.首先,讓我們使用以下命令來獲取連接到SQL server實例的主機名。默認情況下,它將向我們返回連接到SQL Server實例的工作站的主機名。
SELECT HOST_NAME()
3.創建一個僅允許白名單主機名連接的登錄觸發器。並按照下圖所示執行該觸發器。
-- Create our logon triggerCREATE TRIGGER MyHostsOnlyON ALL SERVERFOR LOGONASBEGIN IF ( -- White list of allowed hostnames are defined here. HOST_NAME() NOT IN ('ProdBox','QaBox','DevBox','UserBox') ) BEGIN RAISERROR('You are not allowed to login from this hostname.', 16, 1); ROLLBACK; END END
4.設置登錄觸發器後,當你再次嘗試使用SSMS登錄時,應該會出現類似下面的錯誤,因為你要連接的主機名並不在當前的白名單上。
使用SSMS欺騙主機名在這一點上,你可能會問,「我們(攻擊者)什麼時候會在現實世界中實際使用它呢?」我的回答是通常是在你從配置文件或反編譯代碼恢復連接字符串之後使用,現在我們希望使用該信息直接連接到後端SQL Server,這是應用程式滲透測試中非常常見的情況。此外,我們還會在網絡測試和紅藍對抗期間,在打開的文件共享中找到一些內部應用程式和配置文件。
1.在SSMS中打開「Connect Object Explorer」並導航到「Additional Connection Parameters」選項。這裡我們可以動態設置連接字符串屬性(超酷)。本例中,我們將「Workstation ID」屬性設置為「DevBox」,這是白名單中包含的一個主機名。注意:稍後我會介紹幾種識別白名單主機名的方法。
2.點擊connect登錄。此時,如果你打開查詢窗口再次檢查主機名時,你會發現主機名將返回「DevBox」。這進一步說明我們成功欺騙了主機名的檢測。
SELECT HOST_NAME()
使用連接字符串欺騙主機名實際上,SSMS只是使用」workstation id」屬性集來構建了一個連接字符串。下面是一個簡單連接字符串的例子,它將作為當前Windows用戶連接到遠程SQL Server實例,並選擇「Master」資料庫。
Data Source=server\instance1;Initial Catalog=Master;Integrated Security=True;
如果我們在上一節中展示的登錄觸發器已經生效的話,我們應該看到「failed to connect」消息。 但是,如果將「Workstation ID」屬性設置為白名單中的主機名,就能夠順利登錄。
Data Source=server\instance1;Initial Catalog=Master;Integrated Security=True;Workstation ID = DevBox;
使用PowerUpSQL欺騙主機名我在PowerUpSQL的Get-SQLQuery函數中添加了「WorkstationId」選項。下面是一個示例,將為大家演示如何繞過我們在上一節中創建的登錄觸發器。
1.打開Powershell並使用自己喜歡的方式加載PowerUpSQL。下面的示例顯示了如何直接從GitHub加載PowerUpSQL。
IEX(New-Object System.Net.WebClient).DownloadString("https://raw.githubusercontent.com/NetSPI/PowerUpSQL/master/PowerUpSQL.ps1")
2.由於觸發器限制,初始連接失敗。 請注意,我們需要設置「-ReturnError」標誌,以查看伺服器返回的錯誤信息。
Get-SQLQuery -Verbose -Instance MSSQLSRV04\SQLSERVER2014 -Query "SELECT host_name()" -ReturnError
3.現在我們將workstationid選項設置為「DevBox」,這樣你就能夠成功執行查詢了。
Get-SQLQuery -Verbose -Instance MSSQLSRV04\SQLSERVER2014 -Query "SELECT host_name()" -WorkstationId "DevBox"
4.如果你想要刪除觸發器,你可以執行以下命令。
Get-SQLQuery -Verbose -Instance MSSQLSRV04\SQLSERVER2014 -WorkstationId "DevBox" -Query 'DROP TRIGGER MyHostsOnly on all server'
創建登錄觸發器來限制應用程式以下是在家庭實驗室中設置觸發器的說明,該觸發器將根據連接的應用程式名稱來限制訪問。
1.使用SSMS以sysadmin身份登錄到新的SQL Server實例。
2.首先,讓我們使用以下命令查看下連接到SQL Server實例的應用程式的名稱。不出意外的話,它應為我們返回「Microsoft SQL Server Management Studio – Query」。
SELECT APP_NAME()
3.創建一個僅允許白名單應用程式進行連接的登錄觸發器。並按照下圖所示執行該觸發器。
CREATE TRIGGER MyAppsOnlyON ALL SERVERFOR LOGONASBEGIN IF ( -- Set the white list of application names here APP_NAME() NOT IN ('Application1','Application2','SuperApp3000','LegacyApp','DevApp1') ) BEGIN RAISERROR('You are not allowed to login from this application name.', 16, 1); ROLLBACK; ENDEND
4.設置登錄觸發器後,當你再次嘗試使用SSMS登錄時,你應該會收到以下錯誤提示,因為你要連接的應用程式並不在當前的白名單列表中。
使用SSMS欺騙應用程式名稱同樣地你可能會問,「我們(攻擊者)什麼時候會在現實世界中實際使用它呢?」。某些應用程式的名稱已經在連接SQL Server的連接字符串中靜態設置。與主機名類似,我們可以在配置文件和源碼中找到它們。實際上,很少能見到登錄觸發器使用應用程式名稱來限制訪問,但我們也已碰見過好幾回了。
1.在SSMS中打開」Connect Object Explorer」並導航到」Additional Connection Parameters」選項。我們可以在這裡即時設置連接字符串屬性(超酷)。 對於這個例子來說,我們將」application name」屬性設置為」SuperApp3000」,它是白名單中的一個應用程式名。注意:稍後我會介紹幾種識別白名單中的應用程式名的方法。
2.點擊connect登錄。此時,如果你打開查詢窗口再次檢查應用程式名時,你會發現應用程式名將返回「SuperApp3000」。這進一步說明我們成功欺騙了主機名的檢測。
SELECT APP_NAME()
使用字符串連接欺騙應用程式名稱正如在上一節中提到的那樣,存在一個名為「AppName」的連接字符串屬性,應用程式可以使用它將其應用程式名稱提交給SQL Server,例如:
Data Source=server\instance1;Initial Catalog=Master;Integrated Security=True; Application Name =MyApp"Data Source=server\instance1;Initial Catalog=Master;Integrated Security=True; ApplicationName =MyApp"Data Source=server\instance1;Initial Catalog=Master;Integrated Security=True; AppName =MyApp"
使用PowerUpSQL欺騙應用程式名稱出於場景演示的需要,我更新了PowerUpSQL的Get-SQLQuery函數使其包含「appname」選項。示例如下:
1.打開Powershell並使用自己喜歡的方式加載PowerUpSQL。下面的示例顯示了如何直接從GitHub加載PowerUpSQL。
IEX(New-Object System.Net.WebClient).DownloadString("https://raw.githubusercontent.com/NetSPI/PowerUpSQL/master/PowerUpSQL.ps1")
2.PowerUpSQL函數封裝了許多.NET SQL Server函數。默認情況下,當使用.NET以編程方式連接到SQL Server時,「appname」屬性將設置為「.Net SqlClient Data Provider」。但是,由於我們創建了一個新的登錄觸發器,並通過「appname」來限制訪問,所以會得到以下錯誤。
Get-SQLQuery -Verbose -Instance MSSQLSRV04\SQLSERVER2014 -Query "SELECT app_name()" -ReturnError
3.現在將「appname」屬性設置為「SuperApp3000」,這樣就能夠成功執行查詢了。
Get-SQLQuery -Verbose -Instance MSSQLSRV04\SQLSERVER2014 -Query "SELECT app_name()" -AppName SuperApp3000
4.如果你想要刪除觸發器,你可以執行以下命令。
Get-SQLQuery -Verbose -Instance MSSQLSRV04\SQLSERVER2014 -AppName SuperApp3000 -Query 'DROP TRIGGER MyAppsOnly on all server'
5.現在你不需要欺騙應用程式名稱就可以連接了。
Get-SQLQuery -Verbose -Instance MSSQLSRV04\SQLSERVER2014 -Query 'SELECT APP_NAME()'
6.或者你也可以偽造任意應用程式的名稱。
Get-SQLQuery -Verbose -Instance MSSQLSRV04\SQLSERVER2014 -AppName EvilClient -Query 'SELECT APP_NAME()'
尋找白名單列表中的主機和應用程式名如果你不確定登錄觸發器的白名單列表中有哪些主機和應用程式名,則可以藉助下面的這些方法。
1.檢查登錄觸發原始碼獲取登錄觸發器中白名單列表的最佳方法是查看其原始碼。 但通常情況下,這都需要一定的權限才能訪問。
SELECT name,OBJECT_DEFINITION(OBJECT_ID) as trigger_definition,parent_class_desc,create_date,modify_date,is_ms_shipped,is_disabledFROM sys.server_triggers ORDER BY name ASC
2.查看應用程式代碼查找硬編碼的的主機名和應用程式有時白名單中的主機名和應用程式會被硬編碼到應用程式中。如果您正在處理.NET或Java應用程式,則可以通過反編譯,並查找與正在使用的連接字符串相關的關鍵字來定位有關原始碼。這種方法假定您可以訪問應用程式程序集或配置文件。這時,JD-GUI和DNSPY將會派上用場。
3.考察應用流量有時,白名單中的主機名和應用程式,是應用程式啟動時從資料庫伺服器中抓取的。因此,您可以使用您最喜愛的嗅探器來獲取白名單中的主機名和應用程式。我有過幾次這樣的經歷。你可能會問,為什麼會有人這麼做? 別人可能永遠不會知道答案。
4.使用域系統列表如果您已經擁有域帳戶,則可以查詢Active Directory以獲取域計算機的列表。然後,您可以遍歷列表,從而找出允許連接的列表。當然,這裡假定當前域用戶有權登錄到SQL Server,並且白名單列出的主機名與域相關聯。
5.使用MITM記錄連接我們還可以通過基於ARP的中間人(MITM)攻擊來攔截從遠程系統到SQL Server的連接。如果連接已加密(自SQL Server 2014以來,都會默認進行加密),雖然看不到流量內容,但能夠看到已經連接了哪些主機。當然,我們也可以使用MITM技術。
警告:如果攻擊過程正在驗證登陸憑證,可能會導致數據包丟失,並對生產系統產生嚴重影響,因此請謹慎使用該方法。
一般建議使用登錄觸發器時,不要根據客戶端可以輕鬆修改的信息來限制對SQL Server的訪問。
如果您希望使用白名單技術限制系統訪問,請考慮使用網絡或主機級防火牆規則,而不是登錄觸發器。
考慮根據用戶組和訪問權限來限制對SQL Server的訪問,而不是使用登錄觸發器。
在本文中,我介紹了一些鮮為人知的利用連接字符串屬性來繞過SQL Server登錄觸發器強制執行的訪問限制的方法。這些方法在對傳統桌面應用程式滲透測試時,將非常的有用。對於那些感興趣的人,你還可以在這裡查看我更新後的「SQL Server連接字符串Cheatsheet」。
參考https://gist.github.com/nullbind/91c573b0e27682733f97d4e6eebe36f8
https://docs.microsoft.com/en-us/sql/relational-databases/triggers/logon-triggers?view=sql-server-2017
https://blog.sqlauthority.com/2018/04/14/sql-server-be-careful-with-logon-triggers-dont-use-host_name/
*參考來源:netspi,FB小編 secist 編譯,轉載請註明來自FreeBuf.COM