远程代码注入
2016-06-29 19:39
417 查看
除了通常的通过DLL注入来向其他进程插入代码,还有一种方法,就是直接想目标进程插入代码,此方法与前者相比之下有以下几个优点:
1、由于不用注入DLL,所以是目标进程占用的内存更小
2、由于没有注入DLL,也使得更不容易被检测到(比如有些检测手段通过对比进程运行前后的DLL来判断是否有DLL插入)
当然这种方法也有其缺点,它编程相对复杂,不适合大量代码注入,另外在提权操作中可能有失败的情况,我亲测本方法在win10环境中,提权会失败。
小结:
本程序虽然短小,但是注入思路简洁,将自定结构体作为参数和将写入远进程的缓冲区的起始地址作为创建远线程的参数的方法值得借鉴,原先让我这个不太懂编程的孩子是打破脑袋也想不到的,实为精妙,至于为什么在win10 64位运行失败,以后再来研究。
后续:
1、关于之前在WIN10上CreateRemoteThread失败返回失败码5放入情况,网上查看说是因为权限不够,32位程序在64位系统提权失败,实际上,我的提权函数也写过错误代码而并没有返回错误,说明不是提权失败,而是CreateRemoteThread这个函数在64位系统运行出错的问题,测试用此程序在自己创建的exe程序注入的时候并没有出现异常,猜想是win 10 64位对系统进程作了保护机制,究竟是什么,还是没弄清楚,待进一步查证。
1、由于不用注入DLL,所以是目标进程占用的内存更小
2、由于没有注入DLL,也使得更不容易被检测到(比如有些检测手段通过对比进程运行前后的DLL来判断是否有DLL插入)
当然这种方法也有其缺点,它编程相对复杂,不适合大量代码注入,另外在提权操作中可能有失败的情况,我亲测本方法在win10环境中,提权会失败。
#include "stdafx.h" #include "windows.h" #include "stdio.h" BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege) { TOKEN_PRIVILEGES tp; HANDLE hToken; LUID luid; if( !OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken) ) { printf("OpenProcessToken error: %u\n", GetLastError()); return FALSE; } if( !LookupPrivilegeValue(NULL, // lookup privilege on local system lpszPrivilege, // privilege to lookup &luid) ) // receives LUID of privilege { printf("LookupPrivilegeValue error: %u\n", GetLastError() ); return FALSE; } tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; if( bEnablePrivilege ) tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; else tp.Privileges[0].Attributes = 0; // Enable the privilege or disable all privileges. if( !AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL) ) { printf("AdjustTokenPrivileges error: %u\n", GetLastError() ); return FALSE; } if( GetLastError() == ERROR_NOT_ALL_ASSIGNED ) { printf("The token does not have the specified privilege. \n"); return FALSE; } return TRUE; } typedef struct _THREAD_PARAM { FARPROC pFunc[2];//LoadlibraryA(),GetProAddress() char szBuf[4][128];//"user32.dll","MessageBoxA" //"www.reversecore.com","RecerseCore" }THREAD_PARAM,*PTHREAD_PARAM; //LoadLibraryA() typedef HMODULE (WINAPI *PFLOADLIBRARYA) ( LPCSTR lpLibFileName ); //GetProcAddress() typedef FARPROC (WINAPI *PFGETPROCADDRESS) (HMODULE hModule, LPCSTR lpProcName); //MessageBox typedef int(WINAPI *PFMESSAGEBOXA) ( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType ); //Thread Procdure DWORD WINAPI ThreadProc(LPVOID lParam) { PTHREAD_PARAM pParam =(PTHREAD_PARAM)lParam; HMODULE hMod =NULL; FARPROC pFunc =NULL; //LoadLibrary("user32.dll") //pParam->pFunc[0]->kernel32!LoadLibraryA() //pParam->szBuf[0]->"user32.dll" hMod = ((PFLOADLIBRARYA)pParam->pFunc[0])(pParam->szBuf[0]); //GetProcAddress("MessageBoxA") //pParam->pFunc[1]->kernel32!GetProcAddress() //pParam->szBuf[1]->"MessageBox" pFunc = (FARPROC)((PFGETPROCADDRESS)pParam->pFunc[1])(hMod,pParam->szBuf[1]); //MessageBoxA(NULL,"www.reversecore.com","ReverseCore",MB_OK) //pParam->szBuf[2]->"www.reversecore.com" //pParam->szBuf[3]->"ReverseCore" ((PFMESSAGEBOXA)pFunc)(NULL,pParam->szBuf[2],pParam->szBuf[3],MB_OK); return 0; } BOOL InjectCode(DWORD dwPID) { HMODULE hMod = NULL; THREAD_PARAM param = {0,}; HANDLE hProcess = NULL; HANDLE hThread = NULL; LPVOID pRemoteBuf[2]= {0,}; DWORD dwSize = 0; hMod = GetModuleHandleA("kernel32.dll"); //set THREAD_PARAM param.pFunc[0] = GetProcAddress(hMod,"LoadLibraryA"); param.pFunc[1] = GetProcAddress(hMod,"GetProcAddress"); strcpy_s(param.szBuf[0],"user32.dll"); strcpy_s(param.szBuf[1],"MessageBoxA"); strcpy_s(param.szBuf[2],"www.reversecore.com"); strcpy_s(param.szBuf[3],"RecerseCore"); //open Process hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, dwPID ); if(hProcess==NULL) { printf("open Process failed %d\n",GetLastError()); } //Allocation for THREAD_PARAM dwSize = sizeof(THREAD_PARAM); pRemoteBuf[0] = VirtualAllocEx( hProcess, NULL, dwSize, //dwSize MEM_COMMIT, //flAllocationType PAGE_READWRITE); if(pRemoteBuf[0]==NULL) { printf("Allocation for THREAD_PARAM failed\n"); } WriteProcessMemory( hProcess, pRemoteBuf[0], (LPVOID)¶m,//lpBuffer dwSize, NULL); //lpNumberOfByteWritten //Allocation for ThreadProc /*此处的长度计算有点难以理解,实际上它的长度是因为ThreadProc和 InjectCode是1、2的关系,函数名 代表了函数起始地址,同时在本程序编译Release版本的时候, 内存地址的顺序就是函数顺序,所以可以用2-1的方式, 试想此方法并非通用,当它失效的时候,可以找到的一种方法是 直接通过调试器查看内存,来确定该函数的大小*/ dwSize = (DWORD)InjectCode - (DWORD)ThreadProc; pRemoteBuf[1] = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if(pRemoteBuf[1]==NULL) { printf("Allocation for ThreadProc failed\n"); } WriteProcessMemory( hProcess, pRemoteBuf[1], (LPVOID)ThreadProc,//lpBuffer dwSize, NULL); //lpNumberOfByteWritten hThread = CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pRemoteBuf[1],//lpStartAddress pRemoteBuf[0],//lpParameter 0, NULL); if(hThread==NULL) { printf("hThread==NULL injection failed\n"); printf("open hThread failed %d\n",GetLastError()); } WaitForSingleObject(hThread,INFINITE); CloseHandle(hThread); CloseHandle(hProcess); return TRUE; } int main(int argc, char* argv[]) { DWORD dwPID=0; if(argc!=2) { printf("\n USAGE %s argv[0] pid\n"); return 1; } // change privilege if( !SetPrivilege(SE_DEBUG_NAME, TRUE) ) return 1; //Code Injection dwPID=(DWORD)atol(argv[1]); InjectCode(dwPID); return 0; }
小结:
本程序虽然短小,但是注入思路简洁,将自定结构体作为参数和将写入远进程的缓冲区的起始地址作为创建远线程的参数的方法值得借鉴,原先让我这个不太懂编程的孩子是打破脑袋也想不到的,实为精妙,至于为什么在win10 64位运行失败,以后再来研究。
后续:
1、关于之前在WIN10上CreateRemoteThread失败返回失败码5放入情况,网上查看说是因为权限不够,32位程序在64位系统提权失败,实际上,我的提权函数也写过错误代码而并没有返回错误,说明不是提权失败,而是CreateRemoteThread这个函数在64位系统运行出错的问题,测试用此程序在自己创建的exe程序注入的时候并没有出现异常,猜想是win 10 64位对系统进程作了保护机制,究竟是什么,还是没弄清楚,待进一步查证。
相关文章推荐
- 《深入探索C++对象模型》第三章奇怪语句解释
- Retrofit+RxJava
- TTMS 一个基于Java Swing的Socket通信的剧院票务管理系统
- eclipse中server location灰色,如何修改?
- Struts2 配置文件result的name属性和type属性
- 代码:通过捕捉信号SIGIO将标准输入打印到标准输出
- matlab中fopen函数与fprintf用法
- (二)asp.net WebUploader 分片上传
- JAVA WEB开发之JSP
- PHP数组、日期、文件的简单使用
- Python3之random模块
- Ecos model
- C++ 服务器端学习之心跳控制
- python django1.9.7 ubuntu 14.03 环境部署记录
- C++编程笔记:dll的生成与使用
- (一) asp.net WebUploader 上传
- go语言实现一个简单的登录注册web小程序
- 【NOIP2013模拟联考5】军训(training) 题解+代码
- error the @annotation pointcut expression is only supported at Java 5
- JAVA 枚举基础应用