软件安全之代码注入技术 向目标 PE 文件注入 DLL notepad lpk.dll 远程线程函数 提权函数 OpenProcess VirtualAllocEx

实验 4 代码注入技术

引言

1、实验说明

代码注入是将用户代码注入到其他进程或者可执行文件中,实现拦截目标进程运行过程的关键信息、改变目标进程或可执行文件原本执行流程等目的

2、实验目的

本实验通过远程线程和输入表注入,向目标进程注入代码、向目标 PE 文件注入 DLL,以加深对代码注入技术的理解。

3、实验原理

  • 在目标进程中申请内存并写入待注入DLL的路径,然后调用
    CreateRemoteThread,在目标中创建线程;线程函数地址为LoadLibrary(A/W),线程参数便是存放DLL路径的内存首地址

  • 调用CreateRemoteThread需要目标进程句柄作刀梦数,此N而得到在目标进程中创建线程(PRoCES>CKEAlP_I11nEA)、r '存(PROCESS_VM_WRITE)等多项权限

  • “远程”线程是和CreateThread相对的,匹程纹任疋巧进性主利线程,创建的线程不属于当前进程

  • 使用LoadLibrarv作为线程函数较为方便,因为不考虑返回值和参数类型的情况下,二者有相同的函数原型,如下所示:

    HMODULE WINAPI LoadLibraryA(LPCSTR lpLibFileName);
    DWORD WINAPI ThreadProc(LPVOID lpParameter);
    
  • 远程线程注入过程需要在目标进程空间申请内存,存储线程执行时所需的参数等数据

  • VirtualAllocEx:在指定进程中申请内存空间

  • WriteProcessMemory:向指定进程的指定虚拟内存地址写入数据

//获取目标进程的句柄
HANDLE hProc =OpenProcess(PROCESS_ALL_ACCESS,FALSE, dwTargetPid),
//在目标进程申请空间存储DLL完整路径
LPTSTR pDllFile =(LPTSTR)VirtualAllocEx(hProc, NULL, lstrlen(DllPath)+1,MEM_COMMIT, PAGE_READWRITE);
//将DLL路径写入目标进程申请的内存中
WriteProcessMemory(hProc, pDllFile, DllPath, lstrlen(DllPath)+1, NULL)
//获取LoadLibraryA的入口地址
HMODULE hKernel = GetModuleHandle("Kernel32");
PTHREAD_START_ROUTINE pfnStartAddr = GetProcAddress(hKernel,"LoadLibraryA");
//创建远程线程调用LoadLibrary
CreateRemoteThread(hProc, NULL,0, pfnStartAddr, pDllFile,0, NULL);

区别

原理和远程线程注入DLL原理相似,区别是:

  • 线程执行对象不同:即线程函数不同,注入DLL时创建远程线程执行LoadLibrary(A/W)函数,而注入代码时执行用户实现的这部分代码

  • 目标进程空间存储对象不同:注入DLL时在目标进程中申请的内存空间用于存储DLL路径,而注入代码存储的是作为线程函数的这部分代码,以及线程函数的参数

远程线程注入代码注意事项:

  • 注入代码定位:包括如何确定代码的起始位置和代码的长度,这决定
    了向目标进程写入什么内容、写入多少字节
  • 注入代码实现:注入代码是要在目标进程中执行,因此创建该代码主体中的全局变量、堆内存、本地自定义函数等均无法使用,使用系统API则不受限制

4、实验环境

Windows 7 系统、Visual Studio 6.0 及以上版本
关于Windows 7 的选择,建议大家使用 带Service Pack1的X86系统,镜像下载网站.这样能够在使用WM ware时安装WMtools,实现内容文件的直接复制,方便快捷,是32位系统。
迅雷下载号:

ed2k://|file|hk_windows_7_home_premium_with_sp1_x86_dvd_620848.iso|2621298688|33CB0040A929656DC1BE176E3FF8F00E|/

在这里插入图片描述

5、实验内容

(1)远程线程注入

(2)利用 Detours 实现输入表注入

(3)DLL 劫持

远程线程注入

1创建 Win32 应用程序项目

打开 VS,选择空项目模板,创建 Win32 应用程序,然后向新建项目中添加源程序文件 InjectCode.cpp(附件已提供)。

源代码

#include <windows.h>
#include <stdio.h>

typedef struct _THREAD_PARAM
{
	FARPROC pFunc[2];		// LoadLibraryA(), GetProcAddress()
	char szBuf[4][128];		// "user32.dll", "MessageBoxA",  "text", "caption"
} THREAD_PARAM,  PTHREAD_PARAM;

typedef HMODULE(WINAPI pfnLoadLibrary)(LPCSTR lpLibFileName);
typedef xx(WINAPI pfnGetProcAddress)(xx, xx);
typedef xx (WINAPI pfnMsgBox)(xx, xx, xx, xx);

BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)
{
	HANDLE hToken;
	if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
	{
		printf("OpenProcessToken error:%d\n", GetLastError());
		return FALSE;
	}

	LUID luid;
	if (!LookupPrivilegeValue(NULL,	lpszPrivilege,	&luid))
	{
		printf("LookupPrivilegeValue error:%d\n", GetLastError());
		return FALSE;
	}

	TOKEN_PRIVILEGES NewState;
	NewState.PrivilegeCount = 1;
	NewState.Privileges[0].Luid = luid;
	if (bEnablePrivilege)
		NewState.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
	else
		NewState.Privileges[0].Attributes = 0;

	if (!AdjustTokenPrivileges(hToken, FALSE, &NewState, sizeof(TOKEN_PRIVILEGES), NULL, NULL))
	{
		printf("AdjustTokenPrivileges error:%d\n", GetLastError());
		return FALSE;
	}
	return TRUE;
}

DWORD WINAPI ThreadProc(LPVOID lParam)
{
	PTHREAD_PARAM pParam = (PTHREAD_PARAM)lParam;
	// "user32.dll"
	HMODULE hMod = ((pfnLoadLibrary)pParam->pFunc[0])(pParam->szBuf[0]);
	if (!hMod)
		return 1;

	// "MessageBoxA"
	pfnMsgBox pFunc = (pfnMsgBox)((pfnGetProcAddress)pParam->pFunc[1])(hMod, pParam->szBuf[1]);
	if (!pFunc)
		return 1;

	pFunc(NULL, pParam->szBuf[2], pParam->szBuf[3], MB_OK);
	return 0;
}

BOOL InjectCode(DWORD dwPID)
{
	HANDLE hProcess = OpenProcess(xx, xx, xx);
	if (!hProcess)
	{
		pri
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SK Primin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值