Windows Management Instrumentation WMI Security Technology Learning

Andrew.Hann發表於2014-10-14

目錄

0. 引言
1. WMI(Windows Management Instrumentation)簡介
2. 基於WMI的攻擊向量
3. WMI程式設計示例

 

0. 引言

在進行伺服器主機的入侵檢測、安全攻防的研究中,常常會涉及到大量的和windows作業系統功能、資源、裝置相關的操作(例如通過WMI COM API關閉FTP匿名登入等),而WMI提供了一個對windows作業系統底層各種異構模組/資源的統一介面,通過研究WMI(Windows Management Instruction)技術可以更加深入地瞭解如果通過API方式操作windows系統的基礎服務,通過WMI技術,我們可以實現

1. windows作業系統的配置加固
2. 當前系統的安裝程式的列表探測,確定系統安裝的反病毒軟體

0x1: COM Component(COM元件)技術

因為WMI是架構在COM技術之上的,在開始學習WMI技術之前,我們先來學習一下windows中的COM Component元件技術

元件物件模型(Component Object Model COM),是微軟的一套軟體元件的二進位制介面標準。這使得跨程式語言的程式間通訊、動態物件建立成為可能。COM是多項微軟技術與框架的基礎,包括

1. OLE
2. OLE自動化
3. ActiveX
4. COM+
5. DCOM
6. Windows shell
7. DirectX
8. Windows Runtime
9. WMI
..

什麼是COM元件

1. COM元件是以WIN32動態連結庫(DLL)、或可執行檔案(EXE)形式釋出的可執行程式碼組成,但要注意的是,COM元件不是DLL,只是利用DLL來給元件提供動態連結的能力
2. COM元件是遵循COM規範編寫的
3. COM元件是一些小的二進位制可執行檔案
4. COM元件可以給應用程式、作業系統以及其他元件提供服務
5. 自定義的COM元件可以在執行時刻同其他元件連線起來構成某個應用程式
6. COM元件可以動態的插入或卸出應用
7. COM元件必須是動態連結的
8. COM元件必須隱藏(封裝)其內部實現細節
9. COM元件必須將其實現的語言隱藏
10. COM元件必須以二進位制的形式釋出
11. COM元件必須可以在不妨礙已有使用者的情況下被升級
12. COM元件可以透明的在網路上被重新分配位置
13. COM元件按照一種標準的方式來宣佈它們的存在

Relevant Link:

http://freebird.blog.51cto.com/372076/184567/
http://zh.wikipedia.org/wiki/%E7%BB%84%E4%BB%B6%E5%AF%B9%E8%B1%A1%E6%A8%A1%E5%9E%8B
http://baike.baidu.com/view/185316.htm
http://www.cppblog.com/3522021224/archive/2007/06/22/26803.html

 

1. WMI(Windows Management Instrumentation)簡介

Windows Management Instrumentation是用於提供共同的介面和物件模式以便訪問

1. 作業系統
2. 裝置
3. 應用程式
4. 服務的管理資訊

如果此服務被終止,多數基於 Windows 的軟體將無法正常執行。如果此服務被禁用,任何依賴它的服務將無法啟動,WMI是windows中的一個核心服務,它提供了一個標準的基礎結構來監視和管理系統資源的服務

WMI是Microsoft實現的一個Web-Based Enterprise Management(WBEM)的執行方式,支援Distributed Management Task Force(DMTF),WMI提供您管理服務的能力

通過這張架構圖,我們得到如下結論

1. WMI Providers And Managemed Object
這是整個WMI體系的最底層,它對所有的"提供者(Provider)"提供了封裝和抽象,包括
    1.1 Native C/C++ Provider COM object 
    A WMI provider is a COM object that monitors one or more "managed objects" for WMI. A "managed object" is a logical or physical enterprise component, such as a hard disk drive,
network adapter, database system, operating system, process, or service.
1) SNMP WMI Provider: SNMP Managed Entity 2) Cimv2 WMI Provider: Windows(Win32) Managed Entity 3) Security Provider: Retrieves or changes security settings that control ownership, auditing, and access rights to files, directories, and shares .... 4) Any Managed Entity(Native Code) Similar to a driver, a provider supplies WMI with data from a managed object and handles messages from WMI to the managed object. WMI providers consist of a DLL file and a
Managed Object Format (MOF) file that defines the classes for which the provider returns data and performs operations. Providers, like WMI C++ applications, use the COM API for
WMI.
1.2 .NET C#、VB.NET、And so on COM Inter-Op 1) .NET Managed Application/Entity 2. WMI Infrastructure The WMI infrastructure is a Microsoft Windows operating system component 2.1 WMI Core(CIM Object Managedr) 2.2 WMI Repository WMI repository is organized by WMI namespaces,WMI的namespace由系統自身建立和Provider建立2部分組成,例如 1) root\default 2) root\cimv2 3) root\subscription ... 由底層的Provider建立的namespace 4) /LM/MSFTPSVC/n .. The WMI service acts as an intermediary between the providers, management applications, and the WMI repository. Only static data about objects is stored in the repository,
such as the classes defined by providers. WMI obtains most data dynamically from the provider when a client requests it. You also can set up subscriptions to receive event
notifications from a provider 簡單來說,WMI Repository就相當於一個儲存WMI資訊的資料庫,而底層的Provider所提供的資訊就相當於一個個獨立的資料表,在WMI中稱之為名稱空間namespace,我們在進行WMI查詢之前,需要明確指定需要查詢的namespace 3. WMI Consumers(Management Applications) A WMI consumer is a management application or script that interacts with the WMI infrastructure. A management application can query, enumerate data, run provider methods, or
subscribe to events by calling either the "COM API" for WMI or the Scripting API for WMI. The only data or actions available for a managed object, such as a disk drive or a
service, are those that a provider supplies. 這一層是程式設計師能直接接觸到的API層面的東西,我們可以使用C
++、WMI Script指令碼編寫程式碼去操作WMI COM API對WMI進行操作 3.1 C/C++ Client 3.2 Scripts 3.3 .NET Client Application
關於WMI COM API介面的相關資訊,請參閱
http://msdn.microsoft.com/en-us/library/aa389276(v=vs.85).aspx

關於Scripting API for WMI介面的相關資訊,請參閱(Scripting API For WMI本質上還是呼叫的COM API)
http://msdn.microsoft.com/en-us/library/aa393258(v=vs.85).aspx

0x1: WMI的功能

1. Windows管理規範(Windows Management Instrumentation)是一項核心的 Windows 管理技術
2. 使用者可以使用 WMI 管理本地和遠端計算機
3. WMI 通過程式設計和指令碼語言為日常管理提供了一條連續一致的途徑。例如,使用者可以:
    1) 在遠端計算機器上啟動一個程式 
    2) 設定一個在特定日期和時間執行的程式 
    3) 遠端啟動計算機。
    4) 獲得本地或遠端計算機的已安裝程式列表。
    5) 查詢本地或遠端計算機的 Windows 事件日誌 

在使用WMI的時候,我們經常會涉及到的2個話題就是名稱空間namespace、以及COM API介面

0x2: WMI的命令空間namespace

strComputer = "."
Call EnumNameSpaces("root")

Sub EnumNameSpaces(strNameSpace)
    WScript.Echo strNameSpace 
    Set objWMIService = GetObject("winmgmts:\\" & strComputer & _
        "\" & strNameSpace)
    Set colNameSpaces = objWMIService.InstancesOf("__NAMESPACE")
    For Each objNameSpace In colNameSpaces
        Call EnumNameSpaces(strNameSpace & "\" & objNameSpace.Name)
    Next
End Sub

在命令列下輸入指令

//如果不加CScript,就會以彈框的形式進行輸出
CScript enumwmi.vbs

得到命令空間的列舉結果

Microsoft (R) Windows Script Host Version 5.8
版權所有(C) Microsoft Corporation 1996-2001。保留所有權利。

root
root\subscription
root\subscription\ms_804
root\subscription\ms_409
root\DEFAULT
root\DEFAULT\ms_804
root\DEFAULT\ms_409
root\CIMV2
root\CIMV2\Security
root\CIMV2\Security\MicrosoftTpm
root\CIMV2\Security\MicrosoftVolumeEncryption
root\CIMV2\ms_804
root\CIMV2\power
root\CIMV2\power\ms_804
root\CIMV2\power\ms_409
root\CIMV2\ms_409
root\CIMV2\TerminalServices
root\CIMV2\TerminalServices\ms_804
root\CIMV2\TerminalServices\ms_409
root\CIMV2\Applications
root\CIMV2\Applications\WindowsParentalControls
root\CIMV2\Applications\Games
root\CIMV2\Applications\Games\ms_804
root\CIMV2\Applications\Games\ms_409
root\Cli
root\Cli\MS_804
root\Cli\MS_409
root\nap
root\MicrosoftIISv2
root\MicrosoftIISv2\MS_804
root\SECURITY
root\SecurityCenter2
root\RSOP
root\RSOP\User
root\RSOP\User\S_1_5_21_911831770_3020607629_1626131430_1001
root\RSOP\User\S_1_5_21_1831597161_2851159394_2615556374_500
root\RSOP\User\S_1_5_21_1650095739_3452460257_125639005_500
root\RSOP\User\S_1_5_21_3111613574_2524581245_2586426736_500
root\RSOP\User\S_1_5_21_3727386885_3056668215_3391246470_197649
root\RSOP\User\S_1_5_21_2209633111_3508286175_922290665_500
root\RSOP\User\S_1_5_21_1991281308_1550804765_3468072676_1000
root\RSOP\User\ms_804
root\RSOP\User\S_1_5_21_1991281308_1550804765_3468072676_500
root\RSOP\User\S_1_5_21_911831770_3020607629_1626131430_500
root\RSOP\User\ms_409
root\RSOP\User\S_1_5_21_3952311282_3270686217_2811382985_500
root\RSOP\Computer
root\RSOP\Computer\ms_804
root\RSOP\Computer\ms_409
root\WebAdministration
root\WebAdministration\MS_804
root\WMI
root\WMI\MS_804
root\WMI\ms_409
root\directory
root\directory\LDAP
root\directory\LDAP\ms_804
root\directory\LDAP\ms_409
root\Policy
root\Policy\ms_804
root\Policy\ms_409
root\Interop
root\Interop\ms_804
root\Interop\ms_409
root\ServiceModel
root\SecurityCenter
root\Microsoft
root\Microsoft\SqlServer
root\Microsoft\SqlServer\ServerEvents
root\Microsoft\SqlServer\ServerEvents\SQLEXPRESS
root\Microsoft\SqlServer\ComputerManagement10
root\Microsoft\SqlServer\ComputerManagement10\ms_804
root\Microsoft\HomeNet
root\aspnet

連線到指定的WMI名稱空間namespace之後,就可以藉助相應的COM API對namespace中儲存的資訊進行讀寫了,這裡要特別注意的是

WMI namespace是一個層次樹tree結構,每一層的Class都有自己對應的成員屬性properties,我們在獲取資訊的時候,需要明白自己需要獲取的資訊位於Class Tree的哪一層,這有點類似java中的jar包,每一層都不斷巢狀,同時每一層又都有自己的獨有的東西,不能遞迴包含

http://www.wutils.com/wmi/classes/IIsFtpServerSetting.html

0x3: WMI COM API介面

You can use the WMI Component Object Model (COM) API to write management client applications or create a new WMI provider. The COM API reference provides information for advanced system administrators, as well as developers who are writing client and provider applications.

1. IEnumWbemClassObject    
Enumerator that works with objects of type IWbemClassObject. It is similar to standard COM enumerators, such as IEnumVariant.

2. IMofCompiler    
Implemented by Mofd.dll, this interface provides a COM interface that is used by the MOF compiler and any other applications that compile MOF files.

3. IUnsecuredApartment    
Used to simplify the process of making asynchronous calls from a client process.

4. IWbemBackupRestore    
Backs up and restores the contents of the WMI repository.

5. IWbemCallResult
Used for semisynchronous calls of the IWbemServices interface. When making such calls, the called IWbemServices method returns immediately, along with an IWbemCallResult object.

6. IWbemCausalityAnalysis    
Tracks child requests that are generated from a parent request.

7. IWbemClassObject    
Contains and manipulates both class definitions and class object instances. Developers need not implement this interface; WMI provides its implementation.

8. IWbemConfigureRefresher    
Used by client code to add or remove enumerators, objects, and nested refreshers into a refresher.

9. IWbemContext    
Optionally used to communicate additional context information to providers when submitting IWbemServices calls to Windows Management.

10. IWbemDecoupledBasicEventProvider    
Registers decoupled providers with WMI.

11. IWbemDecoupledRegistrar    
Associates decoupled providers with WMI. This interface allows a process-hosted provider to define the interoperability lifetime of the interface and coexist with other providers.

12. IWbemEventConsumerProvider    
Provides the primary interface for an event consumer provider. Through this interface and the FindConsumer method, an event consumer provider can indicate which event consumers should receive a given event.

13. IWbemEventProvider    
Used to initiate communication with an event provider.

14. IWbemEventProviderQuerySink
Optionally implemented by event providers who want to know what kinds of event query filters are currently active to optimize performance.

15. IWbemEventProviderSecurity    
Optionally implemented by event providers who want to restrict consumer access to their event.

16. IWbemEventSink    
Initiates communication with an event provider using a restricted set of queries. This interface extends IWbemObjectSink, providing new methods dealing with security and performance.

17. IWbemHiPerfProvider    
Enables providers to supply refreshable objects and enumerators.

18. IWbemHiPerfEnum    
Used in refresher operations to provide rapid access to enumerations of instance objects.

19. IWbemLocator
Obtains the initial namespace pointer to the IWbemServices interface for WMI on a specific host computer.

20. IWbemObjectAccess    
Provides access to the methods and properties of an object. An IWbemObjectAccess object is a container for an instance updated by a refresher.

21. IWbemObjectSink    
Used to receive both the results of IWbemServices and certain types of event notifications.

22. IWbemObjectTextSrc    
Used to translate IWbemClassObject instances to and from differing text formats.

23. IWbemPropertyProvider
Supports retrieving and updating individual properties in an instance of a WMI class.

24. IWbemProviderIdentity    
Implemented by an event provider if the provider registers itself using more than one Name (multiple instances of __Win32Provider) with the same CLSID value. The class provides a mechanism for distinguishing which named provider should be used.

25. IWbemProviderInit    
Used to initialize providers.

26. IWbemProviderInitSink
Implemented by WMI and called by providers to report initialization status.

27. IWbemQualifierSet    
Acts as a container for the entire set of named qualifiers for a single property or entire object (a class or instance).

28. IWbemQuery    
Provides an entry point through which a WMI Query Language (WQL) query can be parsed.

29. IWbemRefresher    
Provides an entry point through which refreshable objects such as enumerators or refresher objects, can be refreshed.

30. IWbemServices    
Used by clients and providers to access WMI services. The interface is implemented only by WMI and is the primary WMI interface.

31. IWbemStatusCodeText    
Extracts text string descriptions of error codes or the name of the subsystem where the error occurred.

32. IWbemUnboundObjectSink    
Implemented by all logical event consumers. It is a simple sink interface that accepts delivery of event objects.

Relevant Link:

http://blog.csdn.net/wzsy/article/details/1632792
http://msdn.microsoft.com/zh-cn/library/aa394553(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/aa394570(v=vs.85).aspx
http://msdn.microsoft.com/zh-cn/library/aa393964(v=vs.85).aspx
http://msdn.microsoft.com/zh-cn/library/aa394582(v=vs.85).aspx
http://blog.itpub.net/7868752/viewspace-1056801/

 

2. 基於WMI的攻擊向量

WMI(Windows管理規範)作為一項Windows管理技術,方便使用者對計算機進行遠端管理。但是它的易用性也導致了系統的安全性大幅下降。讓使用者的電腦除了自己賬號密碼的保護外再沒有什麼安全保護措施

我們接下來一起學習一下黑客是如何通過WMI技術對作業系統進行攻擊的

0x1: 漏洞風險的起因

從WMI本質的功能看,它是為了讓計算機的管理更容易,同時方便管理員遠端作業系統而產生的,一般情況下,在本地計算機上執行的WMI操作也可以在遠端計算機上執行,只要使用者擁有該計算機的管理員許可權
如果使用者對遠端計算機擁有許可權並且遠端計算機支援遠端訪問,那麼使用者就可以連線到該遠端計算機並執行擁有相應許可權的操作

因此,WMI能夠成為遠端控制下的一個"合法通道",有了這個通道,入侵者不需要對自己進行偽裝,不必再為探測出對方賬號的密碼為空後,找不到連線對方系統的通道而發愁。
從安全攻防的角度來看,這就是一個典型的介面安全問題,一個原本是正常提供功能的介面因為沒有進行必要的訪問許可權、使用許可權的控制而導致"介面濫用",從而給了黑客可乘之機

0x2: 黑客可能採用的攻擊方式

前面介紹了WMI的原理,下面我們實際瞭解下,如何通過WMI進行入侵,我們知道WMI是windows作業系統中的一個比較基礎的服務,預設情況下作業系統都會開啟這個服務埠的,即這條"WMI入侵通道"相對來說是比較暢通的,對黑客來說,它所需要的就是通過其他的途徑獲得一個可以登入系統的帳號、密碼

1. 掃描135埠
要尋找可以通過WMI入侵的遠端計算機,只要對135埠進行掃描就可以了。因為WMI服務預設開啟的就是135埠。例如可以採用NTscan掃描工具,因為它不但可以對IPC$、SMB、WMI這些資訊進行掃描,同時還可以對掃描到的遠端賬戶
進行弱口令猜測,功能相對來說比較強大。
2. 執行NTscan,在程式視窗的"配置"區域中進行設定。首先在"起始IP""結束"選項中輸入掃描的IP地址範圍,接著選擇"WMI掃描"選項,並且在"掃描開啟埠的主機"選項後輸入"135",最後點選"開始"按鈕就開始進行掃描 3. 開啟終端服務 找到可以入侵的遠端計算機以後,就可以開始入侵操作了。首先是開啟終端服務(Terminal Service) 要注意的是,通過WMI通道執行系統指令需要我們提供一對可能登入系統的帳號密碼(這是這種攻擊姿勢的關鍵)

0x3: 如何防禦WMI入侵

我們知道,攻防是一種針鋒相對的技術,通過研究黑客在攻擊時所採用的攻擊向量的關鍵點,在這個關鍵點上進行過濾、或者阻斷從而達到防禦的目的

1. 屏閉135埠防禦入侵
從WMI入侵的過程中我們可以看出,整個過程中使用的埠都是135。所以為了防止別人通過WMI進行入侵,我們可以使用防火牆對135埠進行遮蔽,這樣就可以達到防範類似的入侵。使用者加強自己的賬號密碼強度,也可以有效防範入侵

2. 加強帳號安全管理
從本質上講,WMI是一個正常的功能通道,WMI本身並不是漏洞,產生漏洞的是系統帳號的洩漏,導致黑客濫用這個通道進行高危指令的執行,所以,我們可以從問題的源頭入手,部署高強度密碼策略,定期更換密碼等措施解決問題

Relevant Link:

http://blog.itpub.net/7868752/viewspace-1056801/

 

3. WMI程式設計示例

操作WMI的方式有以下幾種方式

1. Scripts written in Microsoft ActiveX script hosting, including Visual Basic Scripting Edition (VBScript) and Perl
2. Windows PowerShell
3. Visual Basic applications
4. Active Server Pages
5. C++ applications
6. .NET Framework applications written in C#, Visual Basic .NET, or J#

不論採用哪種方式,對WMI的操作都必須完成以下幾個基本步驟

1. Obtaining Data from WMI:從WMI獲取資料
    1) Decide which language to use
    2) Ensure that your connections to remote computers work
    3) Connecting to WMI on remote computers requires the correct security settings
    4) After connecting to WMI, you can obtain data through queries and enumerations.
    5) Registry data is available through WMI and you can create new keys and values or modify existing ones
    6) You can subscribe to event notifications through WMI, either temporarily between system reboots or permanently.
    7) Performance counter data for a system is available through WMI.

2. Providing Data to WMI
Decide on the type of provider to write. you can take several other approaches to writing a WMI COM provider:
    1) Using the WMI ATL Wizard in Visual Studio.
    2) Using COM directly in any integrated development environment.
    3) Using WMI in the .NET Framework to create a managed code provider.
    4) Using the provider framework classes is not recommended.

3. Important Tasks for WMI
    1) WMI Tasks for Scripts and Applications
    2) Creating a WMI Application or Script
    3) Connecting to WMI on a Remote Computer
    4) Connecting to WMI on a Remote Computer by Using Windows PowerShell
    5) Monitoring Events
    6) Providing Data to WMI
    7) Getting and Providing Data on a 64-bit Computer

這裡我們以最常用的C++、VBS Scripts方式進行程式設計學習

0x1: C++ applications

// wmi_getsysinfo.cpp : 定義控制檯應用程式的入口點。
//

#include "stdafx.h"

#include <iostream>
#include <comdef.h>
#include <Wbemidl.h>

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

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    HRESULT hres;

    /*
    Initialize COM.
    由於用C++編寫WMI應用是基於COM技術的,所以必須初始化COM庫 
    */
    hres =  CoInitializeEx(0, COINIT_MULTITHREADED); 
    if (FAILED(hres))
    {
        cout << "Failed to initialize COM library. " 
            << "Error code = 0x" 
            << hex << hres << endl;
        return 1;              // Program has failed.
    }

    /*
    Initialize
    初始化COM庫安全級別
    */
    hres =  CoInitializeSecurity(
        NULL,     
        -1,      // COM negotiates service                  
        NULL,    // Authentication services
        NULL,    // Reserved
        RPC_C_AUTHN_LEVEL_DEFAULT,    // authentication
        RPC_C_IMP_LEVEL_IMPERSONATE,  // Impersonation
        NULL,             // Authentication info 
        EOAC_NONE,        // Additional capabilities
        NULL              // Reserved
        );
    if (FAILED(hres))
    {
        cout << "Failed to initialize security. " 
            << "Error code = 0x" 
            << hex << hres << endl;
        CoUninitialize();
        return 1;          // Program has failed.
    }

    // Obtain the initial locator to Windows Management
    // on a particular host computer.
    IWbemLocator *pLoc = 0;
    /*
    連線到WMI名稱空間
    通過呼叫CoCreateInstance初始化WMI的定位器(IWbemLocator型別的例項)
    */
    hres = CoCreateInstance(
        CLSID_WbemLocator,             
        0, 
        CLSCTX_INPROC_SERVER, 
        IID_IWbemLocator, (LPVOID *) &pLoc);
    if (FAILED(hres))
    {
        cout << "Failed to create IWbemLocator object. "
            << "Error code = 0x"
            << hex << hres << endl;
        CoUninitialize();
        return 1;       // Program has failed.
    }

    IWbemServices *pSvc = 0;

    // Connect to the root\cimv2 namespace with the
    // current user and obtain pointer pSvc
    // to make IWbemServices calls.
    /*
    呼叫IWbemLocator::ConnectServer方法,通過這個定位器連線到WMI的名稱空間,通過把一個IWbemServices的例項以引數形式傳遞給ConnectServer方法,就會建立這個服務。如我們需要一些BIOS資訊,那麼需要使用的WMI提供程式是Win32_BIOS,則需要連線到ROOT//CIMV2名稱空間中。
    */
    hres = pLoc->ConnectServer(
        _bstr_t(L"ROOT\\CIMV2"), // WMI namespace
        NULL,                    // User name
        NULL,                    // User password
        0,                       // Locale
        NULL,                    // Security flags                 
        0,                       // Authority       
        0,                       // Context object
        &pSvc                    // IWbemServices proxy
        );                            
    if (FAILED(hres))
    {
        cout << "Could not connect. Error code = 0x" 
            << hex << hres << endl;
        pLoc->Release();     
        CoUninitialize();
        return 1;                // Program has failed.
    }

    cout << "Connected to ROOT\\CIMV2 WMI namespace" << endl;

    // Set the IWbemServices proxy so that impersonation
    // of the user (client) occurs.
    /*
    設定WMI服務的安全級別
    根據上一步得到的服務,設定相應的服務安全級別。通常來說,如果我們沒有設定適當的安全屬性,COM安全方案不允許一個程式去訪問另一個程式,因此如果我們要訪問一個外部程式的物件,那麼我們應該設定適當的IWbemServices的安全級別。
    */
    hres = CoSetProxyBlanket(

        pSvc,                         // the proxy to set
        RPC_C_AUTHN_WINNT,            // authentication service
        RPC_C_AUTHZ_NONE,             // authorization service
        NULL,                         // Server principal name
        RPC_C_AUTHN_LEVEL_CALL,       // authentication level
        RPC_C_IMP_LEVEL_IMPERSONATE,  // impersonation level
        NULL,                         // client identity 
        EOAC_NONE                     // proxy capabilities     
        );
    if (FAILED(hres))
    {
        cout << "Could not set proxy blanket. Error code = 0x" 
            << hex << hres << endl;
        pSvc->Release();
        pLoc->Release();     
        CoUninitialize();
        return 1;               // Program has failed.
    }

    //通過WQL使用WMI服務
    IEnumWbemClassObject* pEnumerator = NULL;
    hres = pSvc->ExecQuery(
        bstr_t("WQL"), 
        bstr_t("SELECT * FROM Win32_OperatingSystem"),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
        NULL,
        &pEnumerator);

    if (FAILED(hres))
    {
        cout << "Query for processes failed. "
            << "Error code = 0x" 
            << hex << hres << endl;
        pSvc->Release();
        pLoc->Release();     
        CoUninitialize();
        return 1;               // Program has failed.
    }
    else
    { 
        IWbemClassObject *pclsObj;
        ULONG uReturn = 0;

        while (pEnumerator)
        {
            hres = pEnumerator->Next(WBEM_INFINITE, 1, 
                &pclsObj, &uReturn);

            if(0 == uReturn)
            {
                break;
            }

            VARIANT vtProp;

            // Get the value of the Name property
            hres = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);
            wcout << "Manufacturer Name : " << vtProp.bstrVal << endl;
            VariantClear(&vtProp);
        }

    }

    // Cleanup
    // ========

    pSvc->Release();
    pLoc->Release();     
    CoUninitialize(); 

    return 0;
}

0x2: Scripts written in Microsoft ActiveX script hosting

' Check command line parameters
Select Case WScript.Arguments.Count
    Case 0
        ' Default if none specified is local computer (".")
        Set objWMIService = GetObject( "winmgmts://./root/cimv2" )
        Set colItems = objWMIService.ExecQuery( "Select * from Win32_ComputerSystem", , 48 )
        For Each objItem in colItems
            strComputer = objItem.Name
        Next
    Case 1
        ' Command line parameter can either be a computer name
        ' or "/?" to request online help
        strComputer = Wscript.Arguments(0)
        if InStr( strComputer, "?" ) > 0 Then Syntax
    Case Else
        ' Maximum is 1 command line parameter
        Syntax
End Select

On Error Resume Next
' Connect to computer's WMI service
Set objWMIService = GetObject( "winmgmts://" & strComputer & "/root/cimv2" )
' Display error number and description if applicable
If Err.Number Then ShowError()

' Collect BIOS information
Set colItems = objWMIService.ExecQuery( "Select * from Win32_BIOS where PrimaryBIOS = true", , 48 )
' Display error number and description if applicable
If Err.Number Then ShowError()

' Initialize screen output variable
strMsg = vbCrLf & "BIOS summary for " & strComputer & ":" & vbCrLf

' Prepare collected info for display
For Each objItem in colItems
    strMsg = strMsg _
           & "    BIOS Name       :  " & objItem.Name & vbCrLf _
           & "    Version         :  " & objItem.Version & vbCrLf _
           & "    Manufacturer    :  " & objItem.Manufacturer & vbCrLf _
           & "    SMBIOS Version  :  " & objItem.SMBIOSBIOSVersion & vbCrLf
Next

' Display the results
WScript.Echo strMsg

' Done
WScript.Quit(0)


Sub ShowError
    strMsg = vbCrLf & "Error # " & Err.Number & vbCrLf & _
             Err.Description & vbCrLf & vbCrLf
    Syntax
End Sub


Sub Syntax
    strMsg = strMsg & vbCrLf & "BIOS.vbs,  Version 1.00" & vbCrLf & _
             "Display BIOS information." & vbCrLf & vbCrLf & _
             "Usage:  CSCRIPT  BIOS.VBS  [ computer_name ]" & _
             vbCrLf & vbCrLf & _
             "Where:  " & Chr(34) & "computer_name" & Chr(34) & _
             " is the name of a WMI enabled computer on the network" & _
             vbCrLf & vbCrLf & _
             "Written by Rob van der Woude" & vbCrLf & _
             "http://www.robvanderwoude.com" & vbCrLf & vbCrLf & _
             "Created using Microsoft's Scriptomatic tool" & vbCrLf & _
             "http://www.microsoft.com/technet/treeview/default.asp?" & _
             "url=/technet/scriptcenter/WMImatic.asp" & vbCrLf
    WScript.Echo strMsg
    ' Abort with return code 1
    WScript.Quit(1)
End Sub

Relevant Link:

http://msdn.microsoft.com/en-us/library/aa390418(v=vs.85).aspx
http://www.robvanderwoude.com/wmiexamples.php
http://www.codeproject.com/Articles/46390/WMI-Query-Language-by-Example

 

Copyright (c) 2014 LittleHann All rights reserved

 

相關文章