首页
社区
课程
招聘
[讨论]为啥下面这个MSDN上的利用WMI执行命令的代码总是提示内存无法读取?
2011-4-20 13:02 3871

[讨论]为啥下面这个MSDN上的利用WMI执行命令的代码总是提示内存无法读取?

2011-4-20 13:02
3871
文章作者:pt007@vip.sina.com
信息来源:邪恶八进制信息安全团队(www.eviloctal.com) 
复制内容到剪贴板 
// wmiexe.cpp : Defines the entry point for the console application.
//去掉此宏定义:setting -> c/C++ -> pre definitions ,加DEPRECATE_SUPPORTED,STRSAFE_NO_DEPRECATE

//#define UNICODE
#define _WIN32_DCOM
#include "stdafx.h"
//#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <comdef.h>
#include <WbemIdl.h>
#include <wincred.h>
#include <strsafe.h>

#include <iostream>

#pragma comment(lib, "wbemuuid.lib")
#pragma comment(lib, "credui.lib")
//#pragma comment(lib, "comsuppw.lib")

using namespace std;


int main(int argc, char* argv[])
{
        if(argc != 5)
        
        {
                printf("Usage: %s [ntlmdomain] [user] [password] [cmd]", argv[0]);
        printf("\n\n");
                return 0;
        }

        HRESULT hres;
        hres = CoInitializeEx(0, COINIT_MULTITHREADED);
        if(FAILED(hres))
        {
                printf("Failed to initialize COM library. Error code = 0x%X\n", hres);
                return 1;
        }
        else
                printf("Success to initialize COM library.\n");

        hres = CoInitializeSecurity(NULL,
                -1, // COM authentication
                NULL, // Authentication services
                NULL, // Reserved
                RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication
                RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation
                NULL, // Authentication info
                EOAC_NONE, // Additional capabilities
                NULL); // Reserved
        if(FAILED(hres))
        {
                printf("Failed to initialize security. Error code = 0x%X\n", hres);
                CoUninitialize();
                return 1;
        }
        else
                printf("Success to initialize security.\n");

        IWbemLocator *pLoc = NULL;
        hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *)&pLoc);
        if(FAILED(hres))
        {
                printf("Failed to create IWbemLocator object. Err code = 0x%X\n", hres);
                CoUninitialize();
                return 1;
        }
        else
                printf("Success to create IWbemLocator object.\n");





/*        hres = pLoc->ConnectServer(
        _bstr_t("\\\\xp-01\\root\\cimv2"),
        _bstr_t("Administrator"), // User name
        _bstr_t("123654abc!@#"), // User password
        _bstr_t("MS_409"), // Locale
        NULL, // Security flags
        _bstr_t("ntlmdomain:Boll"), // Authority
        0, // Context object
        &pSvc); // IWbemServices proxy*/
        IWbemServices *pSvc = NULL;
        char Domain[256]="0";
        char User[256]="0";
        char Pass[256]="0";
        char *CMD=NULL;
        memset(Domain,0,256);
    memset(User,0,256);
        memset(Pass,0,256);
        //memset(CMD,0,512);
        wsprintf(Domain,"ntlmdomain:%s", argv[1]);
    //lstrcpy(Domain,"ntlmdomain:");
        //lstrcat(Domain,argv[1]);
    lstrcpy(User,argv[2]);
        lstrcpy(Pass,argv[3]);
        
        printf("Domain=%s,User=%s,Pass=%s\n",Domain,User,Pass);

        /*BOOL fSave; //图形密码输入提示
        CREDUI_INFO cui;
        bool useToken = false;
        DWORD dwErr;

        memset(&cui,0,sizeof(CREDUI_INFO));
        cui.cbSize = sizeof(CREDUI_INFO);
        cui.hwndParent = NULL;
        // Ensure that MessageText and CaptionText identify
        // what credentials to use and which application requires them.
        cui.pszMessageText = TEXT("Press cancel to use process token");
        cui.pszCaptionText = TEXT("Enter Account Information");
        cui.hbmBanner = NULL;
        fSave = FALSE;

        dwErr = CredUIPromptForCredentials( 
                &cui,                             // CREDUI_INFO structure
                TEXT(""),                         // Target for credentials
                NULL,                             // Reserved
                0,                                // Reason
                User,                          // User name
                CREDUI_MAX_USERNAME_LENGTH+1,     // Max number for user name
                Pass,                           // Password
                CREDUI_MAX_PASSWORD_LENGTH+1,     // Max number for password
                &fSave,                           // State of save check box
                CREDUI_FLAGS_GENERIC_CREDENTIALS |// flags
                CREDUI_FLAGS_ALWAYS_SHOW_UI |
                CREDUI_FLAGS_DO_NOT_PERSIST);  

        if(dwErr == ERROR_CANCELLED)
        {
                useToken = true;
        }
        else if (dwErr)
        {
                cout << "Did not get credentials " << dwErr << endl;
                pLoc->Release();     
                CoUninitialize();
                return 1;      
        }*/




        hres = pLoc->ConnectServer(
            _bstr_t("\\\\10.10.11.114\\root\\CIMV2"),
                _bstr_t(User), // User name
                _bstr_t(Pass), // User password
                _bstr_t("MS_409"), // Locale,指定为英语
                0, // Security flags
                NULL,//_bstr_t(Domain), // Authority
                NULL, // Context object
                &pSvc); // IWbemServices proxy

        if(FAILED(hres))
        {
                printf("Could not connect. Error code = 0x%X\n", hres);
                pLoc->Release();
                CoUninitialize();
                return 1;
        }
        printf("Connected to ROOT\\CIMV2 WMI namespace\n");

        // Step 5
        // Set security levels on a WMI connection
        hres = CoSetProxyBlanket(
                pSvc, // Indicates the proxy to set
                RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx
                RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx
                NULL, // Server principal name
                RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx
                RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
                NULL, // client identity
                EOAC_NONE); // proxy capabilities

        if(FAILED(hres))
        {
                printf("Could not set proxy blanket. Error code = 0x%X\n", hres);
                pSvc->Release();
                pLoc->Release();  
                CoUninitialize();
                return 1;
        }
        printf("CoSetProxyBlanket successed!\n");

        BSTR MethodName = SysAllocString(L"Create");
        BSTR ClassName  = SysAllocString(L"Win32_Process");
        
        
        IWbemClassObject* pClass = NULL;
        hres = pSvc->GetObject(ClassName, 0, NULL, &pClass, NULL);
        
        IWbemClassObject* pInParamsDefinition = NULL;
        IWbemClassObject*   pOutMethod   =   NULL; 

        hres = pClass->GetMethod(MethodName, 0, &pInParamsDefinition, &pOutMethod); //这里就是导致内存无法读取的代码,可能是传递了空指针

        if (hres==NULL)
        {
                printf("pClass->GetMethod返回值为空!0x%X\n",GetLastError());
        }
        
        //printf("1.CoSetProxyBlanket successed!\n");
        IWbemClassObject* pClassInstance = NULL;
        hres = pInParamsDefinition->SpawnInstance(0, &pClassInstance);
        
        VARIANT varCommand;
        varCommand.vt = VT_BSTR;
        printf("2.CoSetProxyBlanket successed!\n");
        StringCbPrintf(CMD,strlen(CMD),"cmd.exe /c %s >C:\\1.txt", argv[4]);
        DWORD dwNum = MultiByteToWideChar(CP_ACP, 0, CMD, -1, NULL, 0);
        wchar_t *pwCMD;
        pwCMD = new wchar_t[dwNum];
        if(!pwCMD)
        {
                delete []pwCMD;
        }
        MultiByteToWideChar(CP_ACP, 0, CMD, -1, pwCMD, dwNum);
        varCommand.bstrVal = pwCMD;
    //varCommand.bstrVal = L"cmd.exe /c ver >C:\\VER.txt"; /*这个地方设置要执行的命令*/

        
        hres = pClassInstance->Put(L"CommandLine", 0, &varCommand, 0);
        wprintf(L"The command is: %s ", V_BSTR(&varCommand));

        // Execute Method
        IWbemClassObject* pOutParams = NULL;
        hres = pSvc->ExecMethod(ClassName, MethodName, 0, NULL, pClassInstance, &pOutParams, NULL);
        if(FAILED(hres))
        {
                printf("Could not execute method. Error code = 0x%X\n", hres);
                VariantClear(&varCommand);
                SysFreeString(ClassName);
                SysFreeString(MethodName);
                pClass->Release();
                pInParamsDefinition->Release();
                pOutParams->Release();
                pSvc->Release();
                pLoc->Release();
                CoUninitialize();
                return 1;
        }

        // To see what the method returned,
        // use the following code. The return value will be in &varReturnValue
        VARIANT varReturnValue;
        hres = pOutParams->Get(_bstr_t(L"ReturnValue"), 0, &varReturnValue, NULL, 0);

        // Clean up
        //--------------------------
        VariantClear(&varCommand);
        VariantClear(&varReturnValue);
        SysFreeString(ClassName);
        SysFreeString(MethodName);
        pClass->Release();
        pInParamsDefinition->Release();
        pOutParams->Release();
        pLoc->Release();
        pSvc->Release();
        CoUninitialize();

        return 0;
}

[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

收藏
点赞0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回