前言
当我们获取到一台主机的权限过后,拿到了自己想要搜集的信息,这时候我们就会留一个后门进行权限维持,权限维持的学问其实很深,今天就主要介绍其中一种比较简单的权限维持的方法 – 进程伪装。
我们知道在windows里面有很多系统进程,如winlogon.exe、explorer.exe、services.exe等等,这些exe都是Windows必须具有的exe,当缺失某些exe的时候,windows就不能够正常运行,所以我们如果想到实现进程伪装,最好的选择就是伪装成系统必备的exe,当我们进行进程伪装之后,在系统中显示的就会是系统进程的信息,但这个程序还是能够执行它正常的功能,这样就达到了进程伪装、权限维持的作用。
思路
我们判断一个进程是否被劫持,一般是看他的进程名以及path,即启动路径来判断,那么反推即可得到,我们可以通过修改进程模块中的进程路径以及进程名来实现进程伪装的作用
比如我们这里再看看explorer的进程名和启动路径
那么这里我们改人如何获取进程的这些信息呢,这里可以使用到ntdll.dll里面的NtQueryInformationProcess来获取进程的PEB地址,这里稍微提一个概念,什么是PEB?
PEB,即Process Envirorment Block Structure,英文翻译过来就是进程环境信息块,这里包含了写进程的信息。它的完整结构如下:
typedef struct _PEB {
BYTE Reserved1[2];
BYTE BeingDebugged; //被调试状态
BYTE Reserved2[1];
PVOID Reserved3[2];
PPEB_LDR_DATA Ldr;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
BYTE Reserved4[104];
PVOID Reserved5[52];
PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
BYTE Reserved6[128];
PVOID Reserved7[1];
ULONG SessionId;
} PEB, *PPEB;
这里就不深究每个属性的含义了,这里拿到PEB结构之后我们就能够对进程的一些属性进行修改就能够实现进程伪装的效果,但是这里并不能够通过指针来直接速写内存数据,因为每个程序都有自己独立的空间,所以这里就需要用到ReadProcessMemory和WriteProcessMemory来读写进程
BOOL ReadProcessMemory(
[in] HANDLE hProcess,
[in] LPCVOID lpBaseAddress,
[out] LPVOID lpBuffer,
[in] SIZE_T nSize,
[out] SIZE_T *lpNumberOfBytesRead
);
BOOL WriteProcessMemory(
[in] HANDLE hProcess,
[in] LPVOID lpBaseAddress,
[in] LPCVOID lpBuffer,
[in] SIZE_T nSize,
[out] SIZE_T *lpNumberOfBytesWritten
);
实现过程
首先使用OpenProcess打开进程句柄
HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
然后从ntdll.dll中获取NtQueryInformationProcess的导出地址,因为这个函数没有关联导入库,所以只能动态获取地址
NtQueryInformationProcess = (typedef_NtQueryInformationProcess)::