CreateRemoteThread和WriteProcessMemory技术 示例程序:WinSpy 另一种注入代码到其他进程地址空间的方法是使用WriteProcessMemory API。 这次你不用编写一个独立的DLL而是直接复制你的代码到远程进程(WriteProcessMemory)并用CreateRemoteThread执行之。 让我们看一下CreateRemoteThread的声明: HANDLE CreateRemoteThread( HANDLE hProcess, // handle ●CreateRemoteThread的lpStartAddress参数必须指向远程进程的地址空间中的函数。 用CreateRemoteThread启动远程的ThreadFunc。 7. 等待远程线程的结束(WaitForSingleObject)。 8.
FARPROC GetProcAddress( [in] HMODULE hModule, [in] LPCSTR lpProcName ); CreateRemoteThread函数 https ://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createremotethread ));//获取下一个进程句柄 CloseHandle(processAll); //关闭句柄 return processId; } 远程线程注入实现原理 dll远程线程注入的核心是CreateRemoteThread 从CreateRemoteThread需要的传递的参数中可知,我们需要目标进程空间的多线程函数地址,以及多线程参数。 这样就可以成功在目标的空间中利用CreateRemoteThread创建一个多线程。
总览 注入 OpenProcess() VirtualAllocEx() WriteProcessMemory() GetProcessAddress() -> LoadLibrary CreateRemoteThread CreateToolhelp32Snapshot() Module32FirstW Module32NextW OpenProcess() GetProcessAddress -> FreeLibrary() CreateRemoteThread Kernel32")), "LoadLibraryW"); if (pLoadLib == NULL) return FALSE; AfxMessageBox(_T("OK")); hThread = CreateRemoteThread FreeLibrary"); if (psrThread == NULL) { AfxMessageBox(L"找freelibrary失败"); return FALSE; } hThead = CreateRemoteThread (hProcess, NULL, 0, psrThread, me.modBaseAddr, 0, NULL); if (hThead == NULL) { AfxMessageBox(L"CreateRemoteThread
反汇编QDesk,里面有CreateRemoteThread,很可能跟这个有关。ollydbg用得不熟,否则可以断点看下是不是在Explorer.exe里面创建的线程。 但是x64下, CreateRemoteThread没找到办法Inject到64位的explorer.exe。 在32位系统里, CreateRemoteThread,注入一个线程到explorer.exe,然后在线程里SetWindowLong替换窗口过程,实现应该不难。 原理一样,CreateRemoteThread->LoadLiibray->DllMain,SetWindowLong GWL_WNDPROC->WM_WINDOWPOSCHANGING. 只不过在x64下,注入程序和dll都要编译成64位程序,才能在explorer.exe里面 CreateRemoteThread成功。 耗费了很长时间在x64上 运行结果:
DLL注入的实现方式有许多,典型的实现方式为远程线程注入,该注入方式的注入原理是利用了Windows系统中提供的CreateRemoteThread()这个API函数,该函数第四个参数是准备运行的线程, VirtualAllocEx 在目标进程申请一块内存3.WriteProcessMemory 将注入DLL路径写出到内存中4.GetProcAddress 获得LoadLibraryA函数的内存地址5.CreateRemoteThread 创建远线程,实现DLL注入远程注入的核心实现原理是利用了CreateRemoteThread函数,CreateRemoteThread是Windows系统的一个函数,能够在指定的进程上下文中创建一个线程 该函数的声明如下所示;HANDLE WINAPI CreateRemoteThread( HANDLE hProcess, LPSECURITY_ATTRIBUTES if (NULL == pFuncProcAddr) { return FALSE; } // 启动线程注入 HANDLE hRemoteThread = CreateRemoteThread
注入已有进程: OpenProcess —> WriteProcessMemory —> CreateRemoteThread; 创建进程注入: CreateProcess —> WriteProcessMemory 如果是遇到CreateRemoteThread的情况,就比较直观,只要直接找到该函数的第四个参数lpStartAddress,就是我们要找的context值,下图是一个示例: ? 找到上下文地址后,只需要断在CreateRemoteThread或ResumeThread函数上,使用WinHex打开程序要注入的进程,将该上下文地址处的代码修改为JMP到当前地址(或0xCC,此处可以发散一下 ,只要是能够想办法断下来即可),再单步步过(F8)CreateRemoteThread/ResumeThread,使用OD附加到注入的进程,断在上下文地址处,再将代码修改回原来的代码即可继续执行。 Lib "kernel32" Alias "CreateRemoteThread" (ByVal hProcess As Long, ByVal lpThreadAttributes As Long,
前言 比较常见的进程注入是:CreateRemoteThread。 主要过程为: 1.VirtualAllocEx -> 分配内存空间来暂存 shellcode 2 .WriteProcessMemory -> 将解密/解码的shellcode写入内存空间 3 .CreateRemoteThread 注入方法 在原文中使用的是:远线程(CreateRemoteThread)注入. 创建一个新线程 在远程进程中创建一个新的线程来执行shellcode(CreateRemoteThread) C# demo IntPtr hThread = CreateRemoteThread( processObj.Handle , IntPtr.Zero, 0, addr, IntPtr.Zero, 0x0, out hThread ); Powershell Demo [Dll_text_inject]::CreateRemoteThread
DLL注入的实现方式有许多,典型的实现方式为远程线程注入,该注入方式的注入原理是利用了Windows系统中提供的CreateRemoteThread()这个API函数,该函数第四个参数是准备运行的线程, VirtualAllocEx 在目标进程申请一块内存 3.WriteProcessMemory 将注入DLL路径写出到内存中 4.GetProcAddress 获得LoadLibraryA函数的内存地址 5.CreateRemoteThread 创建远线程,实现DLL注入 远程注入的核心实现原理是利用了CreateRemoteThread函数,CreateRemoteThread是Windows系统的一个函数,能够在指定的进程上下文中创建一个线程 该函数的声明如下所示; HANDLE WINAPI CreateRemoteThread( HANDLE hProcess, LPSECURITY_ATTRIBUTES (NULL == pFuncProcAddr) { return FALSE; } // 启动线程注入 HANDLE hRemoteThread = CreateRemoteThread
"WriteProcessMemory 失败:" << GetLastError() << endl;} // 创建远程线程 HANDLE hNewRemoteThread = CreateRemoteThread hNewRemoteThread){cout << "CreateRemoteThread 失败:" << GetLastError() << endl;} // 等待线程句柄返回 WaitForSingleObject strlen(szDllName) + , ); //在目标进程内创建线程,线程的入口函数就是LoadLibraryA, 参数就是Dll名字 HANDLE hThread = CreateRemoteThread MB_OK); HeapFree(GetProcessHeap(), , lpShowOut); return ; } 需要注意的点都在那一大串注释中 64位进程,就得用64位的EXE来CreateRemoteThread , 另外DLL也应该是64位 32位进程,就得用32位的EXE来CreateRemoteThread, 另外DLL也应该是32位 把CreateRemoteThread的入口点函数设为LoadLibraryA
dllAddr, pathLen, MEM_DECOMMIT); CloseHandle(hPro); return; } DWORD dwPid; HANDLE hThread = CreateRemoteThread WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); CloseHandle(hPro); } 这个只适用于xp系统,win7系统不可以随便CreateRemoteThread 了,返回值一直为NULL 具体方法引用看雪:Vista&Win7下CreateRemoteThread应用的若干问题和解决方案 Dll卸载与注入流程大体相同,先创建 进程快照找到相应的线程模块,获取FreeLibrary ); FARPROC pFun = GetProcAddress(GetModuleHandle("kernel32.dll"),"FreeLibrary"); HANDLE hThread = CreateRemoteThread
ERROR]GetProcAddress(%d)\n", GetLastError() ); return FALSE ; } //创建远程线程 HANDLE hRemoteThread = CreateRemoteThread NULL, 0,fnStartAddr, lpRemoteDllName, 0, NULL ) ; if ( hRemoteThread == NULL ) { printf ( "[ERROR]CreateRemoteThread
Files written to: syscom.asm syscom.h 经典的CreateRemoteThread DLL注入实例 py . LoadLibraryA"); WriteProcessMemory(hProcess, lpBaseAddress, dllPath, strlen(dllPath), nullptr); CreateRemoteThread 使用下列函数及方法并配合“—preset common”参数,可以创建一个Header/ASM键值对: NtCreateProcess (CreateProcess) NtCreateThreadEx (CreateRemoteThread
这篇文章将分析最经典的注入方法: VirtualAllocEx WriteProcessMemory CreateRemoteThread 内存分配 VirtualAllocEx将在目标进程中分配一个新的内存区域 执行 Shellcode CreateRemoteThread在目标进程中创建一个将执行 shellcode 的新线程。线程的起始地址将指向保存 shellcode 的内存区域。 var hThread = Kernel32.CreateRemoteThread( target.Handle, null, 0, hMemory, IntPtr.Zero 那么我们可以最初将其分配为RW,写入shellcode然后在调用 CreateRemoteThread 之前使用VirtualProtectEx使其成为 RX。 那么我们可以尝试使用将 CreateRemoteThread 的使用替换为QueueUserAPC 来解决“线程”问题,也就是使用APC注入。
#include <windows.h> #include <stdio.h> // 使用 CreateRemoteThread 实现远线程注入 BOOL CreateRemoteThreadInjectDll 创建远线程, 实现 DLL 注入 HANDLE hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE #include <windows.h> #include <stdio.h> // 使用 CreateRemoteThread 实现远线程注入 BOOL CreateRemoteThreadInjectDll 创建远线程, 实现 DLL 注入 hThread = CreateRemoteThread(hProcess, NULL, 1024, (LPTHREAD_START_ROUTINE)pfnThreadRtn 由于CreateRemoteThread()底层会调用ZwCreateThreadEx()这个未公开的内核函数,所以我们必须手动调用ZwCreateThread()这一内核函数,将第七个参数设置为0即可
32位:远程线程注入 远程线程注入是最常用的一种注入技术,该技术利用的核心API是 `CreateRemoteThread()` 这个API可以运行远程线程,其次通过创建的线程调用 `LoadLibraryA LPTHREAD_START_ROUTINE lpStartAddress=(LPTHREAD_START_ROUTINE)GetProcAddress(hModule,"LoadLibraryA"); HANDLE hThread=CreateRemoteThread WriteProcessMemory(hProcess, pwszPara, (PVOID)pwszProxyFile, iProxyFileLen, NULL); hThread = CreateRemoteThread
优点:准确的控制注入周期 缺点:依赖消息循环,没消息循环的线程没法注入 远程线程注入(大杀器) 核心方法: CreateRemoteThread VirtualAllocEx VirtualFreeEx ReadProcessMemory WriteProcessMemory 可以用 CreateRemoteThread 在指定进程中创建一个线程,让它执行我们自己的代码,这样可以让远程线程 Load 一个我们自己的 DLL,这就可以为所欲为了……需要注意的是,CreateRemoteThread 的参数 PTHREAD_START_ROUTINE 这个函数地址,需要调用 GetProcAddress
DLL文件,复制到目标/远程进程的内存空间 4.控制进程运行DLL文件 主要用到的几个函数: OpenProcess、VirtualAllocEx、WriteProcessMemory、CreateRemoteThread threatStartRoutineAddress = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW"); CreateRemoteThread 在上面的注入方式中,我们使用了CreateRemoteThread来进行dll注入,而这个方式在具有Sysmon的系统中会留下Event ID 8的痕迹。 通过编写ReflectiveLoader找到DLL文件在内存中的地址,分配装载DLL的空间,并计算 DLL 中用于执行反射加载的导出的内存偏移量,然后通过偏移地址作为入口调用 CreateRemoteThread
WriteProcessMemory(hTargetProcess, targetPage, shellcode, sizeof(shellcode), NULL); DWORD ignored; CreateRemoteThread -> Process32First --> Process32Next 创建线程: OpenProcess --> VirtualAllocEx --> WriteProcessMemory --> CreateRemoteThread LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD); CreateRemoteThreadPrototype CreateRemoteThread = (CreateRemoteThreadPrototype)GetProcAddress(Kernels32, "CreateRemoteThread"); HANDLE hTargetProcess WriteProcessMemory(hTargetProcess, targetPage, shellcode, sizeof(shellcode), NULL); DWORD ignored; CreateRemoteThread
登录后的用户环境,kernel 6引入 系统会话是0,与用户会话隔离(即第一个登录的用户是会话1,而之前是会话0) 但是会话1中的进程可以强行终止会话0中的进程 2、DLL注入 原先的用CreateRemoteThread FALSE; } } else // 2000, XP, Server2003 { hThread = CreateRemoteThread NULL); if( hThread == NULL ) { printf("MyCreateRemoteThread() : CreateRemoteThread
pfnLoadLibraryAddr ) { break; } pRemoteLoadLibraryThread = CreateRemoteThread 之后CreateRemoteThread将在被注入进程中创建一个线程会去调用LoadLibrary,我们的DLL就被载入了,可以为所欲为了。 break; } // 远线程卸载DLL HANDLE pRemoteFreeLibraryThread = CreateRemoteThread pfnLoadLibraryAddr ) { break; } pRemoteLoadLibraryThread = CreateRemoteThread break; } // 远线程卸载DLL HANDLE pRemoteFreeLibraryThread = CreateRemoteThread