4.2 ExcuteDLLTest.exe的实现 http://www.paper51.com 4.2.1 远程线程插入模块的实现 http://www.paper51.com
远程线程技术指的是通过在另一个运行的进程中创建远程线程的方法进入那个线程的内存地址空间。我们知道,在进程中,可以通过CreateThread函数创建线程,被创建的新线程与主线程(就是进程创建时被同时自动建立的那个线程)共享地址空间以及其他的资源。但是很少有人知道,通过CreateRemoteThread也同样可以在另一个进程内创建新线程,被创建的远程线程同样可以共享远程进程的地址空间,所以,实际上,我们通过创建一个远程线程,进入了远程进程的内存地址空间,也就拥有了那个远程进程相当多的权限,例如启动一个DLL木马。 http://www.paper51.com
首先,我们通过OpenProcess 来打开我们试图嵌入的进程(如果不允许打开,那么嵌入就无法进行了,这往往是由于权限不够引起的,例如你试图打开一个受系统保护的进程) 内容来自www.paper51.com hRemoteProcess = OpenProcess(PROCESS_CREATE_THREAD | 内容来自www.paper51.com
//允许远程创建线程 内容来自论文无忧网 www.paper51.com PROCESS_VM_OPERATION |//允许远程VM操作 内容来自论文无忧网 www.paper51.com PROCESS_VM_WRITE, //允许远程VM写 copyright paper51.com FALSE,dwRemoteProcessId ); copyright paper51.com 由于我们后面需要写入远程进程的内存地址空间并建立远程线程,所以需要申请足够的权限(PROCESS_CREATE_THREAD、VM_OPERATION、VM_WRITE)。 paper51.com 然后,我们可以建立LoadLibraryW这个线程来启动我们的DLL木马,LoadLibraryW函数是在kernel32.dll中定义的,用来加载DLL文件,它只有一个参数,就是DLL文件的绝对路径名pszLibFileName,(也就是木马DLL的全路径文件名),但是由于木马DLL是在远程进程内调用的,所以我们首先还需要将这个文件名复制到远程地址空间:(否则远程线程读不到这个参数) copyright paper51.com //计算DLL路径名需要的内存空间 内容来自论文无忧网 www.paper51.com
int cb = (1 + lstrlenW(pszLibFileName)) *sizeof(WCHAR); 内容来自www.paper51.com //使用VirtualAllocEx函数在远程进程的内存地址空间分配DLL文件名缓冲区 copyright paper51.com
pszLibFileRemote = (PWSTR) VirtualAllocEx(hRemoteProcess, NULL, cb, paper51.com MEM_COMMIT,PAGE_READWRITE); copyright paper51.com
//使用WriteProcessMemory函数将DLL的路径名复制到远程进程的内存空间 内容来自www.paper51.com iReturnCode =WriteProcessMemory(hRemoteProcess, 内容来自论文无忧网 www.paper51.com pszLibFileRemote,(PVOID) pszLibFileName, cb, NULL); 内容来自论文无忧网 www.paper51.com //计算LoadLibraryW的入口地址 paper51.com PTHREAD_START_ROUTINE pfnStartAddr =(PTHREAD_START_ROUTINE) paper51.com GetProcAddress(GetModuleHandle(TEXT("Kernel32")),"LoadLibraryW"); http://www.paper51.com
说明一下,上面我们计算的其实是自己这个进程内LoadLibraryW的入口地址,但是因为kernel.dll模块在所有进程内的地址都是相同的(属于内核模块),所以这个入口地址同样适用于远程进程。 http://www.paper51.com 我们通过建立远程线程时的地址pfnStartAddr(实际上就是LoadLibraryW的入口地址)和传递的参数pszLibFileRemote(我们复制到远程进程内存空间的木马DLL的全路径文件名)在远程进程内启动我们的木马DLL: http://www.paper51.com //启动远程线程LoadLibraryW,通过远程线程调用用户的DLL文件 copyright paper51.com hRemoteThread = CreateRemoteThread(hRemoteProcess, //被嵌入的远程进程 内容来自论文无忧网 www.paper51.com NULL, 0, pfnStartAddr, //LoadLibraryW的入口地址 http://www.paper51.com pszLibFileRemote, //木马DLL的全路径文件名 内容来自论文无忧网 www.paper51.com
0, NULL); 内容来自论文无忧网 www.paper51.com 至此,远程嵌入顺利完成。由此可见DLL木马注入的一般步骤为: 内容来自论文无忧网 www.paper51.com (1)取得宿主进程(即要注入木马的进程)的进程ID dwRemoteProcessId; (2)取得DLL的完全路径,并将其转换为宽字符模式pszLibFileName; 内容来自www.paper51.com (3)利用Windows API OpenProcess打开宿主进程,应该开启下列选项: http://www.paper51.com a.PROCESS_CREATE_THREAD:允许在宿主进程中创建线程; 内容来自www.paper51.com b.PROCESS_VM_OPERATION:允许对宿主进程中进行VM操作; copyright paper51.com c.PROCESS_VM_WRITE:允许对宿主进程进行VM写。 paper51.com (4)利用Windows APIVirtualAllocEx函数在远程线程的VM中分配DLL完整路径宽字符所需的存储空间,并利用Windows API WriteProcessMemory函数将完整路径写入该存储空间; 内容来自www.paper51.com
(5)利用Windows API GetProcAddress取得Kernel32模块中LoadLibraryW函数的地址,这个函数将作为随后将启动的远程线程的入口函数; 内容来自论文无忧网 www.paper51.com (6)利用Windows API CreateRemoteThread启动远程线程,将LoadLibraryW的地址作为远程线程的入口函数地址,将宿主进程里被分配空间中存储的完整DLL路径作为线程入口函数的参数以另其启动指定的DLL; 内容来自论文无忧网 www.paper51.com (7)清理现场。 内容来自论文无忧网 www.paper51.com
|