解密MSSQL鏈結資料庫的密碼

2021-09-11 11:23:58 字數 3241 閱讀 7987

文章很多專有名詞,而且老外說話的方式和中國的差別還是太大了點……所以有很多地方翻譯的不是很好,見諒。

從重要系統中獲取明文密碼的過程總是充滿著樂趣。mssql伺服器對本地儲存的密碼是進行了加密操作的,鏈結伺服器的相關憑證也不例外,但與此同時mssql也是有自己的手段可以對相關的密碼憑證進行解密。而你可以直接參考使用本文發布的powershell指令碼對相關的憑證進行解密。以進攻者的角度來看,如果想要解密相關的憑證,我們需要有mssql的sysadmin許可權和本地伺服器系統管理員的許可權。從防禦的層面來看,這篇文章的目的主要是想提醒下相關的管理員,不必要的資料庫鏈結、高許可權資料庫鏈結和使用sql server的身份認證會比使用整合的身份認證產生更多不必要的風險。這篇博文推薦給對資料庫感興趣的黑客及打算深入學習的管理員們。

microsoft sql server允許使用者使用mssql管理其它不同型別的資料庫,一般情況下鏈結伺服器用來管理與本地不同版本的mssql服務。當鏈結建立之後,它們可以被配置為使用安全的上下文和靜態sql server憑據。如果sql server的憑據被新增使用了,相關的使用者名稱和密碼會被加密儲存到相關的表內,而這一加密是可逆的。單向不可逆的hash是不可以用於鏈結伺服器的,因為sql server必須要使用明文的密碼資訊去訪問其它的資料庫。所以,如果密碼資訊是使用了對稱加密而不是單向hash的話,sql server自然會有方法去解密相關的密***。本文主要介紹這一加密、解密的過程及其工具化的實現。

mssql將鏈結伺服器的資訊(包含加密的密碼)儲存在master.sys.syslnklgns表中。我們重點關注的加密密碼是儲存在字段「pwdhash」中的(雖然寫著hash但是他不是乙個普通的hash),下圖是乙個例子:

master.sys.syslnklgns表在正常的資料庫連線情況下是無法訪問的,必須在專用管理員連線(dac)下才可以訪問(更多關於dac的資訊請檢視technet.microsoft.com/en-us/libra…)。開啟專用管理員連線有兩個條件:一是需要有mssql的sysadmin許可權,二是本地伺服器的管理員許可權。

如果本地管理員沒有獲得sysadmin的許可權,你只需要將mssql許可權修改為本地系統賬戶即可。更多資訊請參考www.netspi.com/blog/entryi…

下面介紹一些mssql加密的基本原理。首先我們可以先了解一下服務主金鑰(smk)(更多資訊請參考technet.microsoft.com/en-us/libra…)。根據微軟的描述「服務主金鑰為 sql server 加密層次結構的根。

服務主金鑰是首次需要它來加密其他金鑰時自動生成的」可知smk儲存在master.sys.key_encryptions表中,而他的key_id對應的值是102。smk是使用dpapi來加密的,而這裡他有兩個可用的版本,第一種是使用的localmachine加密,另一種是currentuser的相關上下文(意思是sql server服務執行的賬戶)。這裡我們挑使用localmachine的machinekey來單獨加密的、解密時不依賴於sql server賬戶的格式來討論。下面是乙個例子:

為了增強加密的強度,演算法中會加入熵(密碼學用語,可自行查閱),不過演算法中使用到的熵位元組我們可以從登錄檔hklm:\software\microsoft\microsoft sql server\[instancename]\security\entropy中找到。再次提醒,訪問此表項需要本地系統的管理員許可權。下圖是熵的乙個例子:

搞定上面這些之後(同時必須去除填充位元組等)我們就可以使用dpapi來解密smk了。

從smk的長度(或mssql的版本)我們可以看出兩種不同的加密演算法:mssql 2012使用的是aes,而早期的版本使用的是3des。另外,pwdhash必須解析為bit才可以找到相關的加密密碼。版本使用的演算法參考了高階t-sql程式設計師發布的文章,見stackoverflow.com/questions/2…

即使資料的格式和文章內給出的不太一致,但是也並不難發現正確的加密資料。到此,我們已經有辦法使用smk解密出所有的明***了(當使用的是sql server賬戶而不是windows身份認證)。

該指令碼必須在mssql伺服器本地執行(dpapi必須可以訪問到local machine key),同時執行該指令碼的使用者必須有資料庫的sysadmin許可權(在dac下)可以訪問所有的資料庫例項,而且該賬戶也必須擁有系統管理器許可權(用於讀取登錄檔內的熵)。另外,如果啟用了uac,指令碼必須以管理員身份執行。下面幾個是指令碼執行的關鍵步驟概要:

1. 獲取本伺服器所有mssql的例項

2. 為每個例項開啟dac訪問

3. 獲取每個例項的pwdhash字段值

4. 從master.sys.key_encryptions表中讀取出所有key_id值為102的行所對應的smk,並根據thumbprint欄位來判斷其版本

5. 讀取hklm:\software\microsoft\microsoft sql server\[instancename]\security\entropy 中的熵

6. 使用以上資訊解密smk

7. 程式根據mssql的版本和smk的長度來確定使用aes演算法或3des演算法

8. 使用smk明文去解密鏈結伺服器的憑證

複製**

在測試這個的過程中很多問題的產生,要不是dac登入不上,就是powershell的指令碼一直有問題。

目前測試了兩個環境:

1. win2003 + mssql2005

2. win2008 + mssql2008

複製**

除了指令碼有問題,其它都是可以獲取到的。指令碼大部分語法是類似.net的,基本都是在呼叫.net的庫,由於一些時間問題,我就不再獻醜去改了等大牛們來乙個「一鍵獲取」。

先看點2003的測試圖:

1.pwdhash

2.讀取加密的smk

3.檢視登錄檔key

但是在執行指令碼的時候(注意要2.0以上)還是報錯了:

已經測試過兩個引數都非空,而且應該是正確的。

在2008下也是類似的情況。時間關係不再深入,等有興趣的牛牛們再搞搞。

另外,這也是一種「找資料庫連線資訊」的方法。雖然有點奇葩,但是預計還是可行的,以後如果可以安排得過來,而且沒有大牛修改上面的指令碼的話……我再來獻醜。

第一次搞翻譯,翻譯的不好大家多多原諒。

MSSQL資料庫備份之設定密碼

備份 這兩條語句一起才算是完整的備份,第一條是備份資料庫,第二條是備份日誌,在實際使用中推薦使用這種方式 backup database powercheck to disk d back 20070908.bak with password 123456 這是密碼 backup log power...

建立資料庫伺服器遠端鏈結(MSSQL)

建立鏈結伺服器 exec sp addlinkedserver server pp client 鏈結伺服器名 srvproduct provider n sqloledb datasrc n 117.135.132.71 遠端伺服器名稱 catalog n uims go 建立遠端登入 exec ...

加 解密資料庫使用者 密碼的類設計

可以用來加 解密資料庫使用者 密碼等 using system using system.io using system.text using system.security.cryptography namespace mon static protected byte byteiv static...