基于IAT hook的文件隐藏功能

发布于:2022-12-10 ⋅ 阅读:(530) ⋅ 点赞:(0)

基于 IAT hook 的文件隐藏功能

一 实验目的:实现基于 IAT hook 的文件隐藏功能

二 实验内容:

  1. 分析 explorer.exe 和 cmd.exe 等可以查看文件目录的系统程序遍历文件的实现机制
  2. 通过 IAT Hook 的方法篡改它们的导入表,使这两个程序查看不到文件系统中指定名称的文件。

三 实验过程

1、主程序

(1)功能:将自己编写的包含有攻击代码的 dll 文件注入到目标进程(本实验选择注入到“cmd.exe”)

(2)代码逻辑:

提升本进程权限——> 获取目标进程的 PID——> 获得要注入进程的句柄——> 在远程进程中开辟出一段内存——> 将包含恶意代码的 dll 的名字写入上一步开辟出的内存中——> 在被注入进程中创建新线程加载该 dll——> 卸载注入的 dll

(3)实现细节

① 提升本进程权限

目的:在操作系统进程时,需要提升自己编写的进程到系统权限,以免发生操作失败现象

所用函数:

//获取当前进程句柄
GetCurrentProcess()
//获得进程访问令牌的句柄。第一参数是要修改访问权限的进程句柄;第二个参数指定要进行的操作类型(TOKEN_ADJUST_PRIVILEGES:修改令牌的访问权限,TOKEN_QUERY:查询令牌);第三个参数是返回的访问令牌指针
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
:
//获取一个权限对应的LUID值(代表指定的特权名称),第一个参数是系统的名称(本地系统为NULL),第二个参数指明权限的名称(SE_DEBUG_NAME:Required to debug and adjust the memory of a process owned by another account.);第三个参数返回LUID的指针
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid);
//根据上一步获取的LUID值,为相应特权赋予新的特权属性(SE_PRIVILEGE_ENABLED:特权启用.)。
TOKEN_PRIVILEGES tkp;
tkp.Privileges[0].Luid = luid;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
//对之前获得的访问令牌进行修改,使进程获得调试权。第一个参数是访问令牌的句柄;第二个参数为FALSE表示根据后一个参数进行权限修改;第三个参数指明要修改的权限,是一个指向TOKEN_PRIVILEGES结构的指针
AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof tkp, NULL, NULL);

② 获取目标进程的 PID

目的:PID 为进程唯一标识,获取后方便后面获取目标进程的句柄

所用函数:getProcessHandle();

③ 获得要注入进程的句柄

目的:获得目标进程操作内存空间的权限(可用 VirtualProtectEx 和 WriteProcessMemory)

所用函数:

HANDLE hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, dwpid);

④ 在远程进程中开辟出一段内存

目的:开辟空间用来存放要调用的 dll 的路径

所用函数:

//name + ’
DWORD dwSize = strlen(lpDllName) + 1;
//在指定进程内开辟虚拟空间,第一个参数:申请内存所在的进程句柄;第二个参数:保留页面的内存地址;一般用NULL自动分配;第三个参数:欲分配的内存大小。MEM_COMMIT:为特定的页面区域分配物理存储;PAGE_READWRITE:区域可被应用程序读写
LPVOID lpRemoteBuf = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);

⑤ 将包含恶意代码的 dll 的名字写入上一步开辟出的内存中

所用函数:

//写入内存,函数执行成功返回写入的字节数
WriteProcessMemory(hProcess, lpRemoteBuf, lpDllName, dwSize,(SIZE_T)&dwHasWrite);
//若写入失败,应释放之前分配的内存
VirtualFreeEx(hProcess, lpRemoteBuf, dwSize, MEM_COMMIT);
⑥在被注入进程中创建新线程加载该dll

目的:调用 dll 执行恶意代码
所用函数:

DWORD dwNewThreadId;
//使用LoadLibrary函数来加载动态链接库
LPVOID lpLoadDll = LoadLibraryA;
//创建远程线程,第一个参数为线程所属进程的进程句柄;第三个参数为线程初始大小,以字节为单位,如果该值设为0,那么使用系统默认大小;第四个参数为在远程进程的地址空间中,该线程的线程函数的起始地址.
HANDLE hNewRemoteThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpLoadDll, lpRemoteBuf, 0, &dwNewThreadId);

⑦ 卸载注入的 dll

思路:获得在远程线程中被注入的 Dll 的句柄 —> 卸载 Dll

所用函数:

//获得在远程线程中被注入的Dll的句柄
LPVOID pFunc = GetModuleHandleA;
//获取DLL模块的路径
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, lpRemoteBuf, 0, &dwID);
GetExitCodeThread(hThread, &dwHandle);
//线程的结束码即为Dll模块儿的句柄,存入dwHandle中
//将FreeLibraryA注入到远程线程中卸载Dll
pFunc = FreeLibrary;
hThread = CreateRemoteThread(hThread, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, (LPVOID)dwHandle, 0, &dwID);

2、IATHOOK 程序(fakedll.dll 中调用的攻击代码)

(1)功能:程序中每个调用 API 函数的 CALL 指令所使用的地址都是相应函数登记在 IAT 表的地址,我们将目标进程(cmd.exe)中的 FindNextFileW 函数(遍历文件目录时使用,存储了文件名等信息)在 IAT 表中的地址替换为攻击者编写的虚假 FindNextFileW 函数地址,其中在读到指定文件时在 cmd.exe 界面上不会显示该文件文件名,起到文件隐藏的作用。程序中每个调用 API 函数的 CALL 指令所使用的地址都是相应函数登记在 IAT 表的地址。

(2)代码逻辑:

在这里插入图片描述

四 实验效果

1、待测试目录

在这里插入图片描述

2、DLL 注入前后效果比较

在这里插入图片描述

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到