Windows 的存取控制
Copyright MikeFeng
安全層級:基於NT
核心的Windows
是C2
層級的。 c2是俗稱橘皮書(orange book)規格中的一個安全層級。橘皮書(the orangebook)是美國國家安全域(nsa)的國家電腦資訊安全中心(ncsc)於1983年8月頒發的官方標準,其正式名稱是“受信任電腦系統評量基準(trusted computer system evaluation criteria)",其封面為橘黃色,以此得名.橘皮書是目前頗具權威的電腦系統安全標準之一,ncsc也負責進行電腦系統及相關產品的安全性測試. 橘皮書中對可信任系統的定義是這樣的:一個由完整的硬體及軟體所組成的系統,在不違反存取權限的情況下,它能同時服務於不限定個數的使用者,並處理從一般機密到最高機密等不同範圍的資訊。更進一步,橘皮書將一個電腦系統可接受的信任程度加以分級,凡符合某些安全條件、基準、規則的系統即可歸類為某種安全等級。橘皮書將電腦系統的安全效能由高而低劃分為a、b、c、d四大等級,特別是較高等級的安全範圍涵蓋較低等級的安全範圍,而每個大等級又以安全性高低依次編號細分成數個小等級,其中: d——最低保護(minimal protection),凡沒有通過其他安全等級測試專案的系統即屬於該級,如ibm-pc、apple macintosh等個人電腦的系統雖未經安全性測試,但如果有,很可能屬於此級。 c——自定式保護(discretionary protection),該等級的安全特點在於系統的對象(如檔案、目錄)可由西的主題(如系統管理員、擁護、應用程式)自訂訪問權。例如管理員可以決定某個檔案僅允許一特定使用者讀取、另一使用者寫入。張三可以決定他的某個目錄可公開給其他使用者讀、寫等等。在unix、windows nt等作業系統都可以見到這種屬性。該等級又依安全低、高分為c1、c2兩個安全等級。 b——強制式保護(mandatory protection),該等級的安全特點在於由系統強制的安全保護,在強制式保護模式中,每個系統對象(如檔案、目錄等資源)及主題(如系統管理員、使用者、應用程式)都有自己的安全性標籤(security label),系統即依據使用者的安全等級賦予他對各對象的存取權限。 a——可驗證之保護(verified protection),雖然橘皮書仍可能定義比a1高的安全等級,但目前此級僅有a1等級,a等級的功能基本上與b3的相同,而其特點在於a等級的系統擁有正式的分析及數學式方法可完全證明該系統的安全性原則及安全規格的完整性與一致性。windows nt 3.51+號稱具有c2安全等級,但windows nt 4.0及以上版本目前具有c2安全等級是毫無疑問的。換句話說,它的安全特性就是在於自定式保護(discretionary protection),nt未來可能提高到b2安全等級。 以下內容均針對Windows
- 安全性描述元:內含安全資訊。
- 安全性實體:一個有安全性描述元的對象。在很多Windows API中都傳遞安全性實體,例如CreateFile
- 存取控制模型:一個可以控制進程去訪問安全性實體的模型。
- 訪問tokens:一個登陸使用者的安全資訊。
- 存取權限和存取遮罩:存取遮罩是一組32位的資訊,其中每一位都定義了一種存取權限。
- Trustee:ACE應用的對象,可以是一個使用者帳戶,群組帳戶或者是登陸Session。
- ACE:Access Control Entry。可以包含一個SID,存取遮罩,ACE類型,一些標識位。有三種類型的ACE:用於DACL的禁止訪問ACE和允許訪問ACE,使用者SACE的系統監察ACE
- ACL:ACE的列表。有兩類ACL:DACL和SACL
- DACL:是否允許訪問某個安全性實體的ACL列表
- SACL:是否需要記錄使用者訪問的ACL列表
建立一個安全性實體的過程中有關安全性描述元的部分:將建立是使用者定義的安全性描述元號賦值給新的對象,或者使用預設的安全性描述元。應用在訪問時獲得這個安全性實體,並加以分析,以確定自己是否有許可權訪問。 檢查DACL的過程:分析其中的每一個ACL並累積結果,最終許可權將應用於訪問。NULL DACL:如果一個安全性描述元被設定為NULL,那麼將預設獲得所有許可權Empty DACL:如果一個DACL是空的,那麼預設將沒有任何許可權 更改一個DACL的過程:
- 獲得一個安全性實體的DACL。調用GetNamedSecurityInfo函數;
- 建立一個Explicit_Accsse,簡稱ea;
- 將這個ea作為ACE和原來的ACL的內容設定進入一個新的DACL;
- 重新將這個ACL設定給安全性實體。
樣本函數: intSetAccess(LPSTR FileName){ BOOL bSuccess = FALSE; // assume failure DWORD dwError; ExistingDacl = NULL; NewAcl = NULL; psd = NULL; printf("Operations on %s ... ",FileName); // get current Dacl on specified file if (Maintian==1) { dwError = GetNamedSecurityInfo( FileName, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &ExistingDacl, NULL, &psd ); if(dwError != ERROR_SUCCESS) { DisplayLastError("GetNamedSecurityInfo"); return RTN_ERROR; } } BuildExplicitAccessWithName( &ea, TrusteeName, AccessMask, option, InheritFlag // CONTAINER_INHERIT_ACE INHERIT_ONLY_ACE NO_PROPAGATE_INHERIT_ACE // OBJECT_INHERIT_ACE SUB_CONTAINERS_AND_OBJECTS_INHERIT // SUB_CONTAINERS_ONLY_INHERIT SUB_OBJECTS_ONLY_INHERIT ); // NO_INHERITANCE // add specified access to the object dwError = SetEntriesInAcl( 1, &ea, ExistingDacl, &NewAcl ); if(dwError != ERROR_SUCCESS) { DisplayLastError("SetEntriesInAcl"); goto cleanup; } // apply new security to file dwError = SetNamedSecurityInfo( FileName, SE_FILE_OBJECT, // object type DACL_SECURITY_INFORMATION, NULL, NULL, NewAcl, NULL ); if(dwError != ERROR_SUCCESS) { DisplayLastError("SetNamedSecurityInfo"); goto cleanup; } bSuccess = TRUE; // indicate success printf("successful/n",FileName); cleanup: if( NewAcl != NULL ) AccFree( NewAcl ); if( psd != NULL) AccFree( psd ); if( ExistingDacl!= NULL) AccFree(ExistingDacl); if(!bSuccess) return RTN_ERROR; return RTN_OK;}