cnhackteam7 发布于2022年11月8日 分享 发布于2022年11月8日 0x00 前言 要远程注入指定的进程,通常使用Windows提供的API CreateRemoteThread创建一个远程线程,然后注入dll或者执行shellcode。 在64位系统下,这种方法需要特别注意。注入的目标进程要和程序结构一致,即32位程序只能注入32位进程,64位程序只能注入64位进程。 32位程序注入64位程序会失败(32位和64位结构不同)。 但是在一些特殊情况下,无法预先预测目标流程的结构,准备两个不同版本的程序也是不现实的。 所以我们只能重新思考这个问题: 32位程序真的不能远程注入64位程序吗? 0x01 简介 我在odzhan的博客里找到了解决办法。文章地址如下: https://mode XP . WordPress . com/2015/11/19/dllpic-injection-on-windows-from-wow 64-process/ 本文将介绍实现思路,参考odzhan的开源项目“pi”,编写测试代码,生成32位程序,实现64位进程calc.exe的进程注入,验证32位程序可以注入64位进程的结论。 0x02 实现思路 1、32位程序支持对64位程序的读写 参考资料: rgb/29a: http://www.vxheaven.org/lib/vrg02.html ReWolf: http://blog.rewolf.pl/blog/ https://github.com/rwfpl/rewolf-wow64ext 2、 利用CreateRemoteThread作进程注入的通用方法 进程注入流程: OpenProcess 虚拟分配 WriteProcessMemory 虚拟保护 创建远程线程 WaitForSingleObject 在具体实现过程中,如果指定了一个进程名,就需要先把进程名转换成进程ID。参考代码如下: DWORD processname oid(LPCTSTR lpsz processname) { HANDLE hSnapshot=createtoolhelp 32 snapshot(th 32 cs _ snap process,0); PROCESSENTRY32 pe PE . dwsize=sizeof(process entry 32); 如果(!Process32First(hSnapshot,pe)) { MessageBox(NULL,'进程列表的第一个条目尚未复制到缓冲区',' Notice ',MB _ icon information | MB _ OK); 返回0; } while (Process32Next(hSnapshot,pe)) { 如果(!strcmp(lpszProcessName,pe.szExeFile)) { 返回PE . th 32 processid; } } 返回0; } 依次执行以下操作: 根据进程ID打开进程,获取进程句柄。 申请内存空间 读入数据 将内存改为可读和可执行的(可选) 创建线程 等待线程退出(可选) 代码可以指: http://blog.csdn.net/g710710/article/details/7303081 参考代码略有修改,注射过程的名称被指定为calc.exe。完整的代码已经上传到github,地址如下: https://github . com/3g student/CreateRemoteThread/blob/master/createremotethreadtest . CPP 程序运行后,找到进程calc.exe,然后尝试远程注入,弹出一个对话框,如图。 将程序编译成x86,注入32位进程calc.exe,成功。 程序编译成x64,成功注入64位进程calc.exe。 将程序编译成x86,注入64位进程calc.exe。OpenProcess、VirtualAllocEx、WriteProcessMemory和VirtualProtectEx都正常,执行CreateRemoteThread时会报错。 解决思路: 参考rgb/29a和ReWolf的思路,将这里的CreateRemoteThread切换到64位再创建线程,完成后再切换回32位,就可以实现32位程序到64位进程的远程注入。 3、判断当前系统是32位还是64位 使用API: void WINAPI GetNativeSystemInfo( _Out_ LPSYSTEM_INFO lpSystemInfo ); 查看结构中的wProcessorArchitecture得到CPU架构,然后判断操作系统。 代码如下: #包括 BOOL Is64BitOS() { typedef VOID(WINAPI * LPFN _ GetNativeSystemInfo)(_ _ out LP system _ INFO LPSYSTEM INFO); LPFN _ GetNativeSystemInfo fnGetNativeSystemInfo=(LPFN _ GetNativeSystemInfo)GetProcAddress(GetModuleHandle(' kernel 32 '),' GetNativeSystemInfo '); if(fnGetNativeSystemInfo) { SYSTEM _ INFO stInfo={ 0 }; fnGetNativeSystemInfo(stInfo); if(stinfo . wprocessorarchicture==PROCESSOR _ ARCHITECTURE _ IA64 | | stinfo . wprocessorarchitecture==PROCESSOR _ ARCHITECTURE _ AMD64) { 返回TRUE } } 返回错误的 } int main() { if (Is64BitOS()) printf(' x64 \ n '); 其他 printf(' x86 \ n '); 返回0; } 4、判断注入的进程是32位还是64位 查找进程ID,打开进程,获得句柄,使用API,传入参数,进行判断 使用API: BOOL WINAPI IsWow64Process( _ _在处理h过程时, _ _ out PBOOL进程 ); 返回没错,代表进程是32位,否则是64位 完整代码如下: #包括 #包括 BOOL IsWow64(处理hProcess) { typedef BOOL(WINAPI * LPFN _ is wow 64进程)(HANDLE,PBOOL); LPFN _ is wow 64进程fnis wow 64进程; BOOL bIsWow64=FALSE fnis wow 64 process=(LPFN _ is wow 64 process)GetProcAddress( GetModuleHandle('kernel32 '),'是wow 64进程'); if (NULL!=fnIsWow64Process) { fnIsWow64Process(hProcess,bis wow 64); } 返回bIsWow64 } DWORD进程名oid(LPCTSTR lpsz进程名) { HANDLE hSnapshot=createtoolhelp 32 snapshot(th 32 cs _ snap process,0); PROCESSENTRY32 pe 体育。dwsize=sizeof(进程条目32); 如果(!Process32First(hSnapshot,pe)) { MessageBox(空, 进程列表的第一个条目尚未复制到缓冲区、‘通知’,MB _ icon信息| MB _ OK); 返回0; } while (Process32Next(hSnapshot,pe)) { 如果(!strcmp(lpszProcessName,pe.szExeFile)) { 返回体育。th 32 processid } } 返回0; } int main() { BOOL bWow64 char * szExeName=' calc.exe DWORD dwProcessId=进程名oid(SZ exename); if (dwProcessId==0) { MessageBox(空,"未找到目标进程!",'通知,MB _ icon信息| MB _ OK); return-1; } HANDLE hTargetProcess=open PROCESS(PROCESS _ ALL _ ACCESS,FALSE,dw processid); 如果(!hTargetProcess) { MessageBox(空,"打开目标进程失败!", '注意,MB _ icon信息| MB _ OK); 返回0; } bwow 64=is wow 64(hTargetProcess); if(bWow64) printf('32位进程\ n’); 其他 printf('64位进程\ n’); } 5、开源工程pi 下载地址: https://github.com/odzhan/shellcode/tree/master/win/pi 用法:pi[选项] -d在内存分配后运行线程前等待 -e在远程进程的上下文中执行命令(显示窗口) -f将电影文件加载到远程进程中 -我将动态链接库文件加载到远程进程中 -p列出系统上可用的进程 加在以-u结尾的法语词源的名词之后构成复数排除在中央处理器模式下运行的进程,32或64 示例: 这是一个测试测试. txt记事本测试。txt '-x32 iexplore.exe pi-l ws2 _ 32。dll notepad.exe pi-f反_壳。宾chrome.exe 测试系统: Win7x64 cmd执行: pi32.exe-简体中文开始计算。exe '-x32 calc.exe 上述命令将对64位的calc.exe进行注入 回显如图 有效载荷没有成功执行 0x03 最终代码 虽然圆周率测试失败,但是代码值得参考,提取关键代码,开发测试程序 测试程序结构如下: 判断当前系统 如果为32位系统,调用系统美国石油学会(American Petroleum Institute)创建远程线程,对目标进程尝试远程注入,弹出对话框 如果为64位系统,进入下一个分支,对进程判断 判断进程calc.exe 如果为32位,调用系统美国石油学会(American Petroleum Institute)创建远程线程,对目标进程尝试远程注入,弹出对话框 如果为64位,调用自定义美国石油学会(American Petroleum Institute)创建远程线程64,对目标进程尝试远程注入,执行有效负载:“cmd /c启动calc.exe” 完整代码已上传github,下载地址如下: https://github。com/3g student/create remote thread/blob/master/create remote thread 32到64。卡片打印处理机(Card Print Processor的缩写) 0x04 实际测试 测试系统: Win7 x64 1、将程序编译成32位,打开64位calc.exe 2、运行测试程序 命令行输出如图 成功执行有效负载:" cmd /c start calc.exe ",弹出计算器 0x05 小结 介绍了用32位程序远程注入64位进程的实现方法。参考上面的代码,可以实现Windows 32位/64位系统中进程注入的通用模板。 留下回复 链接帖子 意见的链接 分享到其他网站 更多分享选项…
推荐的帖子