深入剖析 SharePoint: SharePoint 安全帳戶
使用 SharePoint 安全帳戶時(shí),極有可能創(chuàng)建弱系統(tǒng)配置,此類配置可能會暴露整個(gè) SharePoint 環(huán)境。為幫助您正確地部署和保護(hù) SharePoint 服務(wù)器場,Microsoft 發(fā)布了大量信息以及詳細(xì)的指導(dǎo)方針。例如,Office SharePoint Server 安全指南共有 300 多頁,內(nèi)容涉及規(guī)劃和實(shí)施站點(diǎn)及內(nèi)容層次結(jié)構(gòu)、身份驗(yàn)證方法、安全角色、管理員和服務(wù)帳戶以及許多其他安全問題。Windows SharePoint Services 安全帳戶要求工作表還提供了有關(guān)安全帳戶配置的基本信息。如果安全性對您而言至關(guān)重要,您肯定希望確保遵守該工作表。
即使擁有內(nèi)容翔實(shí)的文檔,配置安全帳戶仍可能是一項(xiàng)艱巨的任務(wù)。實(shí)際上,單服務(wù)器安裝的默認(rèn)設(shè)置并不遵從工作表的建議,并且某些組件(如 Windows SharePoint Services (WSS) 3.0 中包括的電子郵件集成 Web 服務(wù))在服務(wù)器上需要提升的權(quán)限,這一點(diǎn)不僅與 Microsoft 安全建議背道而馳,并且與安全性最佳實(shí)踐和一般常識直接沖突。SharePoint 3.0 中心管理工具樂于應(yīng)用關(guān)鍵安全帳戶配置且沒有警告,Microsoft Baseline Security Analyzer (MBSA) 未檢測由此產(chǎn)生的不足,這就為保護(hù) SharePoint 服務(wù)器場以及確保其安全留下了一個(gè)隱患。
在本專欄中,我將深入剖析 SharePoint 安全帳戶,向您展示攻擊者如何利用弱配置完全控制所有站點(diǎn)集合和站點(diǎn)。這是一個(gè)有點(diǎn)敏感的話題。一方面,我希望幫助您找出與 SharePoint 服務(wù)器配置相關(guān)的安全挑戰(zhàn)。畢竟,如果想要有效地保護(hù) SharePoint 環(huán)境,您必須了解它的優(yōu)缺點(diǎn)。
另一方面,我不想助紂為孽。為此,我不會在本專欄中提供任何工作表或自定義工具,并且對源代碼的討論將僅局限于基本主題,所有專業(yè) ASP.NET 開發(fā)人員都應(yīng)非常熟悉這些主題。本專欄中的源代碼段可幫助您檢測漏洞,但不會幫助任何人利用它們。即使編程技能有限,如果擁有 Microsoft Office SharePoint Designer 2007,應(yīng)該就可以使用這些代碼段來創(chuàng)建自定義 ASP.NET 頁面。
可在線獲取 Microsoft Office SharePoint Designer 2007 的試用版。建議您根據(jù)自己的偏好配置一個(gè)測試實(shí)驗(yàn)室,盡您所能的保護(hù)它,然后運(yùn)行代碼段進(jìn)行驗(yàn)證。讓我們來看一下您的 SharePoint 站點(diǎn)有多安全!
應(yīng)用程序池和安全帳戶
安全帳戶是 SharePoint 請求處理模型的核心。它們定義了運(yùn)行 SharePoint Web 應(yīng)用程序的 IIS 工作進(jìn)程的安全上下文。在創(chuàng)建 SharePoint Web 應(yīng)用程序時(shí),必須指定具有相關(guān)安全帳戶憑據(jù)的應(yīng)用程序池以及具有相關(guān)身份驗(yàn)證方法的 SharePoint 數(shù)據(jù)庫。如果使用 Windows 身份驗(yàn)證(推薦),SharePoint 將自動授予指定安全帳戶內(nèi)容數(shù)據(jù)庫的 dbOwner 權(quán)限,這樣運(yùn)行 SharePoint Web 應(yīng)用程序的 IIS 工作進(jìn)程可獲取該數(shù)據(jù)庫中站點(diǎn)集合和站點(diǎn)的訪問權(quán)限。否則,必須提供明確的 SQL Server 憑據(jù)。
在任何情況下,SharePoint 站點(diǎn)集合和站點(diǎn)都是虛擬結(jié)構(gòu)。實(shí)際上,它們與數(shù)據(jù)庫記錄相對應(yīng)。如果知道用于與內(nèi)容數(shù)據(jù)庫建立直接 SQL Server 連接的帳戶名稱和密碼,就可獲取對其所有站點(diǎn)集合和站點(diǎn)數(shù)據(jù)的完全訪問權(quán)限(無論在 SharePoint 級別定義了哪些權(quán)限和訪問控制)。SharePoint 無法阻止您,因?yàn)槟c數(shù)據(jù)庫服務(wù)器建立了直接連接(如圖 1 所示)。因此,安全帳戶是攻擊的主要目標(biāo)。
圖 1 繞開 SharePoint 站點(diǎn)集合和站點(diǎn)訪問數(shù)據(jù)
如果站點(diǎn)集合包含通過身份驗(yàn)證的內(nèi)容和匿名內(nèi)容,為降低安全風(fēng)險(xiǎn),Microsoft 建議分別配置應(yīng)用程序池(和安全帳戶),并隔離存儲密碼的應(yīng)用程序或者用戶可在其中自由地創(chuàng)建和管理站點(diǎn)以及共享內(nèi)容的應(yīng)用程序。如果能遵循這一配置建議,即使攻擊者獲取了某個(gè)應(yīng)用程序池的控制權(quán)限,也并不意味著他對 SharePoint 場中的所有數(shù)據(jù)具有全局訪問權(quán)限。即使對相關(guān)的 Web 應(yīng)用程序分別使用安全帳戶,仍然無法觸及其他數(shù)據(jù)庫中的 SharePoint 站點(diǎn)集合和站點(diǎn)。
Microsoft 在 IIS 6.0 中首先引入了根據(jù)應(yīng)用程序池隔離工作進(jìn)程這一概念,并且指出 IIS 從此再也沒有出現(xiàn)過一次嚴(yán)重的安全漏洞。這是切實(shí)可靠的事實(shí),因此務(wù)必在 SharePoint 場中利用應(yīng)用程序池。但是,請記住,IIS 網(wǎng)站并不等價(jià)于 SharePoint Web 應(yīng)用程序。盡管可隔離 IIS 網(wǎng)站,但無法將 SharePoint Web 應(yīng)用程序彼此隔離開來。
僅當(dāng)網(wǎng)站沒有共享資源時(shí)才存在真正的隔離,而 SharePoint Web 應(yīng)用程序始終都有公共資源(如場的配置數(shù)據(jù)庫)。如圖 2 所示,如果獲取了 SharePoint 安全帳戶的控制權(quán)限,即意味著可以訪問 SharePoint 配置數(shù)據(jù)庫。如果在部署 SharePoint 場時(shí)沒有恰當(dāng)?shù)乜紤]安全帳戶的保護(hù),尤其是要將來自不同的內(nèi)部或外部客戶的站點(diǎn)集合和站點(diǎn)放在一個(gè)共享環(huán)境中時(shí),該訪問能力會讓您感到不安。
圖 2 SharePoint Web 應(yīng)用程序、配置數(shù)據(jù)庫和內(nèi)容數(shù)據(jù)庫之間的關(guān)系
在 SharePoint 服務(wù)器上運(yùn)行自定義代碼
默認(rèn)情況下,SharePoint 并不公開安全帳戶信息;它利用惡意代碼來找出細(xì)節(jié)。眾所周知,攻擊者可以利用安全漏洞上載惡意代碼,但有時(shí)使用入侵更容易達(dá)到目的。
最簡單的情形是攻擊者可在本地或通過終端服務(wù)器登錄 SharePoint 服務(wù)器,將惡意代碼復(fù)制到 %COMMONPROGRAMFILES%\Microsoft Shared\Web Server Extensions\12\TEMPLATE\Layouts 文件夾下。請注意,SharePoint 在每個(gè) SharePoint 站點(diǎn)中都包括作為虛擬子文件夾的這一文件夾。
另一種情況是,SharePoint 管理員可能沒有經(jīng)過適當(dāng)?shù)臏y試和代碼確認(rèn),就部署了來自某個(gè)可疑來源的自定義 SharePoint 解決方案,從而不知不覺地引入了惡意代碼。主頁面和內(nèi)容頁面中嵌入的內(nèi)聯(lián) ASP.NET 代碼也令人擔(dān)憂。默認(rèn)情況下,SharePoint 不會處理服務(wù)器端的腳本,但如果某人擁有 SharePoint Web 應(yīng)用程序 web.config 文件的寫入權(quán)限,他就可以通過更改規(guī)則處理服務(wù)器端腳本。僅需向 web.config 文件的 <PageParserPaths> 中添加一個(gè) PageParserPath 條目即可。那 PageParserPath 條目的工作原理究竟是什么呢?
假設(shè)有一名使用 SharePoint 的開發(fā)人員打電話給您,抱怨他在開發(fā)一個(gè)自定義 ASP.NET 頁面時(shí)出現(xiàn)了一條錯(cuò)誤消息“此文件中不允許使用代碼塊”。您在 Internet 中進(jìn)行搜索并在新聞組或博客站點(diǎn)中找到了解決方案:
<PageParserPath VirtualPath="/*" CompilationMode="Always" AllowServerSideScript="true" IncludeSubFolders="true" />
也許您忽略了安全警告或者甚至并未提及安全隱患。無論如何,您是將以上代碼行添加到了 web.config 文件中,現(xiàn)在所有人都非常高興,因?yàn)槟褑栴}解決了。
但是,您也無意間為以完全信任方式運(yùn)行 ASP.NET 頁面中的任意自定義代碼開啟了方便之門。如果攻擊者此時(shí)上載一個(gè)惡意 ASP.NET 頁面,SharePoint 環(huán)境將面臨危險(xiǎn)。如圖 3 所示,攻擊者在站點(diǎn)集合層次結(jié)構(gòu)的哪個(gè)位置擁有上載頁面的權(quán)限無關(guān)緊要—它可以是一個(gè)看似無惡意的小型團(tuán)隊(duì)站點(diǎn)。攻擊始終影響著 Web 應(yīng)用程序甚至整個(gè)服務(wù)器場,因?yàn)閮?nèi)容數(shù)據(jù)庫和配置數(shù)據(jù)庫均觸手可及。
圖 3 啟用內(nèi)聯(lián) ASP.NET 代碼可能危及 SharePoint Web 應(yīng)用程序的安全
關(guān)于 Jekyll 博士和 Hyde 先生
那么,攻擊者是如何在并不明確了解安全帳戶憑據(jù)的情況下獲取內(nèi)容和配置數(shù)據(jù)庫的訪問權(quán)限的呢?過程其實(shí)比較簡單。運(yùn)行 SharePoint Web 應(yīng)用程序的 IIS 工作進(jìn)程模擬 SharePoint 用戶并使用生成的線程令牌來進(jìn)行訪問檢查。例如,Jekyll 博士可以訪問其安全令牌有權(quán)訪問的所有此類 SharePoint 資源。但是,SharePoint Web 應(yīng)用程序還擁有 IIS 工作進(jìn)程的進(jìn)程令牌,而此令牌是 SharePoint 安全帳戶的安全令牌。
當(dāng)您通過調(diào)用靜態(tài) WindowsIdentity.Impersonate 方法并傳入一個(gè) zero 指針(如圖 4 和 4a 所示)還原模擬時(shí),出現(xiàn)的是 Hyde 先生。Jekyll 博士并無數(shù)據(jù)庫的直接訪問權(quán)限,但 Hyde 先生卻有。這樣就為 SQL Server 連接和 T-SQL 查詢掃清了障礙。
圖 4 SharePoint Web 應(yīng)用程序有兩個(gè)安全上下文(單擊圖像可查看大圖)
圖 4a 用于檢索兩個(gè) SharePoint Web 應(yīng)用程序安全上下文的代碼
private string GetMrHyde() { string retVal = string.Empty;
retVal = "Dr Jekyll is: " + WindowsIdentity.GetCurrent().Name + "<br>";
WindowsImpersonationContext impCtx = WindowsIdentity.Impersonate(IntPtr.Zero);
retVal += "Mr Hyde is: " + WindowsIdentity.GetCurrent().Name + "<br>";
impCtx.Undo(); return retVal; }
安全帳戶和進(jìn)程隔離
如 Web 應(yīng)用程序配置為運(yùn)行未驗(yàn)證代碼,應(yīng)用程序池和安全帳戶將無法幫助您保護(hù)其中的站點(diǎn)集合和站點(diǎn)。它們的作用在于通過進(jìn)程隔離來緩解攻擊者將代碼注入服務(wù)器的某個(gè)站點(diǎn)以攻擊其他站點(diǎn)所帶來的影響。進(jìn)程隔離可幫助實(shí)現(xiàn)此目的,但它要求您將其他站點(diǎn)放在單獨(dú)的 Web 應(yīng)用程序中,它們要在使用不同安全帳戶的應(yīng)用程序池中運(yùn)行。
必須充分地保護(hù)帳戶憑據(jù),否則配置努力將毫無意義。如果向應(yīng)用程序池帳戶授予 IIS 元數(shù)據(jù)庫的訪問權(quán)限(若要運(yùn)行電子郵件集成 Web 服務(wù)中的目錄管理服務(wù),必須擁有此權(quán)限),也容易讓別有用心的人直接得到這些敏感的安全憑據(jù)。如果應(yīng)用程序池帳戶擁有元數(shù)據(jù)庫訪問權(quán)限,攻擊者可還原模擬,然后檢索所有明文形式的帳戶和密碼(如圖 5 和 5a 所示)。整個(gè)服務(wù)器場都已失守,因?yàn)楣粽叽藭r(shí)可通過以任意此類安全帳戶身份運(yùn)行惡意代碼并與所有內(nèi)容數(shù)據(jù)庫建立 SQL Server 連接來繞開進(jìn)程隔離。
圖 5 從 IIS 元數(shù)據(jù)庫檢索安全帳戶信息
圖 5a 用于從 IIS 元數(shù)據(jù)庫檢索安全帳戶信息的代碼
private string GetMetabaseAppPoolIDs() { WindowsImpersonationContext impCtx = WindowsIdentity.Impersonate(IntPtr.Zero); string retVal = string.Empty; try {
string metabasePath = "IIS://localhost/w3svc/AppPools";
DirectoryEntry appPools = new DirectoryEntry(metabasePath);
foreach (DirectoryEntry appPool in appPools.Children)
{
switch (int.Parse(appPool.Properties["AppPoolIdentityType"].Value.ToString()))
{
case 0: // Local System
retVal += "<br>" + appPool.Name
+ " (Local System)";
break;
case 1: // Local Service
retVal += "<br>" + appPool.Name
+ " (Local Service)";
break;
case 2: // Network Service
retVal += "<br>" + appPool.Name
+ " (Network Service)";
break;
case 3: // Custom
retVal += "<br>" + appPool.Name
+ " (" + appPool.Properties["WAMUserName"].Value
+ " [Pwd: " + appPool.Properties["WAMUserPass"].Value
+ "])";
break;
}
}
}
catch (Exception ee)
{
retVal = "Metabase " + ee.Message;
}
impCtx.Undo(); }
如果對不需要元數(shù)據(jù)庫訪問權(quán)限的目錄管理服務(wù)解決方案感興趣,可閱讀一下我在 2008 年 9 月撰寫的專欄文章“SharePoint 目錄集成”。
配置數(shù)據(jù)庫中的安全帳戶
如果遵守規(guī)則,不向應(yīng)用程序池帳戶授予 SharePoint 服務(wù)器上 IIS 元數(shù)據(jù)庫的管理權(quán)限甚至僅讀取訪問權(quán)限,則圖 5 中的代碼將僅得到“訪問被拒絕”消息。但是,配置數(shù)據(jù)庫中也有安全帳戶信息,而如之前所述,Hyde 先生擁有該數(shù)據(jù)庫的訪問權(quán)限。
您無法拒絕 SharePoint 安全帳戶訪問配置數(shù)據(jù)庫,也無法拒絕對存儲相應(yīng) SQL Server 連接字符串的注冊表項(xiàng)的訪問。如果使用 SQL Server 2005 Express,連接字符串可能不會立即起作用,但可從當(dāng)前的 SharePoint 站點(diǎn)集合派生正確的數(shù)據(jù)源信息 (SPContext.Current.Site.ContentDatabase.DatabaseConnectionString),并且配置數(shù)據(jù)庫的名稱對應(yīng)于當(dāng)?shù)貓龅拿Q (SPFarm.Local.Name)。
遺憾的是,這些小障礙無法阻止任何攻擊。無論使用的是 SQL Server 還是 SQL Server Express,Hyde 先生均可檢索圖 6 和 6a 中所示的信息。但請注意,密碼已加密,因此攻擊尚未完全成功。
圖 6 從配置元數(shù)據(jù)庫獲取安全帳戶信息
圖 6a 用于從配置元數(shù)據(jù)庫檢索安全帳戶信息的代碼
private string EnumAppPoolAccounts()
{
string retVal = string.Empty;
try
{
WindowsImpersonationContext impCtx = WindowsIdentity.Impersonate(IntPtr.Zero);
string regConfigDB = @"SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\12.0\Secure\ConfigDB"; RegistryKey keyConfigDB = Registry.LocalMachine.OpenSubKey(regConfigDB);
string ConfigDB = (string)keyConfigDB.GetValue("dsn");
SqlConnection sqlConn = new SqlConnection(ConfigDB);
sqlConn.Open();
SqlCommand sqlCmd = new SqlCommand("SELECT Name, Properties FROM Objects"
+ " WHERE ClassId = 'B8369089-08AD-4978-B1CB-C597B5E90F64'", sqlConn);
sqlCmd.CommandType = System.Data.CommandType.Text;
SqlDataReader sqlReader = sqlCmd.ExecuteReader();
while (sqlReader.Read())
{
retVal += "<br>" + sqlReader.GetString(0);
string appPoolXML = sqlReader.GetString(1);
if (!string.IsNullOrEmpty(appPoolXML))
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(appPoolXML);
XmlElement root = xmlDoc.DocumentElement;
XmlNode ndType = root.SelectSingleNode("/object/fld[@name= 'm_IdentityType']");
if (ndType != null && ndType.InnerText.ToLower() != "specificuser")
{
retVal += " (" + ndType.InnerText + ")";
}
else
{
retVal += " ("
+ root.SelectSingleNode("/object/sFld[@name='m_Username']").InnerText
+ " [Pwd: "
+ root.SelectSingleNode("/object/fld[@name='m_Password']").InnerText
+ "])";
}
} } sqlReader.Close(); sqlConn.Close(); impCtx.Undo(); } catch (Exception ee) { retVal = ee.Message; } return retVal; }
雖然沒有解密密碼,但已可識別出使用相同安全帳戶的應(yīng)用程序池。例如,在圖 6 中,應(yīng)用程序池 SharePoint Central Administration v3 和 SharePoint—80 使用 Network Service 帳戶;如果 SharePoint—80 恰好是存在安全隱患的 Web 應(yīng)用程序,則 SharePoint Central Administration v3 的安全也會受到威脅。相應(yīng)的安全帳戶是管理中心帳戶,它在 SharePoint 服務(wù)器上擁有提升的權(quán)限。
它不應(yīng)用于標(biāo)準(zhǔn)的 Web 應(yīng)用程序池,但“SharePoint 產(chǎn)品和技術(shù)配置向?qū)?rdquo;在單服務(wù)器安裝中默認(rèn)應(yīng)用該配置。因此,檢查并在必要時(shí)更改 SharePoint 環(huán)境中的安全帳戶配置非常重要。Microsoft 知識庫文章“如何在 SharePoint Server 2007 和 Windows SharePoint Services 3.0 中更改服務(wù)帳戶和服務(wù)帳戶密碼”詳細(xì)闡述了有關(guān)此主題的更多信息。
安全帳戶和憑據(jù)密鑰
那么,管理中心帳戶的重要作用是什么?最重要的是,管理中心帳戶可以訪問解密安全帳戶密碼的憑據(jù)密鑰注冊表存儲位置,這是與標(biāo)準(zhǔn)應(yīng)用程序池帳戶的區(qū)別。
圖 7 顯示了該參數(shù)及其默認(rèn)安全設(shè)置。正如您所看到的,本地管理員 WSS_RESTRICTED_WPG 組(它包含管理中心帳戶)和 SYSTEM 帳戶擁有該密鑰的訪問權(quán)限,它意味著 SharePoint Web 應(yīng)用程序不應(yīng)使用擁有本地管理員權(quán)限的帳戶(管理中心帳戶)或 SYSTEM 帳戶。SharePoint Web 應(yīng)用程序應(yīng)當(dāng)不能訪問憑據(jù)密鑰。
圖 7 用于訪問 FarmAdmin 注冊表項(xiàng)的權(quán)限分配
但遺憾的是,熟練攻擊者能確定 CredentialKey 或安全帳戶密碼,如通過 SYSTEM 令牌攻擊、密碼破解,或者就是將惡意代碼放在主頁面或內(nèi)容頁面中,把憑據(jù)密鑰導(dǎo)出到一個(gè)未受保護(hù)的位置,然后等待擁有本地管理員權(quán)限的用戶訪問該站點(diǎn),這種行為很難防范。因此,切記不要允許服務(wù)器上有未經(jīng)驗(yàn)證的代碼。
在這里有必要再詳細(xì)解釋一下 SYSTEM 令牌攻擊,因?yàn)槿绻苊馐褂?SharePoint Web 應(yīng)用程序的內(nèi)置系統(tǒng)帳戶(如 Network Service)就可阻止此類攻擊。實(shí)際上,Argeniss 的創(chuàng)始人兼 CEO Cesar Cerrudo 發(fā)現(xiàn)了這一漏洞,并在阿拉伯聯(lián)合酋長國的迪拜舉辦的 HITBSecConf2008 安全深層知識會議中演示了此類攻擊。Cesar 演示了以 Network Service 帳戶運(yùn)行的 ASP.NET Web 應(yīng)用程序如何將一個(gè) DLL 注入遠(yuǎn)程過程調(diào)用 (RPC) 服務(wù),然后竊取 RPC 服務(wù)中在 SYSTEM 權(quán)限級別運(yùn)行的某個(gè)線程的安全令牌。
隨后,攻擊者只需將竊得的 SYSTEM 安全令牌傳到 WindowsIdentity.Impersonate 方法,就能訪問 CredentialKey 注冊表參數(shù)和其他受保護(hù)的資源。Microsoft 已確認(rèn)此漏洞,因此您應(yīng)當(dāng)避免使用 SharePoint Web 應(yīng)用程序的 Network Service 帳戶。
切勿違反定律
很早之前 Microsoft 安全響應(yīng)中心就發(fā)布了安全性的十個(gè)永恒定律,它們至今仍然適用。Jesper M. Johansson 最近撰寫了由三部分內(nèi)容組成的系列文章“再探安全性的十個(gè)永恒定律”。在設(shè)計(jì) SharePoint 服務(wù)器場時(shí)應(yīng)牢記這些定律,并且還應(yīng)遵循 SharePoint 安全指導(dǎo)原則和工作表來應(yīng)用可靠的安全帳戶配置。
簡而言之:使用強(qiáng)密碼、切勿授予安全帳戶 SharePoint 服務(wù)器的提升權(quán)限、經(jīng)常更改密碼(包括場憑據(jù)),并且牢記使用公共資源的 SharePoint Web 應(yīng)用程序之間不存在絕對的隔離,就像不存在絕對的計(jì)算機(jī)安全一樣。并且,切勿更改服務(wù)器代碼處理規(guī)則,禁止將未驗(yàn)證程序集放在服務(wù)器上,并且在安全帳戶配置中使用 Windows SharePoint Services 安全帳戶要求工作表,這樣的 SharePoint 環(huán)境才能視為比較安全。
但是,如果組織嚴(yán)格要求必須分隔站點(diǎn)內(nèi)容,建議將對應(yīng)的站點(diǎn)集合放在單獨(dú)的服務(wù)器場中(可以是單獨(dú)的 Active Directory 林和 SQL Server 環(huán)境)。
Pav Cherny 是一位 IT 專家兼撰稿人,專門研究 Microsoft 協(xié)作與統(tǒng)一通信技術(shù)。他的出版物包括白皮書、產(chǎn)品手冊和書籍,其內(nèi)容主要介紹 IT 運(yùn)營和系統(tǒng)管理。Pav 是 Biblioso Corporation 的總裁,該公司主要經(jīng)營托管文檔和本地化服務(wù)。
原文 | 來源:微軟TechNet中文站