第七章 以最小特權(quán)運行_第1頁
第七章 以最小特權(quán)運行_第2頁
第七章 以最小特權(quán)運行_第3頁
第七章 以最小特權(quán)運行_第4頁
第七章 以最小特權(quán)運行_第5頁
已閱讀5頁,還剩45頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、第七章 以最小特權(quán)運行 以最小特權(quán)運行的原則,就是總是使用完成任務(wù)所需 的最小特權(quán)集來執(zhí)行任務(wù)。以最小特權(quán)運行還意味著以盡可 能短的時間使用提升后的特權(quán),這將減少利用該特權(quán)進行攻 擊的時間段。在Windows中,你可以在使用某項特權(quán)前將其 激活,執(zhí)行需要此特權(quán)的任務(wù),然后取消此特權(quán)。 如果在很低的特權(quán)下運行那些會危及安全的軟件,就 可以減少那些會導(dǎo)致安全問題的嚴重程序缺陷(比如緩沖區(qū) 溢出)所帶來的危害。當(dāng)用戶意外或無意中執(zhí)行了具有惡意 的代碼,而這些代碼在提高了用戶權(quán)限的條件下運行,將會 導(dǎo)致安全問題的出現(xiàn)。 第七章 以最小特權(quán)運行 現(xiàn)實中的最小特權(quán) 如果你的應(yīng)用程序不是在提升的特權(quán)下運行,

2、許多攻擊都不 會成功。目前,在互聯(lián)網(wǎng)上最普遍的兩種攻擊方式是病 毒/木馬和破壞Web服務(wù)器,當(dāng)用戶只是以普通身份運行 程序時,許多攻擊是不會成功的。 Back Orifice。 Back Orifice是一種工具,一旦安裝在計算 機中,攻擊者就可以對其進行遠程控制,包括啟動計算 機、執(zhí)行由于程序、瀏覽文件內(nèi)容,而且不為用戶所知。 安裝Back Orifice時,它試圖向Windows的系統(tǒng)文件夾以 及一些注冊表項中寫入一些信息,這些操作只有管理員 才能進行,如果用戶不是計算機管理員,Back Orifice將 會安裝失敗。 第七章 以最小特權(quán)運行 現(xiàn)實中的最小特權(quán) SubSeven。 SubS

3、even能使未經(jīng)授權(quán)的攻擊者通過互聯(lián)網(wǎng) 訪問你的計算機,為了能夠執(zhí)行, SubSeven在Windows 系統(tǒng)文件夾中創(chuàng)建自身的一個拷貝,更新Win.ini和 System.ini,而且修改注冊表中的注冊服務(wù)碼,這些只有 管理員才能執(zhí)行。當(dāng)用戶不是管理員時, SubSeven也會 失敗。 FunLove病毒。當(dāng)這個病毒被運行之后,它通過修改被感 染計算機上的內(nèi)核訪問檢測代碼,從而允許用戶訪問所 有文件。它同樣是向系統(tǒng)文件夾中寫入一個文件,然后 插入到Windows內(nèi)核Ntoskrnl.exe中,除非用戶是管理員, 否則FunLove無法寫入這些文件,從而導(dǎo)致失敗。 第七章 以最小特權(quán)運行 現(xiàn)實

4、中的最小特權(quán) ILoveYou病毒。它將自己寫入系統(tǒng)文件夾中,并試圖更 新注冊表中的信息。同樣只要用戶不是管理員,病毒攻 擊會失敗。 破壞Web服務(wù)器。在微軟的Windows 2000中包含的,并 通過IIS暴露出來的Internet打印協(xié)議(IPP)中,存在著緩沖 區(qū)溢出漏洞,非法的攻擊者可以通過它來對IIS服務(wù)進行 攻擊。真正的危險者是IIP的處理程序,它是作為一個 ISAPI擴展來實現(xiàn)的,并以SYSTEM賬戶運行。如果IPP不 是在本地系統(tǒng)賬戶下運行,那么很少會有網(wǎng)站會被攻擊。 第七章 以最小特權(quán)運行 Windows中較強能力的特權(quán)及其能夠帶來 的安全性問題 Windows用戶帳戶都具有

5、一定的特權(quán)或權(quán)限。這些特權(quán)的例 子包括登陸到一臺計算機、調(diào)試屬于其他用戶的程序、 改變系統(tǒng)時間等。特權(quán)是一臺計算機的本地權(quán)限,但它 可以通過組策略(Group Policy)分布到域中的多臺計算機 上。一個用戶可能在一臺計算機上有一組特權(quán),在另一 臺計算機上有另一組特權(quán)。用本地策略(Local Policy)選項 為你自己計算機上的用戶帳戶設(shè)置特權(quán),不會對網(wǎng)絡(luò)中 任何計算機上的特權(quán)策略產(chǎn)生影響。 第七章 以最小特權(quán)運行 Windows中較強能力的特權(quán)及其能夠帶來 的安全性問題 一些能力較強的Windows特權(quán) 顯示的名稱顯示的名稱內(nèi)部名稱內(nèi)部名稱#define(Winnt.h) 備份文件和目錄

6、SeBackupPrivilege(16)SE_BACKUP_NAME 還原文件和目錄SeRestorePrivilege(17)SE_RESTORE_NAME 作為操作系統(tǒng)的一部分SeTcbPrivilege(6)SE_TCB_NAME 調(diào)試程序SeDebugPrivilege(19)SE_DEBUG_NAME 替換進程級別的令牌SeAssignPrimaryTokenPrivilege(2)SE_ASSIGNPRIMARYTOKEN_NAME 裝載和卸載設(shè)備驅(qū)動程序SeLoadDriverPrivilege(9)SE_LOAD_DRIVER_NAME 獲取文件和其他對象的所 有權(quán) SeTa

7、keOwnershipPrivilege(16)SE_TAKE_OWNERSHIP_NAME 第七章 以最小特權(quán)運行 Windows中較強能力的特權(quán)及其能夠帶來 的安全性問題 SeBackupPrivilege問題 實例:執(zhí)行如下步驟: (1)以具有備份特權(quán)的身份登錄,例如一個本地的管理員 (administrator)或一個備份操作員(backup operator)。 (2)創(chuàng)建一個小文件,取名為Test.txt,其中包含一些無用 的文本。 (3)使用ACL編輯工具,在文件中添加一個拒絕ACE來拒絕 你自己的賬戶對該文件的訪問。假如你的賬戶名為Blake, 則添加一個Blake(全部拒絕)

8、ACE。 (4)編譯并運行下面的代碼。 第七章 以最小特權(quán)運行 Windows中較強能力的特權(quán)及其能夠帶來 的安全性問題 SeBackupPrivilege問題 一個具有備份文件和目錄的特權(quán)賬戶能夠讀取那些在正常情 況下該賬戶所不能訪問的文件。 如果一個叫Blake的用戶要備份一個文件,正常情況下,該文 件的ACL將拒絕Blake的訪問,而實際上,由于該賬戶具 有備份文件和目錄的特權(quán),正是這個特權(quán)使得他可以讀 取該文件。一個備份程序可以在調(diào)用CreateFile時,通過 設(shè)置FILE_FLAG_BACKUP_SEMANTICS標志的值來對文件進 行讀取。 第七章 以最小特權(quán)運行 /*WOWAc

9、cess.cpp*/ #include #include int EnablePriv(char *szPriv) HANDLE hToken=0; if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, return -1; TOKEN_PRIVILEGES newPrivs; if(!LookupPrivilegeValue(NULL, szPriv, CloseHandle(hToken); return -1; BOOL OpenProcessToken( HANDLE ProcessHandle, DWOR

10、D DesiredAccess, PHANDLE TokenHandle ); 第一參數(shù)是要修改訪問權(quán)限的進程句柄;第三個參數(shù)就是返回的訪問令牌指針; 第二個參數(shù)指定你要進行的操作類型,如要修改令牌我們要指定第二個參數(shù)為 TOKEN_ADJUST_PRIVILEGES(其它一些參數(shù)可參考PlatformSDK)。 第一個參數(shù)為第一個參數(shù)為系統(tǒng)的名稱,若為空,則在當(dāng)前的sysytem查找。第二個參第二個參 數(shù)數(shù)指明了權(quán)限的名稱,如“SeDebugPrivilege”。第三個參數(shù)第三個參數(shù)返回LUID的 指針。返回一個權(quán)限的局部唯一標識(Local Unique IDentifier) 。 第七章

11、 以最小特權(quán)運行 newPrivs.Privileges0.Attributes=SE_PRIVILEGE_ENABLE; newPrivs.PrivilegeCount=1; if(!AdjustTokenPrivileges(hToken, FALSE, CloseHandle(hToken); return -1; if(GetLastError()=ERROR_NOT_ALL_ASSIGNED) printf(“AdjustTokenPrivileges() succeeded, but not all privs setn”); CloseHandle(hToken); return

12、 0; 第一個參數(shù)是訪問令牌的句柄;第二個參數(shù)決定是進行權(quán) 限修改還是禁止(Disable)所有權(quán)限;第三個參數(shù)指明要 修改的權(quán)限,是一個指向 TOKEN_PRIVILEGES結(jié)構(gòu)的指針, 該結(jié)構(gòu)包含一個數(shù)組,數(shù)據(jù)組的每個項指明了權(quán)限的類型 和要進行的操作; 第四個參數(shù)是結(jié)構(gòu)PreviousState的長 度,如果PreviousState為空,該參數(shù)應(yīng)為NULL;第五個參 數(shù)也是一個指向 TOKEN_PRIVILEGES結(jié)構(gòu)的指針,存放修改 前的訪問權(quán)限的信息,可空;最后一個參數(shù)為實際 PreviousState結(jié)構(gòu)返回的大小。 第七章 以最小特權(quán)運行 void DoIT(char *szF

13、ileName, DWORD dwFlags) printf(“nnAttempting to read %s, with 0 x%x flagsn”, szFileName, dwFlags); HANDLE hFile=CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, dwFlags, NULL); if(hFile=INVALID_HANDLE_VALUE) printf(“CreateFile() failed -%d, GetLastError(); return; char buff

14、128; DWORD cbRead=0, cbBuff=sizeof buff; ZeroMemory(buff, sizeof buff); if(ReadFile(hFile, buff, cbBuff, else printf(“ReadFile() failed -%d, GetLastError(); CloseHandle(hFile); 第七章 以最小特權(quán)運行 void main(int argc, char *argv) if(argc2) printf(“Usage: %s ”, argv0); return; /Need to enable backup priv firs

15、t. if(EnablePriv(SE_BACKUP_NAME)=-1) return; /Try with no backup flag should get access denied. DoIt(argv1, FILE_ATTRIBUTE_NORMAL); /Try with backup flagshould work! DoIt(argv1, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS); 第七章 以最小特權(quán)運行 程序運行后會得到如下類似結(jié)果: Attempting to read Test.txt, with 0 x80 fla

16、gs CreateFile() failed -5 Attempting to read Test.txt, with 0 x2000080 flags Success, read 15 bytes Text is: Hello, Blake! 所以賦予這一用戶權(quán)限將成為一個安全風(fēng)險。既然無法確定 一個用戶是在合法地備份數(shù)據(jù),還是在偷竊數(shù)據(jù),那么就只 向可信任的用戶賦予這一用戶權(quán)限。 第七章 以最小特權(quán)運行 SeRestorePrivilege問題 這項特權(quán)與備份特權(quán)正相反。利用這項特權(quán),攻擊者可以改寫文件,包括一般情 況下不能訪問的DLL和EXE!攻擊者可以利用這項特權(quán)來改變對象的所有權(quán),

17、而所有者具有對象的完全控制。 SeDebugPrivilege問題 一個具有調(diào)試特權(quán)的用戶,能夠依附于任何的進程并可以查看或調(diào)整其內(nèi)存。因 此,如果一個應(yīng)用程序中,有一些秘密需要保護,任何具有這個特權(quán)并且 完全知道如何訪問的用戶都能夠通過使用調(diào)試器調(diào)試該進程來訪問到秘密 數(shù)據(jù)。 調(diào)試程序特權(quán)同時也允許調(diào)用者通過調(diào)用TerminateProcess函數(shù)來結(jié)束計算機上的 任何進程。因此,具有該特權(quán)的非管理員也可以通過結(jié)束一個關(guān)鍵系統(tǒng)進 程,比如LSA(Local Security Authority, 本地安全授權(quán))Lsass.exe,來關(guān)閉計 算機。 還有一種更為危險的可能性,一個具有調(diào)試特權(quán)的

18、攻擊者能夠使用 CreateRemoteThread函數(shù)在任何正在運行的進程中執(zhí)行代碼。例如,在 Lsass.exe中注入一個新線程來執(zhí)行代碼,讀取已經(jīng)經(jīng)過LSA解密的私有數(shù)據(jù), 從而查看存儲在LSA中的秘密數(shù)據(jù)。 第七章 以最小特權(quán)運行 SeTcbPrivilege問題 如果一個賬戶的權(quán)限是作為操作系統(tǒng)的一部分,實質(zhì)上他可以作為一個高可信的 系統(tǒng)組件進行工作。這個特權(quán)同時也被稱作TCB(Trusted Computing Base, 可 信計算庫)特權(quán)。TCB是最為可信的,因而也是Windows系統(tǒng)中最危險的特權(quán)。 因為這一點,具有該特權(quán)的唯一賬戶默認為SYSTEM(系統(tǒng))。 SeLoadD

19、riverPrivilege問題 在內(nèi)核中運行的可執(zhí)行代碼是高度可信任的,可以進行任何可能的任務(wù)。將代碼 載入到內(nèi)核中需要SeLoadDriverPrivilege特權(quán)。在默認情況下,只有管理員 才有此項特權(quán)。裝載即插即用驅(qū)動程序并不需要這項特權(quán),因為即插即用 服務(wù)裝載的代碼是以SYSTEM賬戶運行的。 SeRemoteShutdownPrivilege問題 這項特權(quán)允許關(guān)閉遠程計算機。注意,與所有特權(quán)一樣,用戶賬戶的此項特權(quán)必 須在目標計算機上被激活。 SeTakeOwnershipPrivilege問題 所有者總是擁有對該賬戶所有的任何對象的完全控制。具有此項特權(quán)的賬戶就可 能從對象的原始

20、所有者那里取得所有權(quán)。其結(jié)果就是一個賬戶可能擁有對 系統(tǒng)中任何對象的全部控制。 第七章 以最小特權(quán)運行 令牌、特權(quán)、SID、ACL和進程之間的關(guān)系(*) 當(dāng)用戶登錄運行Windows NT、2000、或XP的計算機時,同時這個 用戶通過了身份認證,則操作系統(tǒng)會為用戶創(chuàng)建一個稱為令 牌(Token)的數(shù)據(jù)結(jié)構(gòu),這個令牌將用于所有由該用戶激活 的進程和其中的每個線程。這個令牌包含該用戶的SID、該用 戶所屬的每一個組的SID和用戶所具有的特權(quán)列表等信息。 Windows NT、Windows 2000、Windows XP中的所有進程都以某一 個身份運行。也就是說,一個令牌與特定進程相關(guān)聯(lián)。一般

21、來說,進程以啟動該應(yīng)用程序的用戶的身份運行。然而,應(yīng) 用程序也可以被一個具有適當(dāng)特權(quán)的用戶通過調(diào)用 CreateProcessAsUser函數(shù)來以其他用戶的身份啟動。典型情況 下,調(diào)用CreateProcessAsUser函數(shù)的進程必須具有 SeAssignPrimaryTokenPrivilege和SeIncreaseQuataPrivilege特權(quán)。 第七章 以最小特權(quán)運行 令牌、特權(quán)、SID、ACL和進程之間的關(guān)系 服務(wù)是另外一種類型的進程,它以服務(wù)控制管理器(SCM)中定 義的身份運行。許多服務(wù)默認以本地系統(tǒng)賬戶來運行,但是 也可以通過在SCM輸入相應(yīng)賬戶的用戶名和密碼來將其配置 為使

22、用其他賬戶運行。 因為進程與賬戶令牌相關(guān)聯(lián),因此,它具有其所屬工作組的所有 資格和特權(quán),它可以被認為是該賬戶的主體(principal),該賬 戶能夠做的,該進程都能夠做到。 一個令牌中包含有SID和特權(quán)。其中的SID用于根據(jù)資源中的ACL來 進行訪問檢查,而令牌中的特權(quán)則用于完成特定的在機器范 圍內(nèi)的任務(wù)。 第七章 以最小特權(quán)運行 應(yīng)用程序要求提高特權(quán)的三個理由 非管理工具的應(yīng)用程序為什么需要使用管理訪問權(quán),一般有三個原因: ACL問題。 特權(quán)問題。 使用LSA秘密。 ACL問題 假定NTFS分區(qū)中的一個文件夾,具有下列ACL: SYSTEM(完全控制)。 Administrators(完全

23、控制)。 Everyone(讀?。?。 除非你是管理員或SYSTEM賬戶,你對該文件夾所進行的操作只能是讀取 文件。 第七章 以最小特權(quán)運行 應(yīng)用程序要求提高特權(quán)的三個理由 ACL問題 有些應(yīng)用程序要向文件系統(tǒng)中受保護的區(qū)域,或向操作系統(tǒng) 中其他部分如注冊表中寫入數(shù)據(jù),這些應(yīng)用程序必須在 管理員賬戶下執(zhí)行,才能進行正確的操作。如許多游戲 向C:Program Files文件夾中寫入最高分信息,這就意味 著玩這些游戲的用戶必須是管理員。 特權(quán)問題 如果你的賬戶需要特定的特權(quán)來完成任務(wù),比如備份文件, 那么你確實需要這項特權(quán)。但是,要謹慎地讓管理員向 用戶賬戶添加過多存在潛在危險的特權(quán),或者讓你的用

24、 戶擁有過多不必要的特權(quán)。 第七章 以最小特權(quán)運行 應(yīng)用程序要求提高特權(quán)的三個理由 使用LSA秘密 LSA可以為應(yīng)用程序存儲機密數(shù)據(jù)。操作LSA秘密的API包括 LsaStorePrivateData和LsaRetrievePrivateData。為了使用 LSA秘密,執(zhí)行這些任務(wù)的進程必須是本地管理員組的成 員。 由于以上問題,普通用戶常常要求提高特權(quán)。 第七章 以最小特權(quán)運行 解決提高特權(quán)的問題 解決ACL問題 以適當(dāng)?shù)脑L問權(quán)打開資源。即僅以所需的許可權(quán)來打開 資源。如果你要讀取一個注冊表項,就只請求只讀訪問 權(quán)即可。 將用戶數(shù)據(jù)保存在用戶能夠?qū)懭氲牡胤?。要求不要將?戶數(shù)據(jù)寫到操作系統(tǒng)受

25、保護的地方,如將用戶文件寫到 用戶的profile目錄。 放寬ACL??梢陨陨苑艑扐CL,因為將ACL降格的風(fēng)險比 要求所有用戶都成為管理員的風(fēng)險會小一些。 解決特權(quán)問題 如果你需要一項完成任務(wù)的特權(quán),那么就必須這么做,沒有 簡單的解決辦法。 第七章 以最小特權(quán)運行 解決提高特權(quán)的問題 解決LSA問題 在Windows 2000及以后版本中,有一種可用的解決方案,稱 為數(shù)據(jù)保護API或DPAPI。使用DPAPI,應(yīng)用程序在訪問秘 密數(shù)據(jù)時,不需要用戶成為管理員,而是將數(shù)據(jù)使用一 個與用戶關(guān)聯(lián)的密鑰進行保護,這樣數(shù)據(jù)的所有者就可 以訪問數(shù)據(jù)了。 第七章 以最小特權(quán)運行 確定適當(dāng)特權(quán)的過程(*)

26、下面的過程可以幫助你根據(jù)應(yīng)用程序的需要來確定 每個SID和特權(quán)是否應(yīng)該包含在令牌中: 找出該應(yīng)用程序所要使用的每個資源。 找出該應(yīng)用程序所使用的有特權(quán)的API。 對應(yīng)用程序運行時需要哪一個賬戶進行評估。 查明令牌中的SID和特權(quán)。 確定執(zhí)行該應(yīng)用程序任務(wù)所需要的所有SID和特 權(quán)。 對令牌進行調(diào)整以滿足上一步的要求。 第七章 以最小特權(quán)運行 確定適當(dāng)特權(quán)的過程 步驟1,找到應(yīng)用程序使用的資源 第一步是列出應(yīng)用程序用到的所有資源的列表,包括:文件、注冊表項、 活動目錄數(shù)據(jù)、命名管道、socket等等。同時也需要列出對于這些 資源需要使用哪種權(quán)限的訪問。如下是一個假設(shè)的應(yīng)用程序所使用 的資源列表:

27、 資源資源所需要的訪問權(quán)限所需要的訪問權(quán)限 配置數(shù)據(jù)由于管理員必須配置這個應(yīng)用程序,所以需要完全的 控制。其他用戶只需要對該數(shù)據(jù)具有讀權(quán)限即可。 一個命名管道上的輸 入數(shù)據(jù) 每個用戶都需要使用這個管道來讀寫數(shù)據(jù)。 應(yīng)用程序要將文件寫 入的數(shù)據(jù)目錄 每個用戶都可以創(chuàng)建文件,并對屬于他的數(shù)據(jù)進行任 何操作。每個用戶都可以讀取他人的文件。 應(yīng)用程序所在的目錄每個用戶都可以讀取并執(zhí)行該應(yīng)用程序,管理員可以 安裝和更新。 第七章 以最小特權(quán)運行 步驟2,找到應(yīng)用程序使用的特權(quán)API 分析應(yīng)用程序中使用了哪些有特權(quán)的API。針對上述假設(shè)的例子,列出了所調(diào)用的有特權(quán)的 API。 函數(shù)名函數(shù)名所需要的權(quán)限或成

28、員關(guān)系所需要的權(quán)限或成員關(guān)系 使用FILE_FLAG_BACKUP_SEMANTICS選項的CreateFileSeBackupPrivilege LogonUserSeTcbPrivilege(Windows XP和Windows 2003不需要) SetTokenInformationSeTcbPrivilege ExitWindowsExSeShutdownPrivilege 使用安全事件日志的OpenEventLogSeSecurityPrivilege 面向所有桌面(BSM_ALLDESKTOPS)的BroadcastSystemMessageExSeTcbPrivilege Reg

29、isterLogonProcessSeTcbPrivilege InitiateSystemShutdownExSeShutdownPrivilege或SeRemoteShutdownPrivilege SetSystemPowerStateSeShutdownPrivilege GetFileSecuritySeSecurityPrivilege 當(dāng)調(diào)試另一賬戶下運行的進程時調(diào)用的調(diào)試函數(shù),包括 DebugActiveProcess和ReadProcessMemory SeDebugPrivilege CreateProcessAsUserSeIncreaseQuataPrivilege,

30、通常還有SeAssignPrimaryTokenPrivilege CreatePrivateObjectSecurityExSeSecurityPrivilege SetSystemTimeSeSystemtimePrivilege VirtualLock和AllocateUserPhysicalPagesSeLockMemoryPrivilege 網(wǎng)絡(luò)API,例如NetUserAdd和NetLocalGroupDel對于許多調(diào)用,調(diào)用者必須是某些組的成員,如Administrators或Account Operators NetjoinDomainSeMachineAccountPrivi

31、lege 第七章 以最小特權(quán)運行 步驟3,哪一個賬戶是必需的 記下運行應(yīng)用程序時所需要的賬戶。比如確定你的應(yīng)用程 序是否需要以管理員的賬戶運行,或者你的服務(wù)是否需要本 地系統(tǒng)賬戶來運行。 步驟4,獲取令牌的內(nèi)容 查明上一步中確定的賬戶所對應(yīng)的令牌中的SID和特權(quán)。 你既可以使用你想要測試的賬戶身份登錄,來確定這些信息, 也可以使用RunAs命令來創(chuàng)建一個新的命令解釋程序 (command shell)來實現(xiàn)。例如,如果你需要你的程序以管理 員的身份來運行,你可以輸入下面的命令: RunAs /user:MyMachineAdministrator cmd.exe 第七章 以最小特權(quán)運行 下面的

32、代碼將顯示用戶令牌中的各種重要的信息: /*MyToken*/ #define SECURITY_WIN32 #include “windows.h” #include “security.h” #include “strsafe.h” #define MAX_NAME 256 /This function determines memory required /and allocates it. The memory must be freed by caller. LPVOID AllocateTokenInfoBuffer(HANDLE hToken, TOKEN_INFORMATION

33、_CLASS InfoClass, DWORD *dwSize) *dwSize=0; GetTokenInformation(hToken, InfoClass, NULL, *dwSize, dwSize); return new BYTE*dwSize; /Get user name(s) Void GetUserNames() EXTENDED_NAME_FORMAT enf=NameDisplay, NameSamCompatible, NameUserPrincipal; for(int i=0; iGroupCount) printf(“tNone!n”); for(DWORD

34、i=0; iGroupCount; i+) SID_NAME_USE SidType; char lpNameMAX_NAME; char lpDomianMAX_NAME; DWORD dwNameSize=MAX_NAME; DWORD dwDomainSize=MAX_NAME; DWORD dwAttr=0; if(!LookupAccountSid(NULL, pSIDInfo-Groupsi.Sid, lpName, else printf(“LookupAccountSid Error %un”, GetLastError(); else dwAttr=pSIDInfo-Grou

35、psi.Attributes; printf(“%12s%-20st%sn”, lpDomain, lpName, (dwAttr delete (LPBYTE)pSIDInfo; 第七章 以最小特權(quán)運行 /Display privileges. void GetPrivis(HANDLE hToken) DWORD dwSize=0; TOKEN_PRIVILEGES *pPrivileges=(PTOKEN_PRIVILEGES)AllocateTokenInfoBuffer(hToken, TokenPrivileges, if(!pPrivileges) return; BOOL bR

36、es=GetTokenInformation(hToken, TokenPrivileges, pPrivileges, dwSize, if(FALSE=bRes) printf(“GetTokenInformation failedn”); for(DWORD i=0; iPrivilegeCount; i+) char szPrivilegeName128; DWORD dwPrivilegeNameLength=sizeof(szPrivilegeName); if(LookupPrivilegeName(NULL, else printf(“LookupPrivilegeName f

37、ailed - %lun”, GetLastError(); delete (LPBYTE)pPrivileges; 第七章 以最小特權(quán)運行 int main() if(!ImpersonateSelf(SecurityImpersonation) printf(“ImpersonateSelf Error %un”, GetLastError(); return -1; HANDLE hToken=NULL; if(!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, return -1; printf(“nUser Namen”); Get

38、UserNames(); printf(“nSIDSn”); GetAllSIDs(hToken, TokenGroups); printf(“nRestricting SIDSn”); GetAllSIDs(hToken, TokenRestrictedSids); printf(“nPrivilegesn”); GetPrivs(hToken); RevertToSelf(); CloseHandle(hToken); return 0; 第七章 以最小特權(quán)運行 注:這段代碼首先打開當(dāng)前線程的令牌,并在 該令牌中查找該線程的用戶名、SID、限定SID和 特權(quán)。函數(shù)GetUser、GetAl

39、lSIDs和GetPrivs能夠 完成上面的主要工作。GetAllSIDs函數(shù)有兩種形 式,一種是獲得SID,另一種是獲得限定SID。限 定SID是從一個可選的SID列表中添加到訪問令牌 中的SID,用來對一個進程或線程的訪問級別進 行限制,使得他們的訪問級別比本來可以訪問 的級別更低。 第七章 以最小特權(quán)運行 在上述例子中,應(yīng)用程序需要以管理員的身份運行。通過MyToken.cpp,可以得到管理員令牌的默認內(nèi)容: User NORTHWINDTRADERSblake SIDS NORTHWINDTRADERSDomain Users Everyone BUILTINAdministrator

40、s BUILTINUsers NT AUTHORITYINTERACTIVE NT AUTHORITYAuthenticated Users Restricting SIDS None Privileges SeChangeNotifyPrivilege (3) SeSecurityPrivilege (0) SeBackupPrivilege (0) SeRestorePrivilege (0) SeSystemtimePrivilege (0) SeShutdownPrivilege (0) SeRemoteShutdownPrivilege (0) SeTakeOwnershipPriv

41、ilege (0) SeDebugPrivilege (0) SeSystemEnvironmentPrivilege (0) SeSystemProfilePrivilege (0) SeProfileSingleProcessPrivilege (0) SeIncreaseBasePriorityPrivilege (0) SeLoadDriverPrivilege (2) SeCreatePagefilePrivilege (0) SeIncreaseQuataPrivilege (0) SeUndockPrivilege (2) SeManageVolumePrivilege (0)

42、第七章 以最小特權(quán)運行 步驟5,所有SID和特權(quán)是否都是必需的 讓設(shè)計、開發(fā)和測試組的成員去分析令牌中每個SID和特 權(quán),并確定哪一個是所需要的。執(zhí)行這個任務(wù)要將第4步中 得到的令牌內(nèi)容與資源列表以及在第1步和第2步中使用的API 函數(shù)進行比較。如果令牌中的SID和特權(quán)與需求不一致,則可 以考慮除去它們。 注意:許多SID是良性的,比如Users和Everyone,你不必 從令牌中刪除它們。 第七章 以最小特權(quán)運行 步驟6,調(diào)整令牌 后一步是降低令牌的能力,這可以使用三種方法: 允許較低權(quán)限的用戶來執(zhí)行你的應(yīng)用程序。 使用限定的令牌。 永久地除去不必要的特權(quán) 允許較低權(quán)限的用戶來執(zhí)行你的應(yīng)用程

43、序 可以允許較低權(quán)限的用戶來執(zhí)行你的應(yīng)用程序,但是卻不 能允許他們執(zhí)行某些功能,如不允許執(zhí)行備份等這樣的功能。 如一個基于Web的產(chǎn)品,不要因為需要管理員添加一個新的 用戶賬戶,而要求該應(yīng)用程序以SYSTEM的身份來運行。 第七章 以最小特權(quán)運行 上述例子可采用如下方法: 以預(yù)置好的具有較低特權(quán)的賬戶來運行系統(tǒng),而取代以本 地系統(tǒng)賬戶來運行。 讓程序要求管理員通過使用Windows身份驗證來鑒別自己 的身份,從而執(zhí)行高特權(quán)的操作,如添加一個新的賬戶。 讓程序模仿用戶賬號并嘗試執(zhí)行用戶賬戶的數(shù)據(jù)庫操作, 如果操作系統(tǒng)拒絕訪問,則這個賬戶不是管理員。 從安全的觀點出發(fā),以較低特權(quán)賬戶運行程序是不可

44、替代 的。如果一個進程以SYSTEM身份或其他較高權(quán)限的賬戶運行, 這個進程將模擬用戶來降低該進程的能力,攻擊者能夠通過 注入代碼來獲得SYSTEM權(quán)限。比如通過緩沖區(qū)溢出,調(diào)用 RevertToSelf,在這一時刻,進程停止模擬。而轉(zhuǎn)為該進程的 身份,即SYSTEM。 第七章 以最小特權(quán)運行 使用限定令牌 在Windows 2000及以后版本中添加了一個新的特性,即能 夠獲得用戶令牌并降低或限定它的能力。一個限定的令牌是 原始或模仿的令牌在調(diào)用了CreateRestrictedToken函數(shù)之后產(chǎn) 生的。在限定令牌的安全環(huán)境下運行的進程或線程,被限制 了訪問安全對象或執(zhí)行特權(quán)操作的能力??梢?/p>

45、使用 CreateRestrictedToken函數(shù)對令牌執(zhí)行下面三步操作來限制令 牌: 從令牌中刪除一些特權(quán)。 指定一個限定SID的列表。 對SID應(yīng)用“只拒絕(deny-only)”的屬性。 第七章 以最小特權(quán)運行 刪除權(quán)限。刪除在令牌中你不想要的任何特權(quán),而且它們在以 后也不會被添加進去。為了重新獲得被刪除的特權(quán),該進程必須 被銷毀并重新創(chuàng)建。 指定限定SID。通過給訪問令牌添加限定SID,你可以決定在令 牌中允許哪些SID。當(dāng)受限進程或線程試圖去訪問可用對象時,系 統(tǒng)會同時在可用的SID集和限定SID列表中進行訪問驗證。只有兩者 檢查都成功,才允許對指定對象的訪問。 例如:一個文件的A

46、CL允許Everyone具有讀權(quán)限,而 Administrators具有讀、寫以及刪除的權(quán)限。而你的應(yīng)用程序不 能刪除該文件。比如一個Brian用戶是管理員和市場部經(jīng)理。代表 Brian的令牌應(yīng)該具有下面的SID: Everyone Authenticated Users Administrators Marketing 應(yīng)該選擇一個僅由Everyone SID組成的限定SID。 第七章 以最小特權(quán)運行 給SID應(yīng)用“只拒絕”的屬性?!爸痪芙^”的SID改變了令牌中的 一個SID,以致使該令牌只能用來拒絕相應(yīng)賬戶對安全資源的 訪問,不能使用該SID來允許對一個資源的訪問。比如,一個 資源可能具有

47、與之相關(guān)聯(lián)的“Marketing”(拒絕所有的訪問) ACE,則該用戶組被拒絕訪問。然而,如果一個資源包含 “Marketing”(允許讀)ACE, “只拒絕”屬性Marketing SID處于 用戶訪問的令牌中,那么只有這個用戶被拒絕對該資源進行 讀操作。 簡單地從令牌中刪除一個SID將會導(dǎo)致安全問題,而這也 是為什么SID能夠被標記為“只拒絕”的原因??梢韵胂笠粋€資 源上的ACL拒絕Marketing對該資源的訪問。如果你的代碼將 Marketing SID從用戶令牌中刪除,用戶反而可以使用該資源。 因此,該SID應(yīng)該標記為“只拒絕”,而不是將其從令牌中刪除。 第七章 以最小特權(quán)運行 何時

48、使用限定令牌 如果你知道你的程序不需要某一層次的訪問,你可以將其 標記為“只拒絕”。 如果你知道這樣一類用戶或組,他們不需要對程序所用到 的資源進行訪問,那么請使用限定SID。 如果你的應(yīng)用程序裝載任意的代碼,你應(yīng)該考慮使用限定 令牌。如果對任意的文件調(diào)用ShellExecute或CreateProcess, 你可能考慮使用限定的令牌。 第七章 以最小特權(quán)運行 限定令牌的代碼實例 限定令牌可以傳遞給CreateProcessAsUser以創(chuàng)建一個進程, 這個進程具有受限的權(quán)限和特權(quán)。這些令牌同樣可以在調(diào)用 ImpersonateLoggedOnUser或SetThreadToken時使用,從而

49、能 夠讓調(diào)用線程模擬一個已登錄用戶的安全上下文,該用戶由 一個限定令牌的句柄表示。 下面的示例代碼顯示了如何根據(jù)目前進程的令牌來創(chuàng)建一 個新的限定令牌。這個令牌除了具有SeChangeNotifyPrivilege 特權(quán),其他特權(quán)都被刪除了。 第七章 以最小特權(quán)運行 /*Restrict.cpp*/ /Create a SID for the BUILTINAdministrators Group. BYTE sidBuffer256; PSID pAdminSID=(PSID)sidBuffer; SID_IDENTIFIER_AUTHORITY SIDAuth=SECURITY_NT_AU

50、THORITY; if(!AllocateAndInitializeSid( return -1; /Change the local administrators SID to a deny-only SID. SID_AND_ATTRIBUTES SidToDisable1; SidToDisable0.Sid=pAdminSID; SidToDisable0.Attributes=0; /Get the current process token. HANDLE hOldToken=NULL; i f ( ! O p e n P r o c e s s T o k e n ( G e t

51、 C u r r e n t P r o c e s s ( ) , TOKEN_ASSIGN_PRIMARY|TOKEN_DUPLICATE|TOKEN_QUERY|TOKEN_ADJUST_DEFAULT, return -1; 第七章 以最小特權(quán)運行 /Create restricted token from the process token. HANDLE hNewToken=NULL; if(!CreateRestrictedToken(hOldToken, DISABLE_MAX_PRIVILEGE, 1, SidToDisable, 0, NULL, 0, NULL, retu

52、rn -1; if(pAdminSID) free(pAdminSID); /The following code creates a new process with the restricted token. PROCESS_INFORMATION pi; STARTUPINFO si; ZeroMemory( si.cb=sizeof(STARTUPINFO); si.lpDesktop=NULL; /Build the path to cmd.exe to make sure were not running a Trojaned cmd.exe. char szSysDirMAX_P

53、ATH+1; if(GetSystemDirectory(szSysDir, MAX_PATH) char szCmdMAX_PATH+1; if(StringCchCopy(szCmd, MAX_PATH, szSysDir)=S_OK CloseHandle(hOldToken); CloseHandle(hNewToken); return 0; 第七章 以最小特權(quán)運行 下面的代碼顯示了如何在多線程應(yīng)用程序中使用限定令牌。該線程調(diào)用函數(shù)ThreadFunc,刪除了線程令牌中的所有特權(quán),然后該線 程調(diào)用了DoThreadwork函數(shù)。 #include DWORD WINAPI Threa

54、dFunc(LPVOID lpParam) DWORD dwErr=0; try if(!ImpersonateSelf(SecurityImpersonation) throw GetLastError(); HANDLE hToken=NULL; HANDLE hThread=GetCurrentThread(); if(!OpenThreadToken(hThread, TOKEN_ASSIGN_PRIMARY|TOKEN_DUPLICATE|TOKEN_QUERY|TOKEN_IMPERSONATE, TRUE, HANDLE hNewToken=NULL; if(!CreateRes

55、trictedToken(hToken, DISABLE_MAX_PRIVILEGE, 0, NULL, 0, NULL, 0, NULL, if(!SetThreadToken( /DoThreadWork operates in restricted context. DoThreadWork(hNewToken); catch (DWORD d) dwErr=d; if(dwErr=0) RevertToSelf(); return dwErr; void main() HANDLE h=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thre

56、adFunc, NULL, CREATE_SUSPENDED, NULL); if(h) ResumeThread(h); 第七章 以最小特權(quán)運行 Windows XP的軟件限制策略 Windows XP包括一個新的功能,叫做“軟件限制策 略”(Software Restriction Policy,也叫做SAFER),它使限定令牌 在程序中更容易被使用和部署。 SAFER也包括一些函數(shù),它們在Winsafer.h中聲明,它能夠 更加容易地與降低了權(quán)限的令牌配合使用。其中一個函數(shù)是 SafeComputeTokenFromLevel。這個函數(shù)能夠接收發(fā)送來的令 牌并對其進行改變,以匹配預(yù)先定義

57、的降低了的功能級別。 下面的代碼展示了如何創(chuàng)建一個以一般用戶(NormalUser) 身份運行的新進程,這種身份就是非管理員和非高級用戶 (PowerUser)賬戶。 第七章 以最小特權(quán)運行 /*SAFER.cpp*/ #include #include #include #include #include void main() SAFER_LEVEL_HANDLE hAuthzLevel; /Valid programmatic SAFER levels: /SAFER_LEVELID_FULLYTRUSTED /SAFER_LEVELID_NORMALUSER /SAFER_LEVELI

58、D_CONSTRAINED /SAFER_LEVELID_UNTRUSTED /SAFER_LEVELID_DISALLOWED /Create a normal user level. if(SaferCreateLevel(SAFER_SCOPEID_USER, SAFER_LEVELID_NORMALUSER, 0, if(SaferComputeTokenFromLevel( hAuthzLevel,/Safer Level handle NULL,/NULL is current thread token. if(GetSystemDirectory(szSysDir, sizeof

59、(szSysDir) StringCbPrintf(szPath, sizeof(szPath), “%scmd.exe”, szSysDir); STARTUPINFO si; ZeroMemory( si.cb=sizeof(STARTUPINFO); si.lpDesktop=NULL; PROCESS_INFOMATION pi; if(!CreateProcessAsUser( hToken, szPath, NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, SaferCloseLevel(hAuthzLevel); 第

60、七章 以最小特權(quán)運行 永久地除去不必要的特權(quán) Windows Server 2003種添加了一項新特性,可以從運行的應(yīng)用程序中除去特權(quán),而不 是從復(fù)制的線程中除去。其特點是這些特權(quán)將永遠不會被應(yīng)用程序使用,無論代 碼是在正常運行還是正受到攻擊。 一般來講,除去特權(quán)的代碼將在應(yīng)用程序啟動時調(diào)用,下面的代碼是從進程令牌中移 去兩個特權(quán)的實例。 /RemPriv #ifndef SE_PRIVILEGE_REMOVED #define SE_PRIVILEGE_REMOVED (0 x00000004) #endif DWORD RemovePrivs(LPCTSTR szPrivs, DWORD

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論