跳至主要内容

27.远程线程注入

注入

  • 所谓注入就是在第三方进程不知道或者不允许的情况下将模块或者代码写入对方进程空间,并设法执行的技术
  • 已知注入方式
    • 远程线程注入,APC注入、消息钩子注入、注册表注入、导入表注入、输入法注入等等。

流程

  • 思路:在进程A中创建线程,将线程函数指向为:LoadLibrary()
  • 具体实现步骤
    • 在进程A中分配空间,存储“A.dll”
    • 获取LoadLibrary函数的地址
    • 创建远程线程,执行LoadLibrary()函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <debugapi.h>
#include <handleapi.h>
#include <libloaderapi.h>
#include <memoryapi.h>
#include <minwindef.h>
#include <processthreadsapi.h>
#include <string.h>
#include <windows.h>
#include <stdio.h>
#include <winnt.h>

BOOL LoadDll(DWORD dwProcessID,char *szDllPathName){
BOOL bRet;
HANDLE hProcess;
HANDLE hThread;
DWORD dwLength;
FARPROC dwLoadAddr;
LPVOID lpAllocAddr;
HMODULE hModule;

bRet = FALSE;
dwLoadAddr = 0;
hProcess = 0;

//获取进程句柄
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE,dwProcessID);
if (hProcess == NULL) {
OutputDebugStringA("OpenProcess Error! \n");
return FALSE;
}
//计算DLL路径名字长度,并且要加上0结尾的长度
dwLength = strlen(szDllPathName) + 1;

//在目标进程分配内存
lpAllocAddr = VirtualAllocEx(hProcess, NULL, dwLength, MEM_COMMIT,PAGE_READWRITE);

if (lpAllocAddr == NULL) {
OutputDebugStringA("VirtualAllocEx Error! \n");
CloseHandle(hProcess);
return FALSE;
}
//拷贝DLL路径名字到目标进程的内存
bRet = WriteProcessMemory(hProcess, lpAllocAddr, szDllPathName,dwLength,NULL);
if (!bRet) {
OutputDebugStringA("WriteProcessMemory Error! \n");
CloseHandle(hProcess);
return FALSE;
}

//获取模块地址
hModule = GetModuleHandleA("Kernel32.dll");
if (hModule == NULL) {
OutputDebugStringA("GetModuleHandleA Error! \n");
CloseHandle(hProcess);
return FALSE;
}
//获取LoadLibraryA函数地址
dwLoadAddr = GetProcAddress(hModule, "LoadLibraryA");
if (dwLoadAddr == NULL) {
OutputDebugStringA("GetProcAddress Error! \n");
CloseHandle(hProcess);
CloseHandle(hModule);
return FALSE;
}
//创建远程线程,加载DLL
hThread = CreateRemoteThread(hProcess, NULL, 0,(LPTHREAD_START_ROUTINE)dwLoadAddr,lpAllocAddr,0,NULL);
if (hThread == NULL) {
OutputDebugStringA("CreateRemoteThread Error! \n");
CloseHandle(hProcess);
CloseHandle(hModule);
return FALSE;
}

CloseHandle(hProcess);
CloseHandle(hThread);

return TRUE;
}

int main(int argc, char *argv[]) {
LoadDll(111, "");
return 0;
}

  • 哎?此时会发现只是Load了DLL并没有执行任何东西
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include <stdio.h>

DWORD WINAPI ThreadProc(LPVOID lpParameter) {
while(1){
printf("Fuck The System!");
Sleep(1000);
}
}


BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
break;
case DLL_THREAD_ATTACH:
OutputDebugStringA("DLL_THREAD_ATTACH\n");
break;
case DLL_THREAD_DETACH:
OutputDebugStringA("DLL_THREAD_DETACH\n");
break;
case DLL_PROCESS_DETACH:
OutputDebugStringA("DLL_PROCESS_DETACH\n");
break;
}
return TRUE;
}


  • 我们自启动不就好了!

关于本文

由 GuQing 撰写,采用 CC BY-NC 4.0 许可协议。