比较忙,更新个作业。
基本思路
目标是:注入到explorer的进程空间,利用CreateProcess启动目标进程target.exe。
其中的基本步骤为:
- 创建一个进程,打开explorer,涉及相关API:CreateProcess
- 提取向其他进程空间写和执行的权限,涉及相关API:AdjustTokenPrivileges
- 编写需要注入的代码和数据结构
- 打开进程explorer,进入其内存空间分配内存、获取函数地址、写入代码和数据,然后执行,涉及到的API:OpenProcess、VirtualAllocEx、WriteProcessMemory、GetProcAddress、CreateRemoteThread。
核心代码
步骤1:打开explorer进程
使用CreateProcessA实现,传入命令,其中涉及到两个结构体,其中pi中dwProcessId即为进程ID,在后面注入时需要此信息。
1 | STARTUPINFO si; |
步骤2:Set Privilege
利用AdjustTokenPrivileges赋予本进程SE_PRIVILEGE_ENABLED的Debug权限,可以打开其他进程。
1 | BOOL SetProcessPrivilege(char *lpName, BOOL opt) |
步骤3:注入例程编写
其中包括:
- 声明需要调用的API的类型MY_CreateProcessA、MY_MESSAGEBOX(非必须,只是用来debug用)
- 例程需要使用的参数放入一个结构体Param中,其中包括待打开进程名、函数地址以及调用函数需要的结构体参数PROCESS_INFORMATION和STARTUPINFO
- 在threadProc中,利用lpdata中的参数、函数地址完成功能
1 | typedef BOOL (* MY_CreateProcessA)( |
步骤4:代码注入
打开目标进程,权限设置为PROCESS_ALL_ACCESS
1
2
3
4
5
6
7
8if (pid)
{
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
}
if (hProcess == NULL)
{
MessageBox(NULL, "OpenProcess Failed!", "Wrong", MB_OK);
}将编写的例程代码写入目标进程(explorer)空间,注意内存页属性设置为可执行的PAGE_EXECUTE_READWRITE
1
2
3
4
5
6
7
8
9LPVOID remoteFunc = VirtualAllocEx(
hProcess, NULL, 4096,
MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (!WriteProcessMemory(hProcess, remoteFunc, &threadProc, 4096, NULL))
{
MessageBox(NULL, "WriteProcessMemory Failed!", "Wrong", MB_OK);
VirtualFreeEx(hProcess, remoteFunc, 4096, MEM_RELEASE);
CloseHandle(hProcess);
}获取API的地址(不同进程空间同一API的地址预设为相等)、将参数赋值,然后写入目标进程的地址空间。其中target.exe即为需要打开的程序。
1
2
3
4
5
6
7
8
9
10
11
12
13
14data.dwMess = (DWORD)GetProcAddress(GetModuleHandle("user32"), "MessageBoxA");
data.dwFunc = (DWORD)GetProcAddress(GetModuleHandle("Kernel32"), "CreateProcessA");
strcpy(data.exeName, "C:\\target.exe");
ZeroMemory( &data.si, sizeof(data.si) );
data.si.cb = sizeof(data.si);
ZeroMemory( &data.pi, sizeof(data.pi) );
LPVOID remoteData = VirtualAllocEx(
hProcess, NULL, sizeof(data), MEM_COMMIT, PAGE_READWRITE);
if (!WriteProcessMemory(hProcess, remoteData, &data, sizeof(data), NULL))
{
MessageBox(NULL, "WriteProcessMemory Failed!", "Wrong", MB_OK);
VirtualFreeEx(hProcess, remoteData, sizeof(data), MEM_RELEASE);
CloseHandle(hProcess);
}调用CreateRemoteThread,在目标进程中启动线程
1
2
3
4
5
6
7hThread = CreateRemoteThread(
hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)remoteFunc, remoteData, 0, NULL);
if (hThread == NULL)
{
MessageBox(NULL, "CreateRemoteThread Failed!", "Wrong", MB_OK);
CloseHandle(hProcess);
}
效果展示
WindowsXP上能成功,能跑。
参考资料
- 【干货】Windows进程注入之CreateRemoteThread_Windows Server - UCloud云社区
- 创建进程 - Win32 apps | Microsoft Docs
- https://docs.microsoft.com/en-us/windows/win32/
Author: chengan 2022/3/22