Share via


安全地接收事件

暫時和永久取用者有不同的方法來保護事件傳遞。

本主題將討論下列各節:

保護暫時取用者

暫存取用者會在系統重新開機或 WMI 停止之前執行,但如果引發特定事件,則無法啟動。 例如, 呼叫 SWbemServices.ExecNotificationQueryAsync 會建立暫時取用者。

呼叫 SWbemServices.ExecNotificationQueryIWbemServices::ExecNotificationQuery 會建立暫時事件取用者。 暫存取用者無法控制誰將事件提供給他們建立的事件 接收

可以同步、半同步或非同步方式呼叫ExecNotificationQuery方法。 例如, SWbemServices.ExecNotificationQuery 是同步方法,可根據 iflags 參數的設定方式,以半同步方式呼叫。 SWbemServices.ExecNotificationQueryAsync 是非同步呼叫。

請注意,這些呼叫非同步版本的回呼可能不會在與腳本所做的呼叫相同的驗證層級傳回。 因此,建議您使用半同步而非非同步呼叫。 如果您需要非同步通訊,請參閱在非同步呼叫上呼叫方法和設定安全性。

腳本訂閱者無法檢查事件提供者的存取權限,以提供事件給腳本所建立的接收。 因此,建議呼叫 SWbemServices.ExecNotificationQuery 使用呼叫的半同步形式,並使用特定的安全性設定。 如需詳細資訊,請參閱 使用 VBScript 進行半同步呼叫

保護永久取用者

永久取用者擁有事件提供者的永久訂用帳戶,該事件提供者會在作業系統重新開機之後保存。 支援永久取用者的事件提供者是 事件取用者提供者。 如果事件發生時事件提供者未執行,則 WMI 會在需要傳遞事件時啟動提供者。 WMI 會根據取用者提供者所定義的邏輯取用者類別,根據__EventConsumerProviderRegistration實例,識別應傳遞事件的取用者提供者__Win32Provider實例。 如需取用者提供者角色的詳細資訊,請參閱 撰寫事件取用者提供者

永久取用者可以控制傳送事件的人員,而事件提供者可以控制誰存取其事件。

用戶端腳本和應用程式會在訂用帳戶中建立邏輯取用者類別的實例。 邏輯取用者類別會定義事件所包含的資訊、用戶端可以使用事件執行的動作,以及事件傳遞方式。

WMI 標準取用者類別提供 邏輯取用者類別角色的範例。 如需詳細資訊,請參閱 使用標準取用者監視和回應事件

保護永久訂閱

永久訂用帳戶可能會造成 WMI 中的安全性問題,因此具有下列安全性需求:

  • 邏輯取用者實例、 __EventFilter__FilterToConsumerBinding 實例在 CreatorSID 屬性中必須有相同的個別安全識別碼 (SID) 。 如需詳細資訊,請參閱 在永久訂用帳戶的所有實例中保留相同的 SID

  • 建立訂用帳戶的帳戶必須是具有本機系統管理員許可權的網域帳戶或本機 Administrators 群群組帳戶。 使用 Administrators 群組 SID 可讓訂用帳戶繼續在本機電腦上運作,即使它與網路中斷連線也一樣。 使用網域帳戶可確切識別使用者。

    不過,如果電腦未連線且建立帳戶是網域帳戶,取用者會失敗,因為 WMI 無法驗證帳戶的身分識別。 若要避免電腦與網路中斷連線,請針對訂用帳戶使用 Administrators 群組 SID。 在此情況下,您應該確定 LocalSystem 帳戶可以存取網域上的群組成員資格資料。 某些事件取用者提供者有特別高的安全性需求,因為 Rogue 訂用帳戶可能會造成重大損害。 範例包括標準取用者、 ActiveScriptEventConsumerCommandLineEventConsumer

  • 您可以將永久訂用帳戶設定為只接受來自特定事件提供者身分識別的事件。 將__EventFilter實例之EventAccess屬性中的安全性描述項設定為事件提供者識別。 WMI 會將事件提供者的身分識別與安全性描述項進行比較,以判斷提供者是否具有 WBEM_RIGHT_PUBLISH 存取權。 如需詳細資訊,請參閱 WMI 安全性常數

    如果篩選準則允許存取事件提供者身分識別,它也會信任事件。 這可讓接收事件的取用者引發委派的事件。

    注意EventAccess中安全性描述項的預設值為Null,可允許所有人存取。 建議限制 __EventFilter 訂用帳戶實例中的存取權,以取得更好的事件安全性。

設定Administrator-Only SD

下列 C++ 程式碼範例會在 __EventFilter 實例上建立僅限系統管理員的安全性描述項。 此範例會使用 安全性描述元定義語言 (SDDL) 來建立安全性描述元。 如需 WBEM_RIGHT_SUBSCRIBE的詳細資訊,請參閱 WMI 安全性常數

// Create SD that allows only administrators 
//    to send events to this filter. 
// The SDDL settings are O:BAG:BAD:(A;;0x80;;;BA)
// Set the EventAccess property in the 
//    IWbemClassObject of the __EventFilter instance. 
   long lMask = WBEM_RIGHT_PUBLISH;
     WCHAR wBuf[MAX_PATH];
     _ltow( lMask, wBuf, 16 );
 
HRESULT hRes = pEventFilterInstance->Put( L"EventAccess", 0,
    &_variant_t( L"O:BAG:BAD:(A;;0x80;;;BA)" ), NULL );

上述程式碼範例需要下列參考和 #include 語句。

#define _WIN32_DCOM
#include <wbemidl.h>
#include <comdef.h>

#pragma comment(lib, "wbemuuid.lib")

模擬事件提供者識別

永久取用者可能需要模擬事件提供者來處理事件。 永久取用者只能在下列條件存在時模擬事件提供者:

  • __FilterToConsumerBinding的實例已將MaintainSecurityCoNtext屬性設定為True
  • 事件會在提供者產生事件時所在的相同安全性內容中傳遞。 只有實作為 DLL 的取用者,即同進程取用者,才能在提供者的安全性內容中接收事件。 如需進程提供者和取用者安全性的詳細資訊,請參閱 提供者裝載和安全性
  • 事件提供者正在允許模擬的進程中執行。

執行取用者進程的帳戶必須具有 WMI 存放庫的FULL_WRITE存取權 , (也稱為 CIM 存放庫) 。 在訂用 帳戶中,__FilterToConsumerBinding、 __EventConsumer__EventFilter 實例在 CreatorSID 屬性中必須有相同的個別安全性識別碼 (SID) 值。 WMI 會將 SID 儲存在每個實例的 CreatorSID 中。

SID 和永久訂閱

當系結、取用者和篩選不是由同一位使用者建立時,永久訂閱將無法運作,這表示CreatorSID屬性中的__FilterToConsumerBinding__EventConsumer__EventFilter必須具有相同的個別安全性識別碼 (SID) 值。 Windows Management Instrumentation (WMI) 會儲存此值。

使用網域帳戶建立永久訂閱

使用網域帳戶建立永久訂用帳戶時,必須考慮幾個問題。 當沒有任何使用者登入時,每個永久訂用帳戶仍可運作,這表示它們在內建 LocalSystem 帳戶下運作。

如果網域使用者是安全性敏感性取用者的永久訂用帳戶建立者, (ActiveScriptEventConsumerCommandLineEventConsumer) ,則 WMI 會驗證__EventFilter類別、__FilterToConsumerBinding類別的CreatorSID屬性,以及取用者實例是否屬於屬於本機 Administrators 群組成員的使用者。

下列程式碼範例示範如何指定 CreatorSID 屬性。

 instance of __EventFilter as $FILTER
    {
        // this is the Administrators SID in array of bytes format
        CreatorSID = {1,2,0,0,0,0,0,5,32,0,0,0,32,2,0,0};    
        // Add filter code here ...
    }

    instance of ActiveScriptEventConsumer as $CONSUMER
    {
       CreatorSID = {1,2,0,0,0,0,0,5,32,0,0,0,32,2,0,0};
       // Add consumer code here ...
    }

    instance of __FilterToConsumerBinding
    {
       CreatorSID = {1,2,0,0,0,0,0,5,32,0,0,0,32,2,0,0};
       Consumer = $CONSUMER;
       Filter = $FILTER;
       // Add binding code here ...
    }

針對跨網域的情況,請將已驗證的使用者新增至「Windows 授權存取群組」。

保護 WMI 事件

接收 WMI 事件