开篇:润墨网以专业的文秘视角,为您筛选了一篇基于动态链接库的木马实现与研究范文,如需获取更多写作素材,在线客服老师一对一协助。欢迎您的阅读与分享!
摘要:木马程序设计最主要的工作是将功能代码实现隐藏,我们可以采用远程线程技术,通过动态链接库方法,借助远程线程将木马作为线程隐藏在其他进程中,从而达到隐藏的目的。
关键词:进程; 木马; 动态链接库
中图分类号:TP393文献标识码:A文章编号:1009-3044(2010)11-2612-02
1 概述
Windows系统平台上提供了有效的编程和运行环境,可以将独立的程序模块创建为较小的DLL(Dynamic Linkable Library)文件,同时可对这些DLL文件功能模块进行单独编译和测试。在运行时,只有当EXE程序确实要调用这些DLL模块的情况下,系统才会将它们装载到内存空间中。此方式不仅减少了EXE文件的大小和对内存空间的需求,而且使这些DLL模块可以同时被多个应用程序使用。Microsoft Windows自己就将一些主要的系统功能以DLL模块的形式实现。例如IE中的一些基本功能就是由DLL文件实现的,它可以被其它应用程序调用和集成。
在windows系统中,WS2_32.DLL是使用标准的动态链接库来加载服务,然后通过加载的服务来实现系统功能,并调用WSPStartup来初始化。WSPStartup是Windows Socket 2的初始化函数,也就是入口函数,通过指定参数,来实现提供应用程序所期望的协议信息,然后我们可以获得所保存的系统服务提供者的DLL名称和路径,加载系统服务后,可以查找到自己所要加载DLL的相关信息, 进而调用系统的各个服务提供者函数。在数据传输服务提供者的实现中,我们需要两个程序,一个是可执行文件用来安装传输服务提供者;另一个就是DLL形式的数据传输服务提供者。
2 基本原理
DLL木马的实现原理是:程序员在DLL程序中包含木马功能相关的代码,随后在目标主机系统中选择特定进程,以某种方式强行执行进程,并且调用包含木马功能的DLL,最终使木马功能代码得到执行,从而达到侵袭目标系统的目的。由于DLL程序自身的特点决定了以这种形式加载木马不仅可行,而且具有良好的隐藏性:
1) DLL程序被映射到宿主进程的地址空间中,可以共享宿主进程的资源,在目标主机的级别进行非法访问,获取相应的系统资源;
2) DLL程序没有独立的进程地址空间,可以避免在目标主机中留下痕迹,从而达到隐蔽自身的目的。
在每个操作系统中都有系统网络服务,它们是在系统启动时自动加载,而且很多是基于IP协议的。若程序设计者编制一个IP协议的传输服务提供者,并安装在服务提供者数据库的最前端,系统网络服务就会加载我们的服务提供者。如果将木马功能代码嵌入到服务提供者的DLL文件之中,在启动系统网络服务时我们的木马程序也会被启动。这种形式的DLL木马只须被安装一次,而后就会被自动加载到可执行文件的进程中,还有一个特点就是它会被多个网络服务加载。通常在系统关闭时,系统网络服务才会结束,所以我们的木马程序同样可以在系统运行时保持激活状态。
我们可以将自已的木马以线程方式注入远程进程之中,远程进程则是合法的用户程序,这样用户管理者看到的只是合法进程,而无法发现木马线程的存在.从而达到隐藏的目的。
若DLL木马实现了隐藏,我们在任务管理器中是看不到木马“进程”,它完全溶进了系统的内核。DLL木马可以注入其它进程的方法为远程线程插入,远程线程插入技术指的是通过在另一个进程中创建远程线程的方法进入那个进程的内存地址空间。将木马功能以DLL的形式实现后,需要使用插入到目标进程中的远程线程将该木马DLL插入到目标进程的地址空间,即利用该线程通过调用Windows API LoadLibrary函数来加载木马DLL,从而实现木马对系统的侵入。
DLL木马功能代码程序注入到系统中必须涉及到一个非常重要的Windows API函数 CreateRemoteThread。与之相比所习惯使用的CreateThrea函数只能在进程自身内部产生一个新的线程,而且被创建的新线程与主线程共享地址空间和其他资源;而CreateRemoteThread则不同,它可以在另外的进程中产生线程。CreateRemoteThread函数中的参数hProcess用于指定要创建线程的远程进程,其函数原型为:
HANDLE CreateRemoteThread(
HANDLE hProcess, //远程进程句柄
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId);
线程函数的代码不能位于我们用来注入DLL木马的进程所在的地址空间中,也就是说,我们不能想当然地自己写一个函数,并把这个函数作为远程线程的入口函数;不能把本进程的指针作为CreateRemoteThread的参数,因为本进程的内存空间与远程进程的不一样。
我们可以将已经编制好的木马功能代码编译为DLL文件,然后将此DLL木马注入程序,也就是将其注入到系统正在运行的系统进程中去,其实现步骤如下:
3.1 打开远程进程
hRemoteProcess = OpenProcess(
PROCESS_CREATE_THREAD | //允许创建线程
PROCESS_VM_OPERATION | //允许VM操作
PROCESS_VM_WRITE, //允许VM写
FALSE, dwRemoteProcessId );
3.2 计算DLL路径名需要的内存空间
int cb = (1 + lstrlenW(pszLibFileName)) * sizeof(WCHAR);
pszLibFileRemote = (PWSTR) VirtualAllocEx( hRemoteProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
3.3将DLL的路径名复制到远程进程的内存空间
iReturnCode = WriteProcessMemory(hRemoteProcess, pszLibFileRemote, (PVOID) pszLibFileName, cb, NULL);
3.4 计算LoadLibraryW的入口地址
PTHREAD_START_ROUTINE pfnStartAddr = (PTHREAD_START_ROUTINE)
GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");
3.5 启动远程线程,通过远程线程调用用户的DLL文件
hRemoteThread = CreateRemoteThread( hRemoteProcess, NULL, 0, pfnStartAddr, pszLibFileRemote, 0, NULL);
3.6 等待远程线程退出
WaitForSingleObject(hRemoteThread, INFINITE);
4 总结
DLL木马注入进程进行隐藏的技术和方法有很多,而且这一技术发展也相当快,本文仅从一个侧面加以讨论,希望通过这一探讨让我们对DLL木马注入进程隐藏技术有一个更清楚的认识,同时也为我们防范他人利用进程手段非法入侵提供参考。